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
//! Compilation backend pipeline: optimized IR to VCode / binemit.

use crate::ir::Function;
use crate::machinst::*;
use crate::settings;
use crate::timing;

use log::debug;
use regalloc::{allocate_registers, RegAllocAlgorithm};

/// Compile the given function down to VCode with allocated registers, ready
/// for binary emission.
pub fn compile<B: LowerBackend>(
    f: &Function,
    b: &B,
    abi: Box<dyn ABIBody<I = B::MInst>>,
) -> CodegenResult<VCode<B::MInst>>
where
    B::MInst: ShowWithRRU,
{
    // This lowers the CL IR.
    let mut vcode = Lower::new(f, abi)?.lower(b)?;

    let universe = &B::MInst::reg_universe(vcode.flags());

    debug!("vcode from lowering: \n{}", vcode.show_rru(Some(universe)));

    // Perform register allocation.
    let algorithm = match vcode.flags().regalloc() {
        settings::Regalloc::Backtracking => RegAllocAlgorithm::Backtracking,
        settings::Regalloc::BacktrackingChecked => RegAllocAlgorithm::BacktrackingChecked,
        settings::Regalloc::ExperimentalLinearScan => RegAllocAlgorithm::LinearScan,
    };

    let result = {
        let _tt = timing::regalloc();
        allocate_registers(
            &mut vcode, algorithm, universe, /*request_block_annotations=*/ false,
        )
        .map_err(|err| {
            debug!(
                "Register allocation error for vcode\n{}\nError: {:?}",
                vcode.show_rru(Some(universe)),
                err
            );
            err
        })
        .expect("register allocation")
    };

    // Reorder vcode into final order and copy out final instruction sequence
    // all at once. This also inserts prologues/epilogues.
    vcode.replace_insns_from_regalloc(result);

    vcode.remove_redundant_branches();

    // Do final passes over code to finalize branches.
    vcode.finalize_branches();

    debug!(
        "vcode after regalloc: final version:\n{}",
        vcode.show_rru(Some(universe))
    );

    Ok(vcode)
}