Add basic ssa analyzer

This commit is contained in:
bjorn3 2018-08-09 10:46:56 +02:00
parent 72fa53bac3
commit f4e622cedc
6 changed files with 86 additions and 12 deletions

1
Cargo.lock generated
View File

@ -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)",

View File

@ -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"

View File

@ -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
View 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;
}

View File

@ -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 {

View File

@ -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;