Files
wasmtime/cranelift/codegen/src/machinst/compile.rs
Chris Fallin a0318f36f0 Switch Cranelift over to regalloc2. (#3989)
This PR switches Cranelift over to the new register allocator, regalloc2.

See [this document](https://gist.github.com/cfallin/08553421a91f150254fe878f67301801)
for a summary of the design changes. This switchover has implications for
core VCode/MachInst types and the lowering pass.

Overall, this change brings improvements to both compile time and speed of
generated code (runtime), as reported in #3942:

```
Benchmark       Compilation (wallclock)     Execution (wallclock)
blake3-scalar   25% faster                  28% faster
blake3-simd     no diff                     no diff
meshoptimizer   19% faster                  17% faster
pulldown-cmark  17% faster                  no diff
bz2             15% faster                  no diff
SpiderMonkey,   21% faster                  2% faster
  fib(30)
clang.wasm      42% faster                  N/A
```
2022-04-14 10:28:21 -07:00

52 lines
1.6 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 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: Box<dyn ABICallee<I = B::MInst>>,
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)?
};
log::trace!("vcode from lowering: \n{:?}", vcode);
// Perform register allocation.
let regalloc_result = {
let _tt = timing::regalloc();
let mut options = RegallocOptions::default();
options.verbose_log = log::log_enabled!(log::Level::Trace);
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")
};
Ok((vcode, regalloc_result))
}