Path: blob/main/cranelift/codegen/src/machinst/compile.rs
1693 views
//! Compilation backend pipeline: optimized IR to VCode / binemit.12use crate::CodegenError;3use crate::dominator_tree::DominatorTree;4use crate::ir::Function;5use crate::ir::pcc;6use crate::isa::TargetIsa;7use crate::machinst::*;8use crate::settings::RegallocAlgorithm;9use crate::timing;10use crate::trace;1112use regalloc2::{Algorithm, RegallocOptions};1314/// Compile the given function down to VCode with allocated registers, ready15/// for binary emission.16pub fn compile<B: LowerBackend + TargetIsa>(17f: &Function,18domtree: &DominatorTree,19b: &B,20abi: Callee<<<B as LowerBackend>::MInst as MachInst>::ABIMachineSpec>,21emit_info: <B::MInst as MachInstEmit>::Info,22sigs: SigSet,23ctrl_plane: &mut ControlPlane,24) -> CodegenResult<(VCode<B::MInst>, regalloc2::Output)> {25// Compute lowered block order.26let block_order = BlockLoweringOrder::new(f, domtree, ctrl_plane);2728// Build the lowering context.29let lower =30crate::machinst::Lower::new(f, abi, emit_info, block_order, sigs, b.flags().clone())?;3132// Lower the IR.33let mut vcode = {34log::debug!(35"Number of CLIF instructions to lower: {}",36f.dfg.num_insts()37);38log::debug!("Number of CLIF blocks to lower: {}", f.dfg.num_blocks());3940let _tt = timing::vcode_lower();41lower.lower(b, ctrl_plane)?42};4344log::debug!(45"Number of lowered vcode instructions: {}",46vcode.num_insts()47);48log::debug!("Number of lowered vcode blocks: {}", vcode.num_blocks());49trace!("vcode from lowering: \n{:?}", vcode);5051// Perform validation of proof-carrying-code facts, if requested.52if b.flags().enable_pcc() {53pcc::check_vcode_facts(f, &mut vcode, b).map_err(CodegenError::Pcc)?;54}5556// Perform register allocation.57let regalloc_result = {58let _tt = timing::regalloc();59let mut options = RegallocOptions::default();60options.verbose_log = b.flags().regalloc_verbose_logs();6162if cfg!(debug_assertions) {63options.validate_ssa = true;64}6566options.algorithm = match b.flags().regalloc_algorithm() {67RegallocAlgorithm::Backtracking => Algorithm::Ion,68RegallocAlgorithm::SinglePass => Algorithm::Fastalloc,69};7071regalloc2::run(&vcode, vcode.abi.machine_env(), &options)72.map_err(|err| {73log::error!(74"Register allocation error for vcode\n{vcode:?}\nError: {err:?}\nCLIF for error:\n{f:?}",75);76err77})78.expect("register allocation")79};8081// Run the regalloc checker, if requested.82if b.flags().regalloc_checker() {83let _tt = timing::regalloc_checker();84let mut checker = regalloc2::checker::Checker::new(&vcode, vcode.abi.machine_env());85checker.prepare(®alloc_result);86checker87.run()88.map_err(|err| {89log::error!("Register allocation checker errors:\n{err:?}\nfor vcode:\n{vcode:?}");90err91})92.expect("register allocation checker");93}9495Ok((vcode, regalloc_result))96}979899