summaryrefslogtreecommitdiff
path: root/chapter25/src/main
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2026-09-30 16:41:07 -0700
committerCliff Click <cliffc@acm.org>2026-09-30 16:41:07 -0700
commita996996a1ad776089a4cb9cbf7744f5f4e8dde6d (patch)
treeb210c9175d96fd8e908a47660c044729788eb0e5 /chapter25/src/main
parentf01ee0522e63b0266314b4e88e524ea2da95cf0d (diff)
downloadSimple-a996996a1ad776089a4cb9cbf7744f5f4e8dde6d.tar.gz
Simple-a996996a1ad776089a4cb9cbf7744f5f4e8dde6d.zip
Forward port mem stuff to ch21
Also a minor reg-alloc improvement for BrainFuck, ported up to ch25
Diffstat (limited to 'chapter25/src/main')
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/codegen/RegAlloc.java16
1 files changed, 14 insertions, 2 deletions
diff --git a/chapter25/src/main/java/com/seaofnodes/simple/codegen/RegAlloc.java b/chapter25/src/main/java/com/seaofnodes/simple/codegen/RegAlloc.java
index 196a1142..97bde2c9 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/codegen/RegAlloc.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/codegen/RegAlloc.java
@@ -694,8 +694,8 @@ public class RegAlloc {
if( defreg != usereg && splitBypass(bb,j,n,defreg) )
usereg = lrg(n.in(1))._reg;
- // Split has same reg? Useless! Can remove it!
- if( defreg == usereg ) {
+ // Same register, or the next instruction can use the source directly.
+ if( defreg == usereg || splitForward(bb,j,n,usereg) ) {
n.removeSplit();
j--;
continue;
@@ -708,6 +708,18 @@ public class RegAlloc {
}
}
+ // A sole, adjacent use can read the source register directly. Nothing can
+ // clobber it in between; only the operand mask and two-address tie remain.
+ private boolean splitForward( CFGNode bb, int j, Node split, int reg ) {
+ if( split.nOuts()!=1 || j+1==bb.nOuts() ) return false;
+ Node use = split.out(0);
+ if( use!=bb.out(j+1) || use instanceof PhiNode || use instanceof CFGNode ||
+ !(use instanceof MachNode mach) ) return false;
+ int i = use._inputs.find(split);
+ RegMask mask = mach.regmap(i);
+ return mask!=null && mask.test(reg) && mach.twoAddress()!=i;
+ }
+
private boolean splitBypass( CFGNode bb, int j, Node lo, int defreg ) {
// Attempt to bypass split
Node hi = lo.in(1);