1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
use crate::ir::Function;
use crate::isa::TargetIsa;
use crate::machinst::*;
use crate::timing;
use regalloc2::RegallocOptions;
use regalloc2::{self, MachineEnv};
pub fn compile<B: LowerBackend + TargetIsa>(
f: &Function,
b: &B,
abi: Box<dyn ABICallee<I = B::MInst>>,
machine_env: &MachineEnv,
emit_info: <B::MInst as MachInstEmit>::Info,
) -> CodegenResult<(VCode<B::MInst>, regalloc2::Output)> {
let block_order = BlockLoweringOrder::new(f);
let lower = Lower::new(f, abi, emit_info, block_order)?;
let vcode = {
let _tt = timing::vcode_lower();
lower.lower(b)?
};
log::trace!("vcode from lowering: \n{:?}", vcode);
let regalloc_result = {
let _tt = timing::regalloc();
let mut options = RegallocOptions::default();
options.verbose_log = log::log_enabled!(log::Level::Trace);
regalloc2::run(&vcode, machine_env, &options)
.map_err(|err| {
log::error!(
"Register allocation error for vcode\n{:?}\nError: {:?}\nCLIF for error:\n{:?}",
vcode,
err,
f,
);
err
})
.expect("register allocation")
};
if b.flags().regalloc_checker() {
let _tt = timing::regalloc_checker();
let mut checker = regalloc2::checker::Checker::new(&vcode, machine_env);
checker.prepare(®alloc_result);
checker
.run()
.map_err(|err| {
log::error!(
"Register allocation checker errors:\n{:?}\nfor vcode:\n{:?}",
err,
vcode
);
err
})
.expect("register allocation checker");
}
Ok((vcode, regalloc_result))
}