summaryrefslogtreecommitdiff
path: root/chapter21/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'chapter21/src/main/java')
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/Node.java20
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/PhiNode.java51
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/StoreNode.java1
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CastARM.java18
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/IntARM.java3
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java6
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/IntRISC.java5
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java2
8 files changed, 72 insertions, 34 deletions
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 e13b77a2..c02a4924 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/Node.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/Node.java
@@ -16,14 +16,14 @@ import static com.seaofnodes.simple.codegen.CodeGen.CODE;
* The Node class provides common functionality used by all subtypes.
* Subtypes of Node specialize by overriding methods.
*/
-public abstract class Node {
+public abstract class Node implements Cloneable {
/**
* Each node has a unique dense Node ID within a compilation context
* The ID is useful for debugging, for using as an offset in a bitvector,
* as well as for computing equality of nodes (to be implemented later).
*/
- public final int _nid;
+ public int _nid;
/**
* Inputs to the node. These are use-def references to Nodes.
@@ -32,7 +32,7 @@ public abstract class Node {
* Ordering is required because e.g. "a/b" is different from "b/a".
* The first input (offset 0) is often a {@link CFGNode} node.
*/
- public final Ary<Node> _inputs;
+ public Ary<Node> _inputs;
/**
* Outputs reference Nodes that are not null and have this Node as an
@@ -43,7 +43,7 @@ public abstract class Node {
* walked in either direction. These outputs are typically used for
* efficient optimizations but otherwise have no semantics meaning.
*/
- public final Ary<Node> _outputs;
+ public Ary<Node> _outputs;
/**
@@ -679,6 +679,18 @@ public abstract class Node {
// Does not need to be implemented in isCFG() nodes.
Node copy(Node lhs, Node rhs) { throw Utils.TODO("Binary ops need to implement copy"); }
+ public Node copy() {
+ Node n;
+ try { n = (Node)clone(); }
+ catch( Exception e ) { throw new RuntimeException(e); }
+ n._nid = CODE.getUID(); // allocate unique dense ID
+ n._inputs = new Ary<>(Node.class);
+ n._outputs = new Ary<>(Node.class);
+ n._deps = null;
+ n._hash = 0;
+ return n;
+ }
+
// Report any post-optimize errors
public Parser.ParseException err() { return null; }
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/PhiNode.java b/chapter21/src/main/java/com/seaofnodes/simple/node/PhiNode.java
index f66e7ad4..be31dd38 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/PhiNode.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/PhiNode.java
@@ -80,31 +80,38 @@ public class PhiNode extends Node {
if( r.in(i)._type == Type.XCONTROL )
return null;
- // Pull "down" a common data op. One less op in the world. One more
- // Phi, but Phis do not make code.
- // Phi(op(A,B),op(Q,R),op(X,Y)) becomes
- // op(Phi(A,Q,X), Phi(B,R,Y)).
+ // Generic "pull down op"
Node op = in(1);
- if( !isMem() && op.nIns()==3 && op.in(0)==null && same_op() ) {
+ if( same_op() ) {
assert !(op instanceof CFGNode);
- Node[] lhss = new Node[nIns()];
- Node[] rhss = new Node[nIns()];
- lhss[0] = rhss[0] = in(0); // Set Region
- for( int i=1; i<nIns(); i++ ) {
- lhss[i] = in(i).in(1);
- rhss[i] = in(i).in(2);
+ boolean solo=true;
+ for( int i=1; i<nIns(); i++ )
+ if( in(i).nOuts() > 1 || in(i).in(0)!=null )
+ { solo=false; break; }
+ if( solo ) {
+ Node cp = op.copy();
+ cp.addDef(null); // No control
+
+ for( int j=1; j<op.nIns(); j++ ) {
+ boolean needsPhi = false;
+ Node x = op.in(j); // Jth input from sample #1
+ for( int i=2; i<nIns(); i++ )
+ if( in(i).in(j) != x )
+ { needsPhi=true; break; }
+ if( needsPhi ) {
+ x = new PhiNode(_label,op.in(j)._type.glb());
+ x.addDef(region());
+ for( int i=1; i<nIns(); i++ )
+ x.addDef(in(i).in(j));
+ x = x.peephole();
+ }
+ cp.addDef(x);
+ }
+ // Test not running backwards, which can happen for e.g. And's
+ if( cp.compute().isa(compute()) )
+ return cp;
+ cp.kill();
}
- Node phi_lhs = new PhiNode(_label, _declaredType,lhss).peephole();
- Node phi_rhs = new PhiNode(_label, _declaredType,rhss).peephole();
- Node down = op.copy(phi_lhs,phi_rhs);
- // Test not running backwards, which can happen for e.g. And's
- if( down.compute().isa(compute()) )
- return down;
- in(1).in(1).addDep(this);
- in(1).in(2).addDep(this);
- in(2).in(1).addDep(this);
- in(2).in(2).addDep(this);
- down.kill();
}
// If merging Phi(N, cast(N)) - we are losing the cast JOIN effects, so just remove.
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/StoreNode.java b/chapter21/src/main/java/com/seaofnodes/simple/node/StoreNode.java
index 7f43f53c..e8f5c4e2 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/StoreNode.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/StoreNode.java
@@ -84,7 +84,6 @@ public class StoreNode extends MemOpNode {
}
}
-
return null;
}
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CastARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CastARM.java
new file mode 100644
index 00000000..a5a4e112
--- /dev/null
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CastARM.java
@@ -0,0 +1,18 @@
+package com.seaofnodes.simple.node.cpus.arm;
+
+import com.seaofnodes.simple.SB;
+import com.seaofnodes.simple.codegen.CodeGen;
+import com.seaofnodes.simple.codegen.Encoding;
+import com.seaofnodes.simple.codegen.RegMask;
+import com.seaofnodes.simple.node.CastNode;
+import com.seaofnodes.simple.node.MachNode;
+
+public class CastARM extends CastNode implements MachNode {
+ public CastARM( CastNode cast ) { super(cast); }
+ @Override public String op() { return label(); }
+ @Override public RegMask regmap(int i) { assert i==1; return RegMask.FULL; }
+ @Override public RegMask outregmap() { return RegMask.FULL; }
+ @Override public int twoAddress( ) { return 1; }
+ @Override public void encoding( Encoding enc ) { }
+ @Override public void asm(CodeGen code, SB sb) { _t.print(sb.p(code.reg(in(1))).p(" isa ")); }
+}
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/IntARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/IntARM.java
index 8affb4c6..0a07b07a 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/IntARM.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/IntARM.java
@@ -4,6 +4,7 @@ import com.seaofnodes.simple.*;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.ConstantNode;
import com.seaofnodes.simple.node.MachNode;
+import com.seaofnodes.simple.type.Type;
import com.seaofnodes.simple.type.TypeInteger;
// Integer constants
@@ -19,7 +20,7 @@ public class IntARM extends ConstantNode implements MachNode {
@Override public void encoding( Encoding enc ) {
short self = enc.reg(this);
- long x = ((TypeInteger)_con).value();
+ long x = _con==Type.NIL ? 0 : ((TypeInteger)_con).value();
int nb0 = 0;
int nb1 = 0;
// Count number of 0000 and FFFF blocks
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java
index 0aea0ae9..bedda4e2 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java
@@ -620,7 +620,7 @@ public class arm extends Machine {
case AndNode and -> and(and);
case BoolNode bool -> cmp(bool);
case CallNode call -> call(call);
- case CastNode cast -> new CastNode(cast);
+ case CastNode cast -> new CastARM(cast);
case CallEndNode cend -> new CallEndARM(cend);
case CProjNode c -> new CProjNode(c);
case ConstantNode con -> con(con);
@@ -696,7 +696,7 @@ public class arm extends Machine {
: new SubARM(sub);
}
- private Node con(ConstantNode con) {
+ private Node con( ConstantNode con ) {
if( !con._con.isConstant() ) return new ConstantNode( con ); // Default unknown caller inputs
return switch( con._con ) {
case TypeInteger ti -> new IntARM(con);
@@ -705,7 +705,7 @@ public class arm extends Machine {
case TypeMemPtr tmp -> new ConstantNode(con);
case TypeNil tn -> throw Utils.TODO();
// TOP, BOTTOM, XCtrl, Ctrl, etc. Never any executable code.
- case Type t -> new ConstantNode(con);
+ case Type t -> t==Type.NIL ? new IntARM(con) : new ConstantNode(con);
};
}
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/IntRISC.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/IntRISC.java
index 764c49e6..70d5c18f 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/IntRISC.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/IntRISC.java
@@ -4,6 +4,7 @@ import com.seaofnodes.simple.*;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.ConstantNode;
import com.seaofnodes.simple.node.MachNode;
+import com.seaofnodes.simple.type.Type;
import com.seaofnodes.simple.type.TypeInteger;
// 12-bit integer constant. Larger constants are made up in the instruction
@@ -17,10 +18,10 @@ public class IntRISC extends ConstantNode implements MachNode {
@Override public IntRISC copy() { return new IntRISC(this); }
@Override public void encoding( Encoding enc ) {
short dst = enc.reg(this);
- TypeInteger ti = (TypeInteger)_con;
+ int val = _con==Type.NIL ? 0 : (int)(((TypeInteger)_con).value() & 0xFFF);
// Explicit truncation of larger immediates; this will sign-extend on
// load and this is handled during instruction selection.
- enc.add4(riscv.i_type(riscv.OP_IMM, dst, 0, riscv.ZERO, (int)(ti.value() & 0xFFF)));
+ enc.add4(riscv.i_type(riscv.OP_IMM, dst, 0, riscv.ZERO, val));
}
@Override public void asm(CodeGen code, SB sb) {
String reg = code.reg(this);
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java
index b4c382c5..12b3a12c 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java
@@ -573,7 +573,7 @@ public class x86_64_v2 extends Machine {
return new CmpX86(bool);
}
- private Node con(ConstantNode con) {
+ private Node con( ConstantNode con ) {
if(!con._con.isConstant()) return new ConstantNode(con); // Default unknown caller inputs
return switch (con._con) {
case TypeInteger ti -> new IntX86(con);