summaryrefslogtreecommitdiff
path: root/chapter22/src/main/java/com
diff options
context:
space:
mode:
Diffstat (limited to 'chapter22/src/main/java/com')
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/codegen/Encoding.java22
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/codegen/GlobalCodeMotion.java14
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/codegen/RegAlloc.java2
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpX86.java6
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/DivX86.java2
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ImmX86.java1
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/RegX86.java1
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java2
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/print/ASMPrinter.java4
9 files changed, 40 insertions, 14 deletions
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/codegen/Encoding.java b/chapter22/src/main/java/com/seaofnodes/simple/codegen/Encoding.java
index 7a43f099..db799b98 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/codegen/Encoding.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/codegen/Encoding.java
@@ -359,11 +359,6 @@ public class Encoding {
slide = 0;
for( int i=0; i<len; i++ ) {
CFGNode bb = _code._cfg.at(i);
- // Functions pad to align 16
- if( bb instanceof FunNode ) {
- int newStart = _opStart[bb._nid]+slide;
- slide += (newStart+15 & -16)-newStart;
- }
_opStart[bb._nid] += slide;
// Slide down all other (non-CFG) ops in the block
for( Node n : bb._outputs )
@@ -387,6 +382,23 @@ public class Encoding {
}
+ // Go again, inserting padding on function headers. Since no
+ // short-jumps span function headers, the padding will not make any
+ // short jumps fail.
+ for( int i=0; i<len; i++ ) {
+ CFGNode bb = _code._cfg.at(i);
+ // Functions pad to align 16
+ if( bb instanceof FunNode ) {
+ int newStart = _opStart[bb._nid]+slide;
+ slide += (newStart+15 & -16)-newStart;
+ }
+ _opStart[bb._nid] += slide;
+ for( Node n : bb._outputs )
+ if( n instanceof MachNode && !(n instanceof CFGNode) )
+ _opStart[n._nid] += slide;
+ }
+
+
// Copy/slide the bits to make space for all the longer branches
int grow = _opStart[_code._cfg.at(len-1)._nid] - oldStarts[len-1];
if( grow > 0 ) { // If no short-form ops, nothing to do here
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/codegen/GlobalCodeMotion.java b/chapter22/src/main/java/com/seaofnodes/simple/codegen/GlobalCodeMotion.java
index 7e0a58ac..04a119c2 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/codegen/GlobalCodeMotion.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/codegen/GlobalCodeMotion.java
@@ -177,14 +177,22 @@ public abstract class GlobalCodeMotion {
}
// Walk all inputs and put on worklist, as their last-use might now be done
- for( Node def : n._inputs )
- if( def!=null && late[def._nid]==null ) {
+ for( Node def : n._inputs ) {
+ if( def!=null && late[def._nid]==null )
work.push(def);
- // if the def has a load use, maybe the load can fire
+ // if the def has a load use, maybe the load can fire
+ if( def!=null )
for( Node out : def._outputs )
if( out instanceof MemOpNode ld && ld._isLoad && late[ld._nid]==null )
work.push(ld);
+ }
+
+ if( n instanceof LoopNode loop ) {
+ for( Node phi : loop._outputs ) {
+ if( phi instanceof PhiNode && late[phi._nid]==null )
+ work.push(phi);
}
+ }
}
}
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/codegen/RegAlloc.java b/chapter22/src/main/java/com/seaofnodes/simple/codegen/RegAlloc.java
index 68b55f6f..57d0d90c 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/codegen/RegAlloc.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/codegen/RegAlloc.java
@@ -559,7 +559,7 @@ public class RegAlloc {
private void postColor() {
int maxReg = -1;
for( CFGNode bb : _code._cfg ) { // For all ops
- if( bb instanceof FunNode fun )
+ if( bb instanceof FunNode )
maxReg = -1; // Reset for new function
// Compute frame size, based on arguments and largest reg seen
if( bb instanceof ReturnNode ret )
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpX86.java
index 06a36d99..3e4200c0 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpX86.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpX86.java
@@ -9,6 +9,12 @@ public class CmpX86 extends MachConcreteNode implements MachNode {
@Override public String op() { return "cmp"; }
@Override public RegMask regmap(int i) { return x86_64_v2.RMASK; }
@Override public RegMask outregmap() { return x86_64_v2.FLAGS_MASK; }
+ // This one is marginal: cloning a Cmp[reg,reg] means stretching the
+ // lifetimes of 2 normal registers in exchange for shortening a flags
+ // register lifetime. Spilling flags is (probably) relatively expensive
+ // compared to some normal registers - and those normal registers might not
+ // be spilling!
+ @Override public boolean isClone() { return true; }
@Override public void encoding( Encoding enc ) {
short dst = enc.reg(in(1));
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/DivX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/DivX86.java
index 87b8b0c3..06f001b0 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/DivX86.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/DivX86.java
@@ -8,7 +8,7 @@ public class DivX86 extends MachConcreteNode implements MachNode {
DivX86( Node div ) { super(div); }
@Override public String op() { return "div"; }
@Override public RegMask regmap(int i) {
- return (i==1) ? x86_64_v2.RAX_MASK : x86_64_v2.RMASK;
+ return (i==1) ? x86_64_v2.RAX_MASK : x86_64_v2.DIV_MASK;
}
@Override public RegMask outregmap() { return x86_64_v2.RAX_MASK; }
@Override public RegMask killmap() { return x86_64_v2.RDX_MASK; }
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ImmX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ImmX86.java
index 760d6805..9e602b47 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ImmX86.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ImmX86.java
@@ -15,6 +15,7 @@ public abstract class ImmX86 extends MachConcreteNode implements MachNode {
@Override public RegMask regmap(int i) { return x86_64_v2.RMASK; }
@Override public RegMask outregmap() { return x86_64_v2.WMASK; }
@Override public int twoAddress() { return 1; }
+ @Override public RegMask killmap() { return x86_64_v2.FLAGS_MASK; }
abstract int opcode();
abstract int mod();
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/RegX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/RegX86.java
index 0997644d..a4a6a814 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/RegX86.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/RegX86.java
@@ -8,6 +8,7 @@ public abstract class RegX86 extends MachConcreteNode {
RegX86( Node add ) { super(add); }
@Override public RegMask regmap(int i) { return x86_64_v2.RMASK; }
@Override public RegMask outregmap() { return x86_64_v2.WMASK; }
+ @Override public RegMask killmap() { return x86_64_v2.FLAGS_MASK; }
@Override public int twoAddress() { return 1; }
abstract int opcode();
@Override public void encoding( Encoding enc ) {
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java
index 60e10d79..94c1511a 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java
@@ -43,6 +43,8 @@ public class x86_64_v2 extends Machine {
static RegMask XMASK = new RegMask(FP_BITS);
static RegMask FLAGS_MASK = new RegMask(FLAGS);
static RegMask RPC_MASK = new RegMask(RPC);
+ // Divide mask: exclude RDX:RAX
+ static RegMask DIV_MASK = new RegMask(RD_BITS & ~(1L<<RAX) & ~(1L<<RDX));
static final long SPILLS = -(1L << MAX_REG);
static final RegMask SPLIT_MASK = new RegMask(WR_BITS | FP_BITS /* | (1L<<FLAGS)*/ | SPILLS, -1L );
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/print/ASMPrinter.java b/chapter22/src/main/java/com/seaofnodes/simple/print/ASMPrinter.java
index 45f71e40..366ae376 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/print/ASMPrinter.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/print/ASMPrinter.java
@@ -22,10 +22,6 @@ public abstract class ASMPrinter {
if( code._cfg.at(i) instanceof FunNode fun )
iadr = print(iadr,sb,code,fun,i);
- // Skip padding
- while( ((iadr+7) & -8) > iadr )
- iadr++;
-
// constant pool
iadr = (iadr+15)&-16; // pad to 16
Encoding enc = code._encoding;