summaryrefslogtreecommitdiff
path: root/chapter21/src/main/java/com
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2025-03-29 16:48:49 -0700
committerCliff Click <cliffc@acm.org>2025-03-29 16:48:49 -0700
commit7d60f55d2c97677e03a6b01869b4832111a12267 (patch)
tree5442480e02f9aa352d86dae0c69d2f42083b57bc /chapter21/src/main/java/com
parent8ea9c74afef87cb562604bf94f803853babe2d33 (diff)
downloadSimple-7d60f55d2c97677e03a6b01869b4832111a12267.tar.gz
Simple-7d60f55d2c97677e03a6b01869b4832111a12267.zip
Force split during a parallel assignment
Was not inserting same-block split, but actually required if doing parallel assignment from fixed regs to fixed regs
Diffstat (limited to 'chapter21/src/main/java/com')
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/codegen/RegAlloc.java30
1 files changed, 22 insertions, 8 deletions
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/codegen/RegAlloc.java b/chapter21/src/main/java/com/seaofnodes/simple/codegen/RegAlloc.java
index fa3c2b81..36de2cdb 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/codegen/RegAlloc.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/codegen/RegAlloc.java
@@ -254,7 +254,7 @@ public class RegAlloc {
makeSplit("def/empty1",round,lrg).insertAfterAndReplace((Node)lrg._machDef, false/*true*/);
// Split just before use
if( lrg._1regUseCnt==1 || (lrg._1regDefCnt==1 && ((Node)lrg._machDef).nOuts()==1) )
- insertBefore((Node)lrg._machUse,lrg._uidx,"use/empty1",round,lrg,true);
+ insertBefore((Node)lrg._machUse,lrg._uidx,"use/empty1",round,lrg);
return true;
}
@@ -394,10 +394,10 @@ public class RegAlloc {
(min==max || n.cfg0().loopDepth() <= min) ) {
// Cloneable constants will be cloned at uses, not after def
if( !(n instanceof MachNode mach && mach.isClone()) &&
- // Single user is already a split
- !(n.nOuts()==1 && n.out(0) instanceof SplitNode) )
+ // Single user is already a split adjacent
+ !(n.nOuts()==1 && n.out(0) instanceof SplitNode split && sameBlockNoClobber(split) ) )
// Split after def in min loop nest
- makeSplit("def/loop",round,lrg).insertAfterAndReplace(n,false);
+ makeSplit("def/loop",round,lrg).insertAfterAndReplace(n,true);
}
// PhiNodes check all CFG inputs
@@ -415,15 +415,12 @@ public class RegAlloc {
} else {
// Others check uses
for( int i=1; i<n.nIns(); i++ ) {
- boolean sizeN=false;
// This is a LRG use
// splitting in inner loop or at loop border
if( lrgSame( n.in( i ), lrg ) &&
(min == max || (n.in(i) instanceof MachNode mach && mach.isClone()) || n.cfg0().loopDepth() <= min) )
- // Not a single-use split same block already
- //!(n.in(i) instanceof SplitNode && n.in(i).nOuts()==1 && n.cfg0()==n.in(i).cfg0() && (sizeN=!((MachNode)n).regmap(i).size1())) )
// Split before in this block
- insertBefore( n, i, "use/loop/use", round,lrg, sizeN );
+ insertBefore( n, i, "use/loop/use", round,lrg, false );
}
}
}
@@ -560,4 +557,21 @@ public class RegAlloc {
lo.setDefOrdered(1,hi.in(1));
return true;
}
+
+ private boolean sameBlockNoClobber( SplitNode split ) {
+ Node def = split.in(1);
+ CFGNode cfg = def.cfg0();
+ if( cfg != split.cfg0() ) return false; // Not same block
+ // Get multinode head
+ Node def0 = def instanceof MultiNode ? def.in(0) : def;
+ int defreg = lrg(def)._reg;
+ if( defreg == -1 ) defreg = lrg(def)._mask.firstReg();
+ for( int idx = cfg._outputs.find(split) -1; idx >= 0; idx-- ) {
+ Node n = cfg.out(idx);
+ if( n==def0 ) return true; // No clobbers
+ if( lrg(n)!=null && lrg(n)._reg == defreg )
+ return false; // Clobbered
+ }
+ throw Utils.TODO();
+ }
}