summaryrefslogtreecommitdiff
path: root/chapter24/src/main/java
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2026-10-07 11:18:47 -0700
committerCliff Click <cliffc@acm.org>2026-10-07 11:18:47 -0700
commitdf5efaa0d05b3583eb6ca3b5f67df83827889e42 (patch)
tree439bfa2dec84d05ce55f0d492f4192230c06506c /chapter24/src/main/java
parent8a20d5238855de5479d84e7fd8e84561844e2dc4 (diff)
downloadSimple-df5efaa0d05b3583eb6ca3b5f67df83827889e42.tar.gz
Simple-df5efaa0d05b3583eb6ca3b5f67df83827889e42.zip
Make RA deterministic
Diffstat (limited to 'chapter24/src/main/java')
-rw-r--r--chapter24/src/main/java/com/seaofnodes/simple/codegen/RegAlloc.java16
1 files changed, 12 insertions, 4 deletions
diff --git a/chapter24/src/main/java/com/seaofnodes/simple/codegen/RegAlloc.java b/chapter24/src/main/java/com/seaofnodes/simple/codegen/RegAlloc.java
index 0899099e..7e826661 100644
--- a/chapter24/src/main/java/com/seaofnodes/simple/codegen/RegAlloc.java
+++ b/chapter24/src/main/java/com/seaofnodes/simple/codegen/RegAlloc.java
@@ -378,9 +378,9 @@ public class RegAlloc {
(use instanceof MachNode mach && mach.twoAddress()!=0 && use.in(mach.twoAddress())==def) )
insertBefore( use, use._inputs.find(def), "use/self/use",round,lrg );
}
- // Split after the Phi which extends the LRG. Split also before
- // Phi slot 1 (and not all inputs), because Phis extend the live range.
- // TODO: split before all inputs (except the last; at least 1 split here must be extra)
+ // Split after the Phi and before its entry. Also isolate inputs
+ // shared with another Phi: otherwise the shared input keeps the
+ // conflicting live ranges joined, even after splitting the entry.
if( def instanceof PhiNode phi && !(def instanceof ParmNode) ) {
if( !deferred.containsKey(phi) ) {
SplitNode split = makeSplit("def/self",round,lrg);
@@ -388,7 +388,9 @@ public class RegAlloc {
if( split.nOuts()==0 )
split.killOrdered();
}
- insertBefore(phi,1,"use/self/phi",round,lrg);
+ for( int i=1; i<(deferred.containsKey(phi) ? 2 : phi.nIns()); i++ )
+ if( i==1 || sharedPhiInput(phi,i) )
+ insertBefore(phi,i,"use/self/phi",round,lrg);
}
// Split before two-address ops which extend the live range
if( def instanceof MachNode mach && mach.twoAddress()!= 0 )
@@ -405,6 +407,12 @@ public class RegAlloc {
}
+ private static boolean sharedPhiInput(PhiNode phi, int i) {
+ for( Node use : phi.in(i)._outputs )
+ if( use instanceof PhiNode && use!=phi ) return true;
+ return false;
+ }
+
// Generic: split around the outermost loop with non-split def/uses. This
// covers both self-conflicts (once we split deep enough) and register
// pressure issues.