Refactoring
This commit is contained in:
parent
0978710ffd
commit
f67ad9c120
4 changed files with 99 additions and 91 deletions
19
src/abi.rs
19
src/abi.rs
|
@ -163,19 +163,6 @@ pub fn get_function_name_and_sig<'a, 'tcx>(
|
|||
(tcx.symbol_name(inst).as_str().to_string(), sig)
|
||||
}
|
||||
|
||||
impl<'a, 'tcx: 'a> CodegenCx<'a, 'tcx, CurrentBackend> {
|
||||
pub fn predefine_function(&mut self, inst: Instance<'tcx>) -> (FuncId, Function) {
|
||||
let (name, sig) = crate::abi::get_function_name_and_sig(self.tcx, inst);
|
||||
let func_id = self
|
||||
.module
|
||||
.declare_function(&name, Linkage::Export, &sig)
|
||||
.unwrap();
|
||||
let func =
|
||||
Function::with_name_signature(ExternalName::user(0, func_id.index() as u32), sig);
|
||||
(func_id, func)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx: 'a> FunctionCx<'a, 'tcx> {
|
||||
/// Instance must be monomorphized
|
||||
pub fn get_function_ref(&mut self, inst: Instance<'tcx>) -> FuncRef {
|
||||
|
@ -315,6 +302,8 @@ pub fn codegen_fn_prelude<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, start_ebb
|
|||
}
|
||||
}).collect::<Vec<(Local, ArgKind, Ty)>>();
|
||||
|
||||
fx.bcx.switch_to_block(start_ebb);
|
||||
|
||||
match output_pass_mode {
|
||||
PassMode::NoPass => {
|
||||
let null = fx.bcx.ins().iconst(types::I64, 0);
|
||||
|
@ -418,6 +407,10 @@ pub fn codegen_fn_prelude<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, start_ebb
|
|||
|
||||
fx.local_map.insert(local, place);
|
||||
}
|
||||
|
||||
fx.bcx
|
||||
.ins()
|
||||
.jump(*fx.ebb_map.get(&START_BLOCK).unwrap(), &[]);
|
||||
}
|
||||
|
||||
pub fn codegen_call<'a, 'tcx: 'a>(
|
||||
|
|
125
src/base.rs
125
src/base.rs
|
@ -2,7 +2,6 @@ use crate::prelude::*;
|
|||
|
||||
pub fn trans_mono_item<'a, 'tcx: 'a>(
|
||||
cx: &mut CodegenCx<'a, 'tcx, CurrentBackend>,
|
||||
context: &mut Context,
|
||||
mono_item: MonoItem<'tcx>,
|
||||
) {
|
||||
let tcx = cx.tcx;
|
||||
|
@ -21,41 +20,8 @@ pub fn trans_mono_item<'a, 'tcx: 'a>(
|
|||
String::from_utf8_lossy(&mir.into_inner())
|
||||
));
|
||||
|
||||
let (func_id, mut func) = cx.predefine_function(inst);
|
||||
|
||||
let comments = trans_fn(cx, &mut func, inst);
|
||||
|
||||
let mut writer = crate::pretty_clif::CommentWriter(comments);
|
||||
let mut cton = String::new();
|
||||
::cranelift::codegen::write::decorate_function(&mut writer, &mut cton, &func, None)
|
||||
.unwrap();
|
||||
tcx.sess.warn(&cton);
|
||||
|
||||
let flags = settings::Flags::new(settings::builder());
|
||||
match ::cranelift::codegen::verify_function(&func, &flags) {
|
||||
Ok(_) => {}
|
||||
Err(err) => {
|
||||
tcx.sess.err(&format!("{:?}", err));
|
||||
let pretty_error =
|
||||
::cranelift::codegen::print_errors::pretty_verifier_error(
|
||||
&func,
|
||||
None,
|
||||
Some(Box::new(writer)),
|
||||
&err,
|
||||
);
|
||||
tcx.sess
|
||||
.fatal(&format!("cretonne verify error:\n{}", pretty_error));
|
||||
}
|
||||
}
|
||||
|
||||
context.func = func;
|
||||
// TODO: cranelift doesn't yet support some of the things needed
|
||||
if should_codegen(cx.tcx) {
|
||||
cx.module.define_function(func_id, context).unwrap();
|
||||
cx.defined_functions.push(func_id);
|
||||
}
|
||||
|
||||
context.clear();
|
||||
let func_id = trans_fn(cx.tcx, cx.module, &mut cx.constants, &mut cx.context, inst);
|
||||
cx.defined_functions.push(func_id);
|
||||
}
|
||||
Instance {
|
||||
def: InstanceDef::DropGlue(_, _),
|
||||
|
@ -64,7 +30,7 @@ pub fn trans_mono_item<'a, 'tcx: 'a>(
|
|||
inst => unimpl!("Unimplemented instance {:?}", inst),
|
||||
},
|
||||
MonoItem::Static(def_id) => {
|
||||
crate::constant::codegen_static(cx, def_id);
|
||||
crate::constant::codegen_static(&mut cx.constants, def_id);
|
||||
}
|
||||
MonoItem::GlobalAsm(node_id) => cx
|
||||
.tcx
|
||||
|
@ -73,25 +39,38 @@ pub fn trans_mono_item<'a, 'tcx: 'a>(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn trans_fn<'a, 'tcx: 'a>(
|
||||
cx: &mut CodegenCx<'a, 'tcx, CurrentBackend>,
|
||||
f: &mut Function,
|
||||
fn trans_fn<'a, 'tcx: 'a>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
module: &mut Module<SimpleJITBackend>,
|
||||
constants: &mut crate::constant::ConstantCx,
|
||||
context: &mut Context,
|
||||
instance: Instance<'tcx>,
|
||||
) -> HashMap<Inst, String> {
|
||||
let mir = cx.tcx.optimized_mir(instance.def_id());
|
||||
let mut func_ctx = FunctionBuilderContext::new();
|
||||
let mut bcx: FunctionBuilder<Variable> = FunctionBuilder::new(f, &mut func_ctx);
|
||||
) -> FuncId {
|
||||
// Step 1. Get mir
|
||||
let mir = tcx.optimized_mir(instance.def_id());
|
||||
|
||||
// Step 2. Declare function
|
||||
let (name, sig) = get_function_name_and_sig(tcx, instance);
|
||||
let func_id = module
|
||||
.declare_function(&name, Linkage::Export, &sig)
|
||||
.unwrap();
|
||||
|
||||
// Step 3. Make FunctionBuilder
|
||||
let mut func = Function::with_name_signature(ExternalName::user(0, 0), sig);
|
||||
let mut func_ctx = FunctionBuilderContext::new();
|
||||
let mut bcx: FunctionBuilder<Variable> = FunctionBuilder::new(&mut func, &mut func_ctx);
|
||||
|
||||
// Step 4. Predefine ebb's
|
||||
let start_ebb = bcx.create_ebb();
|
||||
bcx.switch_to_block(start_ebb);
|
||||
let mut ebb_map: HashMap<BasicBlock, Ebb> = HashMap::new();
|
||||
for (bb, _bb_data) in mir.basic_blocks().iter_enumerated() {
|
||||
ebb_map.insert(bb, bcx.create_ebb());
|
||||
}
|
||||
|
||||
// Step 5. Make FunctionCx
|
||||
let mut fx = FunctionCx {
|
||||
tcx: cx.tcx,
|
||||
module: &mut cx.module,
|
||||
tcx,
|
||||
module,
|
||||
instance,
|
||||
mir,
|
||||
bcx,
|
||||
|
@ -102,17 +81,53 @@ pub fn trans_fn<'a, 'tcx: 'a>(
|
|||
ebb_map,
|
||||
local_map: HashMap::new(),
|
||||
comments: HashMap::new(),
|
||||
constants: &mut cx.constants,
|
||||
constants,
|
||||
};
|
||||
let fx = &mut fx;
|
||||
|
||||
crate::abi::codegen_fn_prelude(fx, start_ebb);
|
||||
// Step 6. Codegen function
|
||||
crate::abi::codegen_fn_prelude(&mut fx, start_ebb);
|
||||
codegen_fn_content(&mut fx);
|
||||
|
||||
fx.bcx
|
||||
.ins()
|
||||
.jump(*fx.ebb_map.get(&START_BLOCK).unwrap(), &[]);
|
||||
// Step 7. Print function to terminal for debugging
|
||||
let mut writer = crate::pretty_clif::CommentWriter(fx.comments);
|
||||
let mut cton = String::new();
|
||||
::cranelift::codegen::write::decorate_function(&mut writer, &mut cton, &func, None).unwrap();
|
||||
tcx.sess.warn(&cton);
|
||||
|
||||
for (bb, bb_data) in mir.basic_blocks().iter_enumerated() {
|
||||
// Step 8. Verify function
|
||||
verify_func(tcx, writer, &func);
|
||||
|
||||
// Step 9. Define function
|
||||
// TODO: cranelift doesn't yet support some of the things needed
|
||||
if should_codegen(tcx) {
|
||||
context.func = func;
|
||||
module.define_function(func_id, context).unwrap();
|
||||
context.clear();
|
||||
}
|
||||
|
||||
func_id
|
||||
}
|
||||
|
||||
fn verify_func(tcx: TyCtxt, writer: crate::pretty_clif::CommentWriter, func: &Function) {
|
||||
let flags = settings::Flags::new(settings::builder());
|
||||
match ::cranelift::codegen::verify_function(&func, &flags) {
|
||||
Ok(_) => {}
|
||||
Err(err) => {
|
||||
tcx.sess.err(&format!("{:?}", err));
|
||||
let pretty_error = ::cranelift::codegen::print_errors::pretty_verifier_error(
|
||||
&func,
|
||||
None,
|
||||
Some(Box::new(writer)),
|
||||
&err,
|
||||
);
|
||||
tcx.sess
|
||||
.fatal(&format!("cretonne verify error:\n{}", pretty_error));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn codegen_fn_content<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>) {
|
||||
for (bb, bb_data) in fx.mir.basic_blocks().iter_enumerated() {
|
||||
let ebb = fx.get_ebb(bb);
|
||||
fx.bcx.switch_to_block(ebb);
|
||||
|
||||
|
@ -208,8 +223,6 @@ pub fn trans_fn<'a, 'tcx: 'a>(
|
|||
|
||||
fx.bcx.seal_all_blocks();
|
||||
fx.bcx.finalize();
|
||||
|
||||
fx.comments.clone()
|
||||
}
|
||||
|
||||
fn trans_stmt<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, cur_ebb: Ebb, stmt: &Statement<'tcx>) {
|
||||
|
|
|
@ -32,8 +32,8 @@ impl ConstantCx {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn codegen_static<'a, 'tcx: 'a, B: Backend>(cx: &mut CodegenCx<'a, 'tcx, B>, def_id: DefId) {
|
||||
cx.constants.todo.insert(TodoItem::Static(def_id));
|
||||
pub fn codegen_static<'a, 'tcx: 'a>(ccx: &mut ConstantCx, def_id: DefId) {
|
||||
ccx.todo.insert(TodoItem::Static(def_id));
|
||||
}
|
||||
|
||||
pub fn codegen_static_ref<'a, 'tcx: 'a>(
|
||||
|
|
42
src/lib.rs
42
src/lib.rs
|
@ -103,6 +103,9 @@ pub struct CodegenCx<'a, 'tcx: 'a, B: Backend + 'a> {
|
|||
pub module: &'a mut Module<B>,
|
||||
pub constants: crate::constant::ConstantCx,
|
||||
pub defined_functions: Vec<FuncId>,
|
||||
|
||||
// Cache
|
||||
pub context: Context,
|
||||
}
|
||||
|
||||
struct CraneliftMetadataLoader;
|
||||
|
@ -248,16 +251,25 @@ impl CodegenBackend for CraneliftCodegenBackend {
|
|||
let isa = cranelift::codegen::isa::lookup(target_lexicon::Triple::host())
|
||||
.unwrap()
|
||||
.finish(flags);
|
||||
let mut module: Module<SimpleJITBackend> = Module::new(SimpleJITBuilder::new());
|
||||
let mut context = Context::new();
|
||||
let mut jit_module: Module<SimpleJITBackend> = Module::new(SimpleJITBuilder::new());
|
||||
let mut faerie_module: Module<FaerieBackend> = Module::new(
|
||||
FaerieBuilder::new(
|
||||
isa,
|
||||
"some_file.o".to_string(),
|
||||
FaerieTrapCollection::Disabled,
|
||||
FaerieBuilder::default_libcall_names(),
|
||||
).unwrap(),
|
||||
);
|
||||
|
||||
let defined_functions = {
|
||||
use std::io::Write;
|
||||
let mut cx = CodegenCx {
|
||||
tcx,
|
||||
module: &mut module,
|
||||
module: &mut jit_module,
|
||||
constants: Default::default(),
|
||||
defined_functions: Vec::new(),
|
||||
|
||||
context: Context::new(),
|
||||
};
|
||||
|
||||
let mut log = ::std::fs::File::create("target/log.txt").unwrap();
|
||||
|
@ -273,9 +285,8 @@ impl CodegenBackend for CraneliftCodegenBackend {
|
|||
|
||||
for mono_item in mono_items {
|
||||
let cx = &mut cx;
|
||||
let context = &mut context;
|
||||
let res = ::std::panic::catch_unwind(::std::panic::AssertUnwindSafe(move || {
|
||||
base::trans_mono_item(cx, context, mono_item);
|
||||
base::trans_mono_item(cx, mono_item);
|
||||
}));
|
||||
if let Err(err) = res {
|
||||
match err.downcast::<NonFatal>() {
|
||||
|
@ -304,43 +315,34 @@ impl CodegenBackend for CraneliftCodegenBackend {
|
|||
|
||||
let (name, sig) =
|
||||
crate::abi::get_function_name_and_sig(tcx, Instance::mono(tcx, start_wrapper));
|
||||
let called_func_id = module
|
||||
let called_func_id = jit_module
|
||||
.declare_function(&name, Linkage::Import, &sig)
|
||||
.unwrap();
|
||||
|
||||
for func_id in defined_functions {
|
||||
if func_id != called_func_id {
|
||||
module.finalize_function(func_id);
|
||||
jit_module.finalize_function(func_id);
|
||||
}
|
||||
}
|
||||
tcx.sess.warn("Finalized everything");
|
||||
|
||||
let finalized_function: *const u8 = module.finalize_function(called_func_id);
|
||||
let finalized_function: *const u8 = jit_module.finalize_function(called_func_id);
|
||||
let f: extern "C" fn(*const u8, isize, *const *const u8) -> isize =
|
||||
unsafe { ::std::mem::transmute(finalized_function) };
|
||||
let res = f(0 as *const u8, 0, 0 as *const _);
|
||||
tcx.sess.warn(&format!("main returned {}", res));
|
||||
|
||||
module.finish();
|
||||
jit_module.finish();
|
||||
} else if should_codegen(tcx) {
|
||||
for func_id in defined_functions {
|
||||
module.finalize_function(func_id);
|
||||
jit_module.finalize_function(func_id);
|
||||
}
|
||||
|
||||
tcx.sess.warn("Finalized everything");
|
||||
}
|
||||
|
||||
let mut translated_module: Module<FaerieBackend> = Module::new(
|
||||
FaerieBuilder::new(
|
||||
isa,
|
||||
"some_file.o".to_string(),
|
||||
FaerieTrapCollection::Disabled,
|
||||
FaerieBuilder::default_libcall_names(),
|
||||
).unwrap(),
|
||||
);
|
||||
|
||||
Box::new(OngoingCodegen {
|
||||
product: translated_module.finish(),
|
||||
product: faerie_module.finish(),
|
||||
metadata: metadata.raw_data,
|
||||
crate_name: tcx.crate_name(LOCAL_CRATE),
|
||||
})
|
||||
|
|
Loading…
Add table
Reference in a new issue