Files
wasmtime/cranelift/codegen/src/machinst/compile.rs
Nick Fitzgerald f0c60f46a8 Cranelift: Remove ABICallee trait (#4701)
* Cranelift: Remove `ABICallee` trait

It has only one implementation: the `ABICalleeImpl` struct. By using that
directly we can avoid unnecessary layers of generics and abstractions as well as
a couple `Box`es that were previously putting the single implementation into a
`Box<dyn>`.

* Cranelift: Rename `ABICalleeImpl` to `AbiCallee`

* Fix comments as per review

* Rename `AbiCallee` to `Callee`
2022-08-15 18:27:05 +00:00

71 lines
2.2 KiB
Rust

//! Compilation backend pipeline: optimized IR to VCode / binemit.
use crate::ir::Function;
use crate::isa::TargetIsa;
use crate::machinst::*;
use crate::timing;
use crate::trace;
use regalloc2::RegallocOptions;
use regalloc2::{self, MachineEnv};
/// Compile the given function down to VCode with allocated registers, ready
/// for binary emission.
pub fn compile<B: LowerBackend + TargetIsa>(
f: &Function,
b: &B,
abi: Callee<<<B as LowerBackend>::MInst as MachInst>::ABIMachineSpec>,
machine_env: &MachineEnv,
emit_info: <B::MInst as MachInstEmit>::Info,
) -> CodegenResult<(VCode<B::MInst>, regalloc2::Output)> {
// Compute lowered block order.
let block_order = BlockLoweringOrder::new(f);
// Build the lowering context.
let lower = Lower::new(f, abi, emit_info, block_order)?;
// Lower the IR.
let vcode = {
let _tt = timing::vcode_lower();
lower.lower(b)?
};
trace!("vcode from lowering: \n{:?}", vcode);
// Perform register allocation.
let regalloc_result = {
let _tt = timing::regalloc();
let mut options = RegallocOptions::default();
options.verbose_log = b.flags().regalloc_verbose_logs();
regalloc2::run(&vcode, machine_env, &options)
.map_err(|err| {
log::error!(
"Register allocation error for vcode\n{:?}\nError: {:?}\nCLIF for error:\n{:?}",
vcode,
err,
f,
);
err
})
.expect("register allocation")
};
// Run the regalloc checker, if requested.
if b.flags().regalloc_checker() {
let _tt = timing::regalloc_checker();
let mut checker = regalloc2::checker::Checker::new(&vcode, machine_env);
checker.prepare(&regalloc_result);
checker
.run()
.map_err(|err| {
log::error!(
"Register allocation checker errors:\n{:?}\nfor vcode:\n{:?}",
err,
vcode
);
err
})
.expect("register allocation checker");
}
Ok((vcode, regalloc_result))
}