ARM64 backend, part 3 / 11: MachInst infrastructure.
This patch adds the MachInst, or Machine Instruction, infrastructure. This is the machine-independent portion of the new backend design. It contains the implementation of the "vcode" (virtual-registerized code) container, the top-level lowering algorithm and compilation pipeline, and the trait definitions that the machine backends will fill in. This backend infrastructure is included in the compilation of the `codegen` crate, but it is not yet tied into the public APIs; that patch will come last, after all the other pieces are filled in. This patch contains code written by Julian Seward <jseward@acm.org> and Benjamin Bouvier <public@benj.me>, originally developed on a side-branch before rebasing and condensing into this patch series. See the `arm64` branch at `https://github.com/cfallin/wasmtime` for original development history. Co-authored-by: Julian Seward <jseward@acm.org> Co-authored-by: Benjamin Bouvier <public@benj.me>
This commit is contained in:
76
cranelift/codegen/src/machinst/compile.rs
Normal file
76
cranelift/codegen/src/machinst/compile.rs
Normal file
@@ -0,0 +1,76 @@
|
||||
//! Compilation backend pipeline: optimized IR to VCode / binemit.
|
||||
|
||||
use crate::ir::Function;
|
||||
use crate::machinst::*;
|
||||
use crate::settings;
|
||||
use crate::timing;
|
||||
|
||||
use log::debug;
|
||||
use regalloc::{allocate_registers, RegAllocAlgorithm};
|
||||
use std::env;
|
||||
|
||||
/// Compile the given function down to VCode with allocated registers, ready
|
||||
/// for binary emission.
|
||||
pub fn compile<B: LowerBackend>(
|
||||
f: &mut Function,
|
||||
b: &B,
|
||||
abi: Box<dyn ABIBody<B::MInst>>,
|
||||
flags: &settings::Flags,
|
||||
) -> VCode<B::MInst>
|
||||
where
|
||||
B::MInst: ShowWithRRU,
|
||||
{
|
||||
// This lowers the CL IR.
|
||||
let mut vcode = Lower::new(f, abi).lower(b);
|
||||
|
||||
let universe = &B::MInst::reg_universe();
|
||||
|
||||
debug!("vcode from lowering: \n{}", vcode.show_rru(Some(universe)));
|
||||
|
||||
// Perform register allocation.
|
||||
let algorithm = match env::var("REGALLOC") {
|
||||
Ok(str) => match str.as_str() {
|
||||
"lsrac" => RegAllocAlgorithm::LinearScanChecked,
|
||||
"lsra" => RegAllocAlgorithm::LinearScan,
|
||||
// to wit: btc doesn't mean "bitcoin" here
|
||||
"btc" => RegAllocAlgorithm::BacktrackingChecked,
|
||||
_ => RegAllocAlgorithm::Backtracking,
|
||||
},
|
||||
// By default use backtracking, which is the fastest.
|
||||
Err(_) => RegAllocAlgorithm::Backtracking,
|
||||
};
|
||||
|
||||
let result = {
|
||||
let _tt = timing::regalloc();
|
||||
allocate_registers(
|
||||
&mut vcode, algorithm, universe, /*request_block_annotations=*/ false,
|
||||
)
|
||||
.map_err(|err| {
|
||||
debug!(
|
||||
"Register allocation error for vcode\n{}\nError: {:?}",
|
||||
vcode.show_rru(Some(universe)),
|
||||
err
|
||||
);
|
||||
err
|
||||
})
|
||||
.expect("register allocation")
|
||||
};
|
||||
|
||||
// Reorder vcode into final order and copy out final instruction sequence
|
||||
// all at once. This also inserts prologues/epilogues.
|
||||
vcode.replace_insns_from_regalloc(result, flags);
|
||||
|
||||
vcode.remove_redundant_branches();
|
||||
|
||||
// Do final passes over code to finalize branches.
|
||||
vcode.finalize_branches();
|
||||
|
||||
debug!(
|
||||
"vcode after regalloc: final version:\n{}",
|
||||
vcode.show_rru(Some(universe))
|
||||
);
|
||||
|
||||
//println!("{}\n", vcode.show_rru(Some(&B::MInst::reg_universe())));
|
||||
|
||||
vcode
|
||||
}
|
||||
Reference in New Issue
Block a user