WARNING! Access to this system is limited to authorised users only.
Unauthorised users may be subject to prosecution.
Unauthorised access to this system is a criminal offence under Australian law (Federal Crimes Act 1914 Part VIA)
It is a criminal offence to:
(1) Obtain access to data without authority. -Penalty 2 years imprisonment.
(2) Damage, delete, alter or insert data without authority. -Penalty 10 years imprisonment.
User activity is monitored and recorded. Anyone using this system expressly consents to such monitoring and recording.

To protect your data, the CISO officer has suggested users to enable 2FA as soon as possible.
Currently 2.2% of users enabled 2FA.

Commit d152c68c authored by qinsoon's avatar qinsoon
Browse files

validating register allocation

when proceeding to a new block, prune alive entries based on liveout and
liveins
parent 1461b6f1
......@@ -2870,7 +2870,12 @@ impl <'a> InstructionSelection {
unimplemented!()
},
&Constant::NullRef => {
self.backend.emit_xor_r_r(&tmp, &tmp);
// xor a, a -> a will mess up register allocation validation
// since it uses a regsiter with arbitrary value
// self.backend.emit_xor_r_r(&tmp, &tmp);
// for now, use mov -> a
self.backend.emit_mov_r_imm(&tmp, 0);
},
_ => panic!("expected ireg")
}
......
......@@ -251,7 +251,6 @@ impl AliveEntries {
}
} else {
// find entry without a temp in the other set and do intersect
for another_entry in another.inner.values() {
if !another_entry.has_temp() {
if entry.intersect(another_entry) {
......@@ -264,6 +263,40 @@ impl AliveEntries {
changed
}
pub fn preserve_list(&mut self, list: &Vec<MuID>) {
let mut indices_to_delete : Vec<EntryID> = vec![];
for (index, entry) in self.inner.iter() {
if !entry.has_temp() {
if list.iter().any(|x| entry.match_reg(*x)) {
} else {
indices_to_delete.push(*index);
}
} else {
let temp = entry.get_temp().unwrap();
if !vec_utils::find_value(list, temp).is_some() {
indices_to_delete.push(*index);
}
}
}
// always preserve entries with spill location
let mut indices_to_really_delete : Vec<EntryID> = vec![];
for index in indices_to_delete {
let entry = self.inner.get(&index).unwrap();
if !entry.has_stack_slots() {
indices_to_really_delete.push(index);
}
}
// delete
for index in indices_to_really_delete {
self.inner.remove(&index);
}
}
}
#[derive(Clone)]
......
......@@ -133,6 +133,16 @@ pub fn validate_regalloc(cf: &CompiledFunction,
trace!("---");
}
// find liveout of the block, and only preserve what is in the liveout
let liveout = match mc.get_ir_block_liveout(&block) {
Some(liveout) => liveout,
None => panic!("cannot find liveout for block {}", block)
};
alive.preserve_list(liveout);
debug!("liveout is {:?}", liveout);
debug!("preserve only entries in liveout, we get:");
debug!("{}", alive);
// find succeeding blocks
let succeeding_blocks : Vec<MuName> = mc.get_succs(last_inst).iter()
.map(|x| match mc.is_label(*x - 1) {
......@@ -168,13 +178,37 @@ pub fn validate_regalloc(cf: &CompiledFunction,
debug!("push block {} to work list", succeeding_blocks[0]);
} else if succeeding_blocks.len() == 2 {
// conditional branch
// FIXME: need to prune alive entries based on live in
// it is possible that a variable is alive at the end of a BB, and used
// only in one of its successors
work_queue.insert(succeeding_blocks[0].clone(), alive.clone());
work_queue.insert(succeeding_blocks[1].clone(), alive.clone());
debug!("push block {} to work list", succeeding_blocks[0]);
debug!("push block {} to work list", succeeding_blocks[1]);
// 1st branch
{
let block1 = succeeding_blocks[0].clone();
let block1_livein = match mc.get_ir_block_livein(&block1) {
Some(livein) => livein,
None => panic!("cannot find livein for block {}", block1)
};
let mut block1_alive = alive.clone();
block1_alive.preserve_list(block1_livein);
work_queue.insert(block1, block1_alive);
debug!("push block {} to work list", succeeding_blocks[0]);
}
// 2nd branch
{
let block2 = succeeding_blocks[1].clone();
let block2_livein = match mc.get_ir_block_livein(&block2) {
Some(livein) => livein,
None => panic!("cannot find livein for block {}", block2)
};
let mut block2_alive = alive.clone();
block2_alive.preserve_list(block2_livein);
work_queue.insert(block2, block2_alive);
debug!("push block {} to work list", succeeding_blocks[1]);
}
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment