Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/cranelift/codegen/src/machinst/compile.rs
1693 views
1
//! Compilation backend pipeline: optimized IR to VCode / binemit.
2
3
use crate::CodegenError;
4
use crate::dominator_tree::DominatorTree;
5
use crate::ir::Function;
6
use crate::ir::pcc;
7
use crate::isa::TargetIsa;
8
use crate::machinst::*;
9
use crate::settings::RegallocAlgorithm;
10
use crate::timing;
11
use crate::trace;
12
13
use regalloc2::{Algorithm, RegallocOptions};
14
15
/// Compile the given function down to VCode with allocated registers, ready
16
/// for binary emission.
17
pub 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
// Compute lowered block order.
27
let block_order = BlockLoweringOrder::new(f, domtree, ctrl_plane);
28
29
// Build the lowering context.
30
let lower =
31
crate::machinst::Lower::new(f, abi, emit_info, block_order, sigs, b.flags().clone())?;
32
33
// Lower the IR.
34
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
// Perform validation of proof-carrying-code facts, if requested.
53
if b.flags().enable_pcc() {
54
pcc::check_vcode_facts(f, &mut vcode, b).map_err(CodegenError::Pcc)?;
55
}
56
57
// Perform register allocation.
58
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
// Run the regalloc checker, if requested.
83
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(&regalloc_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
}
98
99