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/codegen/Encoding.java15
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/LoopNode.java14
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/Node.java2
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NJmpRISC.java10
4 files changed, 23 insertions, 18 deletions
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/codegen/Encoding.java b/chapter21/src/main/java/com/seaofnodes/simple/codegen/Encoding.java
index b4d5aefa..335715c6 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/codegen/Encoding.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/codegen/Encoding.java
@@ -159,8 +159,11 @@ public class Encoding {
Ary<CFGNode> rpo = new Ary<>(CFGNode.class);
BitSet visit = _code.visit();
for( Node n : _code._start._outputs )
- if( n instanceof FunNode fun )
+ if( n instanceof FunNode fun ) {
+ int x = rpo._len;
_rpo_cfg(fun, visit, rpo);
+ assert rpo.at(x) instanceof ReturnNode;
+ }
rpo.add(_code._start);
// Reverse in-place
@@ -227,13 +230,19 @@ public class Encoding {
t.invert();
f.invert();
CProjNode tmp=f; f=t; t=tmp; // Swap t/f
+ int d=tld; tld=fld; fld=d; // Swap depth
}
- // Always visit the False side last (so True side first), so that
+ // Whichever side is visited first becomes last in the RPO. With
+ // no loops, visit the False side last (so True side first) so that
// when the False RPO visit returns, the IF is immediately next.
// When the RPO is reversed, the fall-through path will always be
// following the IF.
- if( t.nOuts()==1 && !invert ) {
+
+ // If loops are involved, attempt to keep them in a line. Visit
+ // the exits first, so they follow the loop body when the order gets
+ // reversed.
+ if( fld < tld || (fld==tld && f.nOuts()==1) ) {
_rpo_cfg(f,visit,rpo);
_rpo_cfg(t,visit,rpo);
} else {
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/LoopNode.java b/chapter21/src/main/java/com/seaofnodes/simple/node/LoopNode.java
index 6b4026c5..787b43d2 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/LoopNode.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/LoopNode.java
@@ -49,18 +49,16 @@ public class LoopNode extends RegionNode {
NeverNode iff = CodeGen.CODE._mach == null
? new NeverNode(back()) // Ideal never-branch
: CodeGen.CODE._mach.never(back()); // Machine never-branch
- for( Node use : _outputs )
- if( use instanceof PhiNode )
- iff.addDef(use);
CProjNode t = new CProjNode(iff,0,"True" ).init();
CProjNode f = new CProjNode(iff,1,"False").init();
- setDef(2,f);
- iff._ltree = t._ltree = f._ltree = _ltree;
+ setDef(2,t);
+ iff._ltree = t._ltree = _ltree;
+ ReturnNode ret = fun.ret();
+ f._ltree = ret._ltree;
// Now fold control into the exit. Might have 1 valid exit, or an
// XCtrl or a bunch of prior NeverNode exits.
Node top = new ConstantNode(Type.TOP).peephole();
- ReturnNode ret = fun.ret();
Node ctrl = ret.ctrl(), mem = ret.mem(), expr = ret.expr();
if( ctrl!=null && ctrl._type != Type.XCONTROL ) {
// Perfect aligned exit?
@@ -74,11 +72,11 @@ public class LoopNode extends RegionNode {
expr = new PhiNode(r,expr).init();
}
// Append new Never exit
- ctrl.addDef(t );
+ ctrl.addDef(f );
mem .addDef(top);
expr.addDef(top);
} else {
- ctrl = t;
+ ctrl = f;
mem = top;
expr = top;
}
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 1e9630e3..45217e80 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/Node.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/Node.java
@@ -334,6 +334,8 @@ public abstract class Node {
int i;
if( use instanceof PhiNode phi ) {
cfg = phi.region().cfg(uidx);
+ if( cfg instanceof CProjNode && cfg.in(0) instanceof NeverNode nvr )
+ cfg = nvr.cfg0();
i = cfg.nOuts()-1;
} else {
i = cfg._outputs.find(use);
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NJmpRISC.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NJmpRISC.java
index f0d28a3a..39e9052b 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NJmpRISC.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NJmpRISC.java
@@ -14,17 +14,13 @@ public class NJmpRISC extends NeverNode implements MachNode, RIPRelSize {
@Override public String label() { return op(); }
@Override public String comment() { return "L"+cproj(1)._nid; }
@Override public StringBuilder _print1( StringBuilder sb, BitSet visited ) { return sb.append("jmp "); }
- @Override public RegMask regmap(int i) {
- if( i!=3 ) return null;
- TypeFunPtr tfp = cproj(0).uctrl().fun().sig();
- return riscv.retMask(tfp,2);
- }
+ @Override public RegMask regmap(int i) { throw Utils.TODO(); }
@Override public RegMask outregmap() { return null; }
@Override public void encoding( Encoding enc ) {
// Short form +/-4K: beq r0,r0,imm12
// Long form: auipc rX,imm20/32; jal r0,[rX+imm12/32]
- enc.jump(this,cproj(1));
+ enc.jump(this,cproj(0));
enc.add4(riscv.j_type(riscv.OP_JAL, 0, 0));
}
@@ -45,6 +41,6 @@ public class NJmpRISC extends NeverNode implements MachNode, RIPRelSize {
}
@Override public void asm(CodeGen code, SB sb) {
- sb.p(label(cproj(1).uctrl()));
+ sb.p(label(cproj(0).uctrl()));
}
}