Fix subtle interaction of treeifier-induced code motion and local (register) allocation.

This commit is contained in:
Chris Fallin 2022-11-29 21:04:55 -08:00
parent 3d102ac899
commit 52013a7f46
No known key found for this signature in database
GPG key ID: 31649E4FE65EB465
2 changed files with 53 additions and 15 deletions

View file

@ -241,6 +241,47 @@ impl<'a> Context<'a> {
) )
}); });
fn visit_inst_uses(
body: &FunctionBody,
cfg: &CFGInfo,
trees: &Trees,
block: Block,
inst: Value,
live_values: &mut HashSet<Value>,
live_locals: &mut HashSet<Local>,
results: &mut Localifier,
affinities: &HashMap<Value, SmallVec<[Value; 4]>>,
) {
body.values[inst].visit_uses(|u| {
// If treeified, then don't process use. However, do
// process uses of the treeified value.
if trees.owner.contains_key(&u) {
visit_inst_uses(
&body,
&cfg,
trees,
block,
u,
live_values,
live_locals,
results,
affinities,
);
} else {
handle_use(
body,
cfg,
block,
u,
live_values,
live_locals,
results,
affinities,
)
}
});
}
for &inst in self.body.blocks[block].insts.iter().rev() { for &inst in self.body.blocks[block].insts.iter().rev() {
handle_def( handle_def(
self.body, self.body,
@ -249,21 +290,17 @@ impl<'a> Context<'a> {
&mut live_locals, &mut live_locals,
&self.results, &self.results,
); );
self.body.values[inst].visit_uses(|u| { visit_inst_uses(
// If treeified, then don't process use. &self.body,
if !self.trees.owner.contains_key(&u) { &self.cfg,
handle_use( &self.trees,
self.body, block,
self.cfg, inst,
block, &mut live_values,
u, &mut live_locals,
&mut live_values, &mut self.results,
&mut live_locals, &self.affinities,
&mut self.results, );
&self.affinities,
)
}
});
} }
for &(_, param) in &self.body.blocks[block].params { for &(_, param) in &self.body.blocks[block].params {

View file

@ -180,6 +180,7 @@ fn const_eval(op: &Operator, vals: &[ConstVal]) -> Option<ConstVal> {
(Operator::I64Extend32S, [ConstVal::I64(a)]) => { (Operator::I64Extend32S, [ConstVal::I64(a)]) => {
Some(ConstVal::I64(*a as i32 as i64 as u64)) Some(ConstVal::I64(*a as i32 as i64 as u64))
} }
(Operator::Select, [x, y, ConstVal::I32(k)]) => Some(if *k != 0 { *x } else { *y }),
_ => None, _ => None,
} }