refactoring some stuff and loosening a requrement on assert

Signed-off-by: Jakub Doka <jakub.doka2@gmail.com>
This commit is contained in:
Jakub Doka 2024-12-15 20:49:37 +01:00
parent 6fba7da782
commit 9f43e3bb92
No known key found for this signature in database
GPG key ID: C6E9A89936B8C143

View file

@ -709,7 +709,7 @@ impl Nodes {
); );
debug_assert_matches!( debug_assert_matches!(
self[self[user].inputs[3]].kind, self[self[user].inputs[3]].kind,
Kind::Stre | Kind::Mem | Kind::Phi Kind::Stre | Kind::Mem | Kind::Phi | Kind::Join
); );
self[user].inputs.iter().position(|&v| v == val).is_some_and(|v| v < 3) self[user].inputs.iter().position(|&v| v == val).is_some_and(|v| v < 3)
} }
@ -749,31 +749,28 @@ impl Nodes {
nid nid
} }
fn uses_of<'a>( fn uses_of(&self, nid: Nid, types: &Types, stack: &mut Vec<Nid>, buf: &mut Vec<(Nid, Nid)>) {
&'a self, debug_assert!(stack.is_empty());
nid: Nid, debug_assert!(buf.is_empty());
types: &'a Types,
) -> impl Iterator<Item = (Nid, Nid)> + use<'a> {
if self[nid].kind.is_cfg() && !matches!(self[nid].kind, Kind::Call { .. }) { if self[nid].kind.is_cfg() && !matches!(self[nid].kind, Kind::Call { .. }) {
return None.into_iter().flatten(); return;
} }
let mut uses = vec![]; stack.push(nid);
let mut to_expand = vec![nid];
while let Some(exp) = to_expand.pop() { while let Some(exp) = stack.pop() {
for &o in self[exp].outputs.iter() { for &o in self[exp].outputs.iter() {
if !self.is_data_dep(exp, o, types) { if !self.is_data_dep(exp, o, types) {
continue; continue;
} }
if self.is_unlocked(o) { if self.is_unlocked(o) {
uses.push((self.use_block_of(exp, o), o)); buf.push((self.use_block_of(exp, o), o));
} else { } else {
to_expand.push(o); stack.push(o);
} }
} }
} }
Some(uses).into_iter().flatten()
} }
} }
@ -810,13 +807,14 @@ impl<'a> Regalloc<'a> {
debug_assert!(self.res.dfs_buf.is_empty()); debug_assert!(self.res.dfs_buf.is_empty());
let mut uses_buf = Vec::new();
let mut bundle = Bundle::new(self.res.instrs.len()); let mut bundle = Bundle::new(self.res.instrs.len());
self.res.visited.clear(self.nodes.len()); self.res.visited.clear(self.nodes.len());
for i in (0..self.res.blocks.len()).rev() { for i in (0..self.res.blocks.len()).rev() {
for [a, rest @ ..] in self.nodes.phi_inputs_of(self.res.blocks[i].entry) { for [a, rest @ ..] in self.nodes.phi_inputs_of(self.res.blocks[i].entry) {
if self.res.visited.set(a) { if self.res.visited.set(a) {
self.append_bundle(a, &mut bundle, None); self.append_bundle(a, &mut bundle, None, &mut uses_buf);
} }
for r in rest { for r in rest {
@ -828,6 +826,7 @@ impl<'a> Regalloc<'a> {
r, r,
&mut bundle, &mut bundle,
Some(self.res.node_to_reg[a as usize] as usize - 1), Some(self.res.node_to_reg[a as usize] as usize - 1),
&mut uses_buf,
); );
} }
} }
@ -838,15 +837,22 @@ impl<'a> Regalloc<'a> {
if self.nodes[inst].has_no_value() || self.res.visited.get(inst) || inst == 0 { if self.nodes[inst].has_no_value() || self.res.visited.get(inst) || inst == 0 {
continue; continue;
} }
self.append_bundle(inst, &mut bundle, None); self.append_bundle(inst, &mut bundle, None, &mut uses_buf);
} }
self.res.instrs = instrs; self.res.instrs = instrs;
} }
fn collect_bundle(&mut self, inst: Nid, into: &mut Bundle) { fn append_bundle(
&mut self,
inst: Nid,
tmp: &mut Bundle,
prefered: Option<usize>,
uses_buf: &mut Vec<(Nid, Nid)>,
) {
let dom = self.nodes.idom_of(inst); let dom = self.nodes.idom_of(inst);
self.res.dfs_seem.clear(self.nodes.len()); self.res.dfs_seem.clear(self.nodes.len());
for (cursor, uinst) in self.nodes.uses_of(inst, self.tys) { self.nodes.uses_of(inst, self.tys, &mut self.res.dfs_buf, uses_buf);
for (cursor, uinst) in uses_buf.drain(..) {
if !self.res.dfs_seem.set(uinst) { if !self.res.dfs_seem.set(uinst) {
continue; continue;
} }
@ -876,13 +882,9 @@ impl<'a> Regalloc<'a> {
range.end = new; range.end = new;
debug_assert!(range.start < range.end, "{:?} {inst} {uinst}", range); debug_assert!(range.start < range.end, "{:?} {inst} {uinst}", range);
into.add(range); tmp.add(range);
}); });
} }
}
fn append_bundle(&mut self, inst: Nid, tmp: &mut Bundle, prefered: Option<usize>) {
self.collect_bundle(inst, tmp);
if tmp.is_empty() { if tmp.is_empty() {
self.res.node_to_reg[inst as usize] = u8::MAX; self.res.node_to_reg[inst as usize] = u8::MAX;