cranelift_codegen/machinst/
compile.rs1use crate::dominator_tree::DominatorTree;
4use crate::ir::pcc;
5use crate::ir::Function;
6use crate::isa::TargetIsa;
7use crate::machinst::*;
8use crate::settings::RegallocAlgorithm;
9use crate::timing;
10use crate::trace;
11use crate::CodegenError;
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.machine_env(), &options)
73 .map_err(|err| {
74 log::error!(
75 "Register allocation error for vcode\n{:?}\nError: {:?}\nCLIF for error:\n{:?}",
76 vcode,
77 err,
78 f,
79 );
80 err
81 })
82 .expect("register allocation")
83 };
84
85 if b.flags().regalloc_checker() {
87 let _tt = timing::regalloc_checker();
88 let mut checker = regalloc2::checker::Checker::new(&vcode, vcode.machine_env());
89 checker.prepare(®alloc_result);
90 checker
91 .run()
92 .map_err(|err| {
93 log::error!(
94 "Register allocation checker errors:\n{:?}\nfor vcode:\n{:?}",
95 err,
96 vcode
97 );
98 err
99 })
100 .expect("register allocation checker");
101 }
102
103 Ok((vcode, regalloc_result))
104}