Add basic ssa analyzer
This commit is contained in:
parent
72fa53bac3
commit
f4e622cedc
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -409,6 +409,7 @@ name = "rustc_codegen_cranelift"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ar 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cranelift 0.18.1 (git+https://github.com/CraneStation/cranelift.git)",
|
||||
"cranelift-faerie 0.18.1 (git+https://github.com/CraneStation/cranelift.git)",
|
||||
"cranelift-module 0.18.1 (git+https://github.com/CraneStation/cranelift.git)",
|
||||
|
@ -23,3 +23,4 @@ target-lexicon = "0.0.3"
|
||||
#goblin = "0.0.17"
|
||||
faerie = "0.4.4"
|
||||
ar = "0.6.0"
|
||||
bitflags = "1.0.3"
|
||||
|
39
src/abi.rs
39
src/abi.rs
@ -186,17 +186,15 @@ impl<'a, 'tcx: 'a> FunctionCx<'a, 'tcx> {
|
||||
}
|
||||
|
||||
pub fn codegen_fn_prelude<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, start_ebb: Ebb) {
|
||||
let ssa_analyzed = crate::analyze::analyze(fx);
|
||||
fx.tcx.sess.warn(&format!("ssa {:?}", ssa_analyzed));
|
||||
|
||||
match fx.self_sig().abi {
|
||||
Abi::Rust | Abi::RustCall => {}
|
||||
_ => unimplemented!("declared function with non \"rust\" or \"rust-call\" abi"),
|
||||
}
|
||||
|
||||
let ret_param = fx.bcx.append_ebb_param(start_ebb, types::I64);
|
||||
let _ = fx.bcx.create_stack_slot(StackSlotData {
|
||||
kind: StackSlotKind::ExplicitSlot,
|
||||
size: 0,
|
||||
offset: None,
|
||||
}); // Dummy stack slot for debugging
|
||||
|
||||
enum ArgKind {
|
||||
Normal(Value),
|
||||
@ -237,6 +235,17 @@ pub fn codegen_fn_prelude<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, start_ebb
|
||||
|
||||
for (local, arg_kind, ty) in func_params {
|
||||
let layout = fx.layout_of(ty);
|
||||
|
||||
if let ArgKind::Normal(ebb_param) = arg_kind {
|
||||
if !ssa_analyzed.get(&local).unwrap().contains(crate::analyze::Flags::NOT_SSA) {
|
||||
let var = Variable(local);
|
||||
fx.bcx.declare_var(var, fx.cton_type(ty).unwrap());
|
||||
fx.bcx.def_var(var, ebb_param);
|
||||
fx.local_map.insert(local, CPlace::Var(var, layout));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
let stack_slot = fx.bcx.create_stack_slot(StackSlotData {
|
||||
kind: StackSlotKind::ExplicitSlot,
|
||||
size: layout.size.bytes() as u32,
|
||||
@ -270,12 +279,20 @@ pub fn codegen_fn_prelude<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, start_ebb
|
||||
for local in fx.mir.vars_and_temps_iter() {
|
||||
let ty = fx.mir.local_decls[local].ty;
|
||||
let layout = fx.layout_of(ty);
|
||||
let stack_slot = fx.bcx.create_stack_slot(StackSlotData {
|
||||
kind: StackSlotKind::ExplicitSlot,
|
||||
size: layout.size.bytes() as u32,
|
||||
offset: None,
|
||||
});
|
||||
let place = CPlace::from_stack_slot(fx, stack_slot, ty);
|
||||
|
||||
let place = if ssa_analyzed.get(&local).unwrap().contains(crate::analyze::Flags::NOT_SSA) {
|
||||
let stack_slot = fx.bcx.create_stack_slot(StackSlotData {
|
||||
kind: StackSlotKind::ExplicitSlot,
|
||||
size: layout.size.bytes() as u32,
|
||||
offset: None,
|
||||
});
|
||||
CPlace::from_stack_slot(fx, stack_slot, ty)
|
||||
} else {
|
||||
let var = Variable(local);
|
||||
fx.bcx.declare_var(var, fx.cton_type(ty).unwrap());
|
||||
CPlace::Var(var, layout)
|
||||
};
|
||||
|
||||
fx.local_map.insert(local, place);
|
||||
}
|
||||
}
|
||||
|
52
src/analyze.rs
Normal file
52
src/analyze.rs
Normal file
@ -0,0 +1,52 @@
|
||||
use crate::prelude::*;
|
||||
|
||||
use rustc::mir::{StatementKind::*};
|
||||
|
||||
bitflags! {
|
||||
pub struct Flags: u8 {
|
||||
const NOT_SSA = 0b00000001;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn analyze<'a, 'tcx: 'a>(fx: &FunctionCx<'a, 'tcx>) -> HashMap<Local, Flags> {
|
||||
let mut flag_map = HashMap::new();
|
||||
|
||||
for local in fx.mir.local_decls.indices() {
|
||||
flag_map.insert(local, Flags::empty());
|
||||
}
|
||||
|
||||
not_ssa(&mut flag_map, RETURN_PLACE);
|
||||
|
||||
for (local, local_decl) in fx.mir.local_decls.iter_enumerated() {
|
||||
if fx.cton_type(local_decl.ty).is_none() {
|
||||
not_ssa(&mut flag_map, local);
|
||||
}
|
||||
}
|
||||
|
||||
for bb in fx.mir.basic_blocks().iter() {
|
||||
for stmt in bb.statements.iter() {
|
||||
match &stmt.kind {
|
||||
Assign(_, Rvalue::Ref(_, _, place)) => analyze_non_ssa_place(&mut flag_map, place),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
match &bb.terminator().kind {
|
||||
TerminatorKind::Call { destination: Some((place, _)), .. } => analyze_non_ssa_place(&mut flag_map, place),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
flag_map
|
||||
}
|
||||
|
||||
fn analyze_non_ssa_place(flag_map: &mut HashMap<Local, Flags>, place: &Place) {
|
||||
match place {
|
||||
Place::Local(local) => not_ssa(flag_map, local),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn not_ssa<L: ::std::borrow::Borrow<Local>>(flag_map: &mut HashMap<Local, Flags>, local: L) {
|
||||
*flag_map.get_mut(local.borrow()).unwrap() |= Flags::NOT_SSA;
|
||||
}
|
@ -9,7 +9,7 @@ use crate::prelude::*;
|
||||
pub type CurrentBackend = ::cranelift_simplejit::SimpleJITBackend;
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
pub struct Variable(Local);
|
||||
pub struct Variable(pub Local);
|
||||
|
||||
impl EntityRef for Variable {
|
||||
fn new(u: usize) -> Self {
|
||||
|
@ -12,6 +12,8 @@ extern crate rustc_target;
|
||||
extern crate rustc_data_structures;
|
||||
|
||||
extern crate ar;
|
||||
#[macro_use]
|
||||
extern crate bitflags;
|
||||
extern crate faerie;
|
||||
//extern crate goblin;
|
||||
extern crate cranelift;
|
||||
@ -49,6 +51,7 @@ macro_rules! unimpl {
|
||||
}
|
||||
|
||||
mod abi;
|
||||
mod analyze;
|
||||
mod base;
|
||||
mod common;
|
||||
mod constant;
|
||||
|
Loading…
Reference in New Issue
Block a user