cranelift_codegen/machinst/
compile.rs1use crate::CodegenError;
4use crate::dominator_tree::DominatorTree;
5use crate::ir::Function;
6use crate::ir::pcc;
7use crate::isa::TargetIsa;
8use crate::machinst::*;
9use crate::settings::RegallocAlgorithm;
10use crate::timing;
11use crate::trace;
12
13use regalloc2::{Algorithm, RegallocOptions};
14
15pub fn compile<B: LowerBackend + TargetIsa>(
18 f: &Function,
19 domtree: &DominatorTree,
20 b: &B,
21 abi: Callee<<<B as LowerBackend>::MInst as MachInst>::ABIMachineSpec>,
22 emit_info: <B::MInst as MachInstEmit>::Info,
23 sigs: SigSet,
24 ctrl_plane: &mut ControlPlane,
25) -> CodegenResult<(VCode<B::MInst>, regalloc2::Output)> {
26 let block_order = BlockLoweringOrder::new(f, domtree, ctrl_plane);
28
29 let lower =
31 crate::machinst::Lower::new(f, abi, emit_info, block_order, sigs, b.flags().clone())?;
32
33 let mut vcode = {
35 log::debug!(
36 "Number of CLIF instructions to lower: {}",
37 f.dfg.num_insts()
38 );
39 log::debug!("Number of CLIF blocks to lower: {}", f.dfg.num_blocks());
40
41 let _tt = timing::vcode_lower();
42 lower.lower(b, ctrl_plane)?
43 };
44
45 log::debug!(
46 "Number of lowered vcode instructions: {}",
47 vcode.num_insts()
48 );
49 log::debug!("Number of lowered vcode blocks: {}", vcode.num_blocks());
50 trace!("vcode from lowering: \n{:?}", vcode);
51
52 if b.flags().enable_pcc() {
54 pcc::check_vcode_facts(f, &mut vcode, b).map_err(CodegenError::Pcc)?;
55 }
56
57 let regalloc_result = {
59 let _tt = timing::regalloc();
60 let mut options = RegallocOptions::default();
61 options.verbose_log = b.flags().regalloc_verbose_logs();
62
63 if cfg!(debug_assertions) {
64 options.validate_ssa = true;
65 }
66
67 options.algorithm = match b.flags().regalloc_algorithm() {
68 RegallocAlgorithm::Backtracking => Algorithm::Ion,
69 RegallocAlgorithm::SinglePass => Algorithm::Fastalloc,
70 };
71
72 regalloc2::run(&vcode, vcode.abi.machine_env(), &options)
73 .map_err(|err| {
74 log::error!(
75 "Register allocation error for vcode\n{vcode:?}\nError: {err:?}\nCLIF for error:\n{f:?}",
76 );
77 err
78 })
79 .expect("register allocation")
80 };
81
82 if b.flags().regalloc_checker() {
84 let _tt = timing::regalloc_checker();
85 let mut checker = regalloc2::checker::Checker::new(&vcode, vcode.abi.machine_env());
86 checker.prepare(®alloc_result);
87 checker
88 .run()
89 .map_err(|err| {
90 log::error!("Register allocation checker errors:\n{err:?}\nfor vcode:\n{vcode:?}");
91 err
92 })
93 .expect("register allocation checker");
94 }
95
96 Ok((vcode, regalloc_result))
97}