diff options
| author | Darrick Wiebe <darrickw@gmail.com> | 2025-03-31 12:38:12 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-03-31 09:38:12 -0700 |
| commit | 3a7a9bde8ee95b4e2f4c08588428c59125d727e4 (patch) | |
| tree | 7537f023f93f6e75d37f915dcd335604d02b84f2 /chapter21/src/main/java | |
| parent | ec9a8a7f49f7a8b22897ca96cf2aff8c47e475f8 (diff) | |
| download | Simple-3a7a9bde8ee95b4e2f4c08588428c59125d727e4.tar.gz Simple-3a7a9bde8ee95b4e2f4c08588428c59125d727e4.zip | |
Fix sameBlockNoClobber and refine insertAfterAndReplace (#189)
Also fix firstReg when empty
Diffstat (limited to 'chapter21/src/main/java')
3 files changed, 10 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 ceb75d64..f595bf74 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/codegen/RegAlloc.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/codegen/RegAlloc.java @@ -251,7 +251,7 @@ public class RegAlloc { // alloc // V2/rax - kills prior RAX // st4 [V1],len - No good, must split around - makeSplit("def/empty1",round,lrg).insertAfterAndReplace((Node)lrg._machDef, false/*true*/); + makeSplit("def/empty1",round,lrg).insertAfterAndReplace((Node)lrg._machDef, this, 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); @@ -341,7 +341,7 @@ public class RegAlloc { // TODO: split before all inputs (except the last; at least 1 split here must be extra) if( def instanceof PhiNode phi && !(def instanceof ParmNode) ) { SplitNode split = makeSplit("def/self",round,lrg); - split.insertAfterAndReplace(def,false); + split.insertAfterAndReplace(def,this,false); if( split.nOuts()==0 ) split.kill(); insertBefore(phi,1,"use/self/phi",round,lrg); @@ -398,7 +398,7 @@ public class RegAlloc { // 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,true); + makeSplit("def/loop",round,lrg).insertAfterAndReplace(n,this,true); } // PhiNodes check all CFG inputs @@ -559,14 +559,15 @@ public class RegAlloc { return true; } - private boolean sameBlockNoClobber( SplitNode split ) { + public 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; + Node def0 = def instanceof ProjNode ? def.in(0) : def; int defreg = lrg(def)._reg; if( defreg == -1 ) defreg = lrg(def)._mask.firstReg(); + if( defreg == -1 ) return false; // no allowed registers -> clobbered for( int idx = cfg._outputs.find(split) -1; idx >= 0; idx-- ) { Node n = cfg.out(idx); if( n==def0 ) return true; // No clobbers diff --git a/chapter21/src/main/java/com/seaofnodes/simple/codegen/RegMask.java b/chapter21/src/main/java/com/seaofnodes/simple/codegen/RegMask.java index 88ce8627..12ab222c 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/codegen/RegMask.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/codegen/RegMask.java @@ -66,6 +66,7 @@ public class RegMask { public short firstReg() { + if( isEmpty() ) return -1; return (short)(_bits0 != 0 ? Long.numberOfTrailingZeros(_bits0) : Long.numberOfTrailingZeros(_bits1)+64); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/Node.java b/chapter21/src/main/java/com/seaofnodes/simple/node/Node.java index 29d2f669..28f70fce 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/Node.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/Node.java @@ -10,6 +10,7 @@ import com.seaofnodes.simple.type.TypeInteger; import java.util.*; import java.util.function.Function; import static com.seaofnodes.simple.codegen.CodeGen.CODE; +import com.seaofnodes.simple.codegen.RegAlloc; /** * All Nodes in the Sea of Nodes IR inherit from the Node class. @@ -321,13 +322,12 @@ public abstract class Node { // Replace uses of `def` with `this`, and insert `this` immediately after // `def` in the basic block. - public void insertAfterAndReplace( Node def, boolean must ) { + public void insertAfterAndReplace( Node def, RegAlloc r, boolean must ) { CFGNode cfg = insertAfter(def); for( int j=def.nOuts()-1; j>=0; j-- ) { // Can we avoid a split of a split? 'this' split is used by // another split in the same block. - if( !must && def.out(j) instanceof SplitNode split && def.out(j).cfg0()==cfg && - !split._kind.contains("self") ) + if( !must && def.out(j) instanceof SplitNode split && r.sameBlockNoClobber(split) ) continue; Node use = def._outputs.del(j); use.unlock(); |
