summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarrick Wiebe <darrickw@gmail.com>2025-03-31 12:38:12 -0400
committerGitHub <noreply@github.com>2025-03-31 09:38:12 -0700
commit3a7a9bde8ee95b4e2f4c08588428c59125d727e4 (patch)
tree7537f023f93f6e75d37f915dcd335604d02b84f2
parentec9a8a7f49f7a8b22897ca96cf2aff8c47e475f8 (diff)
downloadSimple-3a7a9bde8ee95b4e2f4c08588428c59125d727e4.tar.gz
Simple-3a7a9bde8ee95b4e2f4c08588428c59125d727e4.zip
Fix sameBlockNoClobber and refine insertAfterAndReplace (#189)
Also fix firstReg when empty
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/codegen/RegAlloc.java11
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/codegen/RegMask.java1
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/Node.java6
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();