calculate use positions
This commit is contained in:
@@ -14,12 +14,16 @@ use crate::{domtree, postorder, InstPosition};
|
|||||||
use super::data_structures::u64_key;
|
use super::data_structures::u64_key;
|
||||||
use super::Stats;
|
use super::Stats;
|
||||||
|
|
||||||
#[derive(Default, Clone, Copy)]
|
#[derive(Default, Clone)]
|
||||||
struct VRegData {
|
struct VRegData {
|
||||||
pub preg: Option<PReg>,
|
pub preg: Option<PReg>,
|
||||||
pub slot_idx: Option<u32>,
|
pub slot_idx: Option<u32>,
|
||||||
pub def_block: Option<Block>,
|
pub def_block: Option<Block>,
|
||||||
pub reftype: bool,
|
pub reftype: bool,
|
||||||
|
|
||||||
|
// use information
|
||||||
|
pub cur_use_idx: u32,
|
||||||
|
pub uses: SmallVec<[u32; 8]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Clone, Copy)]
|
#[derive(Default, Clone, Copy)]
|
||||||
@@ -395,18 +399,20 @@ pub fn run<F: Function>(func: &F, mach_env: &MachineEnv) -> Result<Output, RegAl
|
|||||||
let mut state = FastAllocState::init(func, mach_env);
|
let mut state = FastAllocState::init(func, mach_env);
|
||||||
let const_state = ReadOnlyData::init(func, mach_env);
|
let const_state = ReadOnlyData::init(func, mach_env);
|
||||||
|
|
||||||
|
calc_use_positions(&mut state, &const_state);
|
||||||
|
|
||||||
state.blocks[func.entry_block().index()].params_allocated = true;
|
state.blocks[func.entry_block().index()].params_allocated = true;
|
||||||
|
|
||||||
let len = const_state.postorder.len();
|
let len = const_state.postorder.len();
|
||||||
for i in 0..len {
|
for i in 0..len {
|
||||||
let block = const_state.postorder[len - 1 - i];
|
let block = const_state.postorder[len - 1 - i];
|
||||||
if state.blocks[block.index()].reg_allocated {
|
if state.blocks[block.index()].reg_allocated {
|
||||||
trace!("Block {} already allocated. Skipping", i);
|
trace!("Block {} already allocated. Skipping", block.index());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
state.blocks[block.index()].reg_allocated = true;
|
state.blocks[block.index()].reg_allocated = true;
|
||||||
|
|
||||||
trace!("Allocating block {}", i);
|
trace!("Allocating block {}", block.index());
|
||||||
|
|
||||||
allocate_block_insts(&mut state, &const_state, block)?;
|
allocate_block_insts(&mut state, &const_state, block)?;
|
||||||
handle_out_block_params(&mut state, &const_state, block)?;
|
handle_out_block_params(&mut state, &const_state, block)?;
|
||||||
@@ -1023,3 +1029,47 @@ fn handle_out_block_params<'a, F: Function>(
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn calc_use_positions<'a, F: Function>(
|
||||||
|
state: &mut FastAllocState<'a, F>,
|
||||||
|
const_state: &ReadOnlyData,
|
||||||
|
) {
|
||||||
|
// we use a pseudo-counter to have a uniform position for instructions
|
||||||
|
let mut cur_pos = 0u32;
|
||||||
|
let len = const_state.postorder.len();
|
||||||
|
for i in 0..len {
|
||||||
|
let block = const_state.postorder[len - 1 - i];
|
||||||
|
trace!("Calculating uses for block {}", block.index());
|
||||||
|
|
||||||
|
let insts = state.func.block_insns(block);
|
||||||
|
for inst in insts.clone().iter() {
|
||||||
|
let operands = state.func.inst_operands(inst);
|
||||||
|
for op in operands {
|
||||||
|
if op.kind() != OperandKind::Use {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if op.vreg() == VReg::invalid() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
state.vregs[op.vreg().vreg()].uses.push(cur_pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
cur_pos += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let last_inst = insts.last();
|
||||||
|
if !state.func.is_branch(last_inst) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for i in 0..state.func.block_succs(block).len() {
|
||||||
|
for vreg in state.func.branch_blockparams(block, last_inst, i) {
|
||||||
|
state.vregs[vreg.vreg()].uses.push(cur_pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cur_pos += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user