Fix regalloc issue

This commit is contained in:
Chris Fallin 2022-11-30 23:36:00 -08:00
parent 284be86cd4
commit 4b40e52c28
No known key found for this signature in database
GPG key ID: 31649E4FE65EB465

View file

@ -58,7 +58,7 @@ impl<'a> Context<'a> {
let mut point = 0; let mut point = 0;
let mut live: HashMap<Value, usize> = HashMap::default(); let mut live: HashMap<Value, usize> = HashMap::default();
let mut block_ends: HashMap<Block, usize> = HashMap::default(); let mut block_starts: HashMap<Block, usize> = HashMap::default();
for &block in &self.cfg.postorder { for &block in &self.cfg.postorder {
self.body.blocks[block].terminator.visit_uses(|u| { self.body.blocks[block].terminator.visit_uses(|u| {
self.handle_use(&mut live, &mut point, u); self.handle_use(&mut live, &mut point, u);
@ -75,7 +75,7 @@ impl<'a> Context<'a> {
} }
point += 1; point += 1;
block_ends.insert(block, point); block_starts.insert(block, point);
// If there were any in-edges from blocks numbered earlier // If there were any in-edges from blocks numbered earlier
// in postorder ("loop backedges"), extend the start of // in postorder ("loop backedges"), extend the start of
@ -84,12 +84,12 @@ impl<'a> Context<'a> {
// extend the *end* of the liverange down to the end of // extend the *end* of the liverange down to the end of
// the loop.) // the loop.)
// //
// Note that we do this *after* inserting our own end // Note that we do this *after* inserting our own start
// above, so we handle self-loops properly. // above, so we handle self-loops properly.
for &pred in self.cfg.preds(block) { for &pred in self.cfg.preds(block) {
if let Some(&end) = block_ends.get(&pred) { if let Some(&start) = block_starts.get(&pred) {
for live_end in live.values_mut() { for live_start in live.values_mut() {
*live_end = end; *live_start = std::cmp::min(*live_start, start);
} }
} }
} }
@ -101,12 +101,15 @@ impl<'a> Context<'a> {
fn handle_def(&mut self, live: &mut HashMap<Value, usize>, point: &mut usize, value: Value) { fn handle_def(&mut self, live: &mut HashMap<Value, usize>, point: &mut usize, value: Value) {
// If the value was not live, make it so just for this // If the value was not live, make it so just for this
// point. Otherwise, end the liverange. // point. Otherwise, end the liverange.
log::trace!("localify: point {}: live {:?}: def {}", point, live, value);
match live.entry(value) { match live.entry(value) {
Entry::Vacant(_) => { Entry::Vacant(_) => {
log::trace!(" -> was dead; use {}..{}", *point, *point + 1);
self.ranges.insert(value, *point..(*point + 1)); self.ranges.insert(value, *point..(*point + 1));
} }
Entry::Occupied(o) => { Entry::Occupied(o) => {
let start = o.remove(); let start = o.remove();
log::trace!(" -> was live; use {}..{}", start, *point + 1);
self.ranges.insert(value, start..(*point + 1)); self.ranges.insert(value, start..(*point + 1));
} }
} }
@ -114,7 +117,9 @@ impl<'a> Context<'a> {
fn handle_use(&mut self, live: &mut HashMap<Value, usize>, point: &mut usize, value: Value) { fn handle_use(&mut self, live: &mut HashMap<Value, usize>, point: &mut usize, value: Value) {
let value = self.body.resolve_alias(value); let value = self.body.resolve_alias(value);
log::trace!("localify: point {}: live {:?}: use {}", point, live, value);
if self.trees.owner.contains_key(&value) { if self.trees.owner.contains_key(&value) {
log::trace!(" -> treeified, going to inst");
// If this is a treeified value, then don't process the use, // If this is a treeified value, then don't process the use,
// but process the instruction directly here. // but process the instruction directly here.
self.handle_inst(live, point, value, /* root = */ false); self.handle_inst(live, point, value, /* root = */ false);
@ -133,16 +138,25 @@ impl<'a> Context<'a> {
root: bool, root: bool,
) { ) {
let value = self.body.resolve_alias(value); let value = self.body.resolve_alias(value);
log::trace!(
"localify: point {}: live {:?}: handling inst {} root {}",
point,
live,
value,
root
);
// If this is an instruction... // If this is an instruction...
if let ValueDef::Operator(_, ref args, _) = &self.body.values[value] { if let ValueDef::Operator(_, ref args, _) = &self.body.values[value] {
// Handle uses. // Handle uses.
for &arg in args { for &arg in args {
log::trace!(" -> arg {}", arg);
self.handle_use(live, point, arg); self.handle_use(live, point, arg);
} }
// If root, we need to process the def. // If root, we need to process the def.
if root { if root {
*point += 1; *point += 1;
log::trace!(" -> def {}", value);
self.handle_def(live, point, value); self.handle_def(live, point, value);
} }
} }