Skip to content

Commit 9c5e39e

Browse files
committed
fix: ra split error
1 parent aa6ee09 commit 9c5e39e

82 files changed

Lines changed: 4372 additions & 31 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,3 @@ Mkfile.old
5555
dkms.conf
5656
/core-rs/target
5757
/paper
58-
/core-rs/epass-ir/tests/epir

core-rs/epass-ir/src/cg/alloc.rs

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::env::Env;
55
use crate::error::Result;
66
use crate::ir::insn::InsnKind;
77
use crate::ir::value::VrType;
8-
use crate::ir::{Function, InsnId, InsertPos, Value};
8+
use crate::ir::{Function, InsertPos, InsnId, Value};
99
use crate::{internal, invalid};
1010

1111
use super::prepare::{create_alloc, ensure_extra};
@@ -67,8 +67,15 @@ pub fn pre_spill(env: &mut Env, func: &mut Function, cg: &mut CgState) -> Result
6767
cg.extra_mut(v).w += 1;
6868
let adj = cg.extra(v).adj.clone();
6969
for u in adj {
70-
// u is in the clique if it appears earlier in the SEO.
71-
if seo[..i].contains(&u) {
70+
// On a chordal graph, every earlier neighbor of `v` in a perfect
71+
// elimination order is mutually adjacent and therefore belongs to
72+
// this clique. Our interference graph is not always chordal, so an
73+
// MCS order is not necessarily perfect; only keep `u` if it is
74+
// adjacent to every value already in `q`. Otherwise `q` is merely an
75+
// earlier-neighbor set, and treating it as an oversized clique can
76+
// force bogus spills or fail with "no spillable VR" even when the
77+
// graph is colorable.
78+
if seo[..i].contains(&u) && q.iter().all(|&x| cg.extra(u).adj.contains(&x)) {
7279
q.push(u);
7380
cg.extra_mut(u).w += 1;
7481
}
@@ -110,7 +117,10 @@ pub fn spill(
110117
) -> Result<()> {
111118
let _ = env;
112119
for &v in to_spill {
113-
if matches!(func.insn(v).kind, InsnKind::Call { .. } | InsnKind::AllocArray { .. }) {
120+
if matches!(
121+
func.insn(v).kind,
122+
InsnKind::Call { .. } | InsnKind::AllocArray { .. }
123+
) {
114124
return Err(internal!("attempted to spill a call/allocarray"));
115125
}
116126
let users = func.insn(v).users.clone();
@@ -157,11 +167,7 @@ fn spill_one_use(
157167
) -> Result<()> {
158168
match func.insn(user).kind.clone() {
159169
// A store of the spilled value into its own slot: nothing to do.
160-
InsnKind::Store
161-
if func.insn(user).values.first() == Some(&Value::Insn(user)) =>
162-
{
163-
Ok(())
164-
}
170+
InsnKind::Store if func.insn(user).values.first() == Some(&Value::Insn(user)) => Ok(()),
165171
InsnKind::Phi => {
166172
// Reload at the end of each predecessor block contributing v.
167173
let entries = func.insn(user).phi.clone();
@@ -268,9 +274,7 @@ pub fn pick_spill_victim(func: &Function, cg: &CgState, failed: InsnId) -> Resul
268274
}
269275
}
270276
best.ok_or_else(|| {
271-
crate::error::Error::RegAlloc(
272-
"coloring failed and no spillable value is available".into(),
273-
)
277+
crate::error::Error::RegAlloc("coloring failed and no spillable value is available".into())
274278
})
275279
}
276280

0 commit comments

Comments
 (0)