summaryrefslogtreecommitdiff
path: root/chapter22
diff options
context:
space:
mode:
Diffstat (limited to 'chapter22')
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/Parser.java4
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java19
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/codegen/GlobalCodeMotion.java13
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/node/CFGNode.java14
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/node/CallNode.java12
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/node/FunNode.java7
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/node/ParmNode.java4
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/node/StopNode.java20
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/TFPARM.java2
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TFPRISC.java3
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/TFPX86.java1
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/TMPX86.java1
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java1
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/sys/sys.smp9
-rw-r--r--chapter22/src/test/java/com/seaofnodes/simple/Chapter01Test.java6
-rw-r--r--chapter22/src/test/java/com/seaofnodes/simple/Chapter18Test.java12
-rw-r--r--chapter22/src/test/java/com/seaofnodes/simple/Chapter19Test.java6
-rw-r--r--chapter22/src/test/java/com/seaofnodes/simple/Chapter20Test.java2
-rw-r--r--chapter22/src/test/java/com/seaofnodes/simple/Chapter21Test.java2
-rw-r--r--chapter22/src/test/java/com/seaofnodes/simple/progs/helloWorld.smp3
-rw-r--r--chapter22/src/test/java/com/seaofnodes/simple/progs/jig.smp21
21 files changed, 109 insertions, 53 deletions
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/Parser.java b/chapter22/src/main/java/com/seaofnodes/simple/Parser.java
index ab2c775c..eae823eb 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/Parser.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/Parser.java
@@ -196,7 +196,7 @@ public class Parser {
ScopeNode breakScope = _breakScope; _breakScope = null;
ScopeNode continueScope = _continueScope; _continueScope = null;
- FunNode fun = _fun = (FunNode)peep(new FunNode(loc(),sig,null,_code._start));
+ FunNode fun = _fun = (FunNode)peep(new FunNode(loc(),sig,_nestedType,null,_code._start));
// Once the function header is available, install in linker table -
// allowing recursive functions. Linker matches on declared args and
// exact fidx, and ignores the return (because the fidx will only match
@@ -731,7 +731,7 @@ public class Parser {
// expr is a constant function
if( t instanceof TypeFunPtr && expr._type instanceof TypeFunPtr tfp && tfp.isConstant() ) {
if( expr instanceof ExternNode ) t = expr._type; // Upgrade declared type to exact function
- else _code.link(tfp)._name = name; // Assign debug name to Simple function
+ else _code.link(tfp).setName(name); // Assign debug name to Simple function
}
} else {
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java b/chapter22/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java
index 26f2e522..8a28dacc 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java
@@ -166,6 +166,22 @@ public class CodeGen {
// Pessimistic peephole optimization on a worklist
_iter.iterate(this);
+
+ // Not really a true optimistic pass, but look for unlinked functions.
+ // This can be removed, which may trigger another round of pessimistic.
+ // This is the point where we flip from a virtual Call Graph (any call
+ // can call any function) to having a correct (but conservative) CG.
+
+ FunNode main = link(_main);
+ for( Node use : _start._outputs )
+ if( use instanceof FunNode fun &&
+ fun.nIns()==2 && fun.in(1)==_start && fun != main &&
+ (fun._name==null || fun._name.startsWith("sys.")) ) {
+ add(fun).setDef(1,Parser.XCTRL);
+ addAll(fun._outputs);
+ }
+ _iter.iterate(this);
+
_tOpto = (int)(System.currentTimeMillis() - t0);
// TODO:
@@ -203,7 +219,7 @@ public class CodeGen {
_phase = Phase.LoopTree;
long t0 = System.currentTimeMillis();
// Build the loop tree, fix never-exit loops
- _start.buildLoopTree(_stop);
+ _start.buildLoopTree(_start,_stop);
_tLoopTree = (int)(System.currentTimeMillis() - t0);
return this;
}
@@ -262,7 +278,6 @@ public class CodeGen {
_rpcMask = new RegMask(_mach.rpc());
_retMasks[3] = _rpcMask;
-
// Convert to machine ops
long t0 = System.currentTimeMillis();
_uid = 1; // All new machine nodes reset numbering
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 c05cfe2e..78e2f75f 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/codegen/GlobalCodeMotion.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/codegen/GlobalCodeMotion.java
@@ -13,19 +13,6 @@ public abstract class GlobalCodeMotion {
// Node.use(0) is always a block tail (either IfNode or head of the
// following block). There are no unreachable infinite loops.
public static void buildCFG( CodeGen code ) {
- // Unlink all linked calls. This can remove RPC constants which
- // shuffled the StartNode outputs so requires a while loop.
- boolean done=false;
- while(!done) {
- done = true;
- for( Node use : code._start._outputs )
- if( use instanceof FunNode fun )
- for( Node c : fun._inputs )
- if( c instanceof CallNode call )
- { call.unlink_all(); done=false; }
- }
-
-
Ary<CFGNode> rpo = new Ary<>(CFGNode.class);
_rpo_cfg(null, code._start, code.visit(), rpo);
// Reverse in-place
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/CFGNode.java b/chapter22/src/main/java/com/seaofnodes/simple/node/CFGNode.java
index 56a33a26..96597648 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/node/CFGNode.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/node/CFGNode.java
@@ -123,7 +123,19 @@ public abstract class CFGNode extends Node {
// Tag all CFG Nodes with their containing LoopNode; LoopNodes themselves
// also refer to *their* containing LoopNode, as well as have their depth.
// Start is a LoopNode which contains all at depth 1.
- public void buildLoopTree(StopNode stop) {
+ public void buildLoopTree(StartNode start, StopNode stop) {
+ // Unlink all linked calls. This can remove RPC constants which
+ // shuffled the StartNode outputs so requires a while loop.
+ boolean done=false;
+ while(!done) {
+ done = true;
+ for( Node use : start._outputs )
+ if( use instanceof FunNode fun )
+ for( Node c : fun._inputs )
+ if( c instanceof CallNode call )
+ { call.unlink_all(); done=false; }
+ }
+
_ltree = stop._ltree = Parser.XCTRL._ltree = new LoopTree((StartNode)this);
_bltWalk(2,null,stop, new BitSet());
}
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/CallNode.java b/chapter22/src/main/java/com/seaofnodes/simple/node/CallNode.java
index 773716f7..8b243e87 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/node/CallNode.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/node/CallNode.java
@@ -32,8 +32,11 @@ public class CallNode extends CFGNode {
return sb.append(")");
}
public String name() {
- if( fptr()._type instanceof TypeFunPtr tfp && tfp.isConstant() )
- return CodeGen.CODE.link(tfp)._name;
+ if( fptr()._type instanceof TypeFunPtr tfp && tfp.isConstant() ) {
+ FunNode fun = CodeGen.CODE.link(tfp);
+ if( fun !=null ) return fun._name;
+ if( fptr() instanceof ExternNode ex ) return ex._extern;
+ }
return null;
}
@@ -139,7 +142,7 @@ public class CallNode extends CFGNode {
assert linked(fun);
int idx = fun._inputs.find(this);
for( Node use : fun._outputs )
- if( use instanceof ParmNode parm )
+ if( use instanceof ParmNode )
use.delDef(idx);
fun.delDef(idx);
cend().delDef(cend()._inputs.find(fun.ret()));
@@ -162,6 +165,9 @@ public class CallNode extends CFGNode {
if( !arg(i+2)._type.isa(tfp.arg(i)) )
return Parser.error( "Argument #"+i+" isa "+arg(i+2)._type+", but must be a "+tfp.arg(i), _loc);
+ if( tfp.fidxs() < 0 )
+ throw Utils.TODO(); // Infinite unknown TFPs? Should be fairly precise CG
+
return null;
}
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/FunNode.java b/chapter22/src/main/java/com/seaofnodes/simple/node/FunNode.java
index 5a356185..c469fc96 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/node/FunNode.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/node/FunNode.java
@@ -21,7 +21,7 @@ public class FunNode extends RegionNode {
public String _name; // Debug name
- public FunNode( Parser.Lexer loc, TypeFunPtr sig, Node... nodes ) { super(loc,nodes); _sig = sig; }
+ public FunNode( Parser.Lexer loc, TypeFunPtr sig, String name, Node... nodes ) { super(loc,nodes); _name=name; _sig = sig; }
public FunNode( FunNode fun ) {
super( fun, fun==null ? null : fun._loc );
if( fun!=null ) {
@@ -69,6 +69,11 @@ public class FunNode extends RegionNode {
}
}
+ public void setName( String name ) {
+ if( _name==null ) _name=name;
+ else _name += "."+name;
+ }
+
@Override
public Type compute() {
// Only dead if no callers after SCCP
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/ParmNode.java b/chapter22/src/main/java/com/seaofnodes/simple/node/ParmNode.java
index 9e11a129..32e41f54 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/node/ParmNode.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/node/ParmNode.java
@@ -45,4 +45,8 @@ public class ParmNode extends PhiNode {
// Always in-progress until we run out of unknown callers
@Override public boolean inProgress() { return fun().inProgress(); }
+
+ @Override public boolean eq( Node n ) {
+ return ((ParmNode)n)._idx==_idx && super.eq(n);
+ }
}
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/StopNode.java b/chapter22/src/main/java/com/seaofnodes/simple/node/StopNode.java
index 9be08ad9..b65535f1 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/node/StopNode.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/node/StopNode.java
@@ -23,11 +23,15 @@ public class StopNode extends CFGNode {
@Override
public StringBuilder _print1(StringBuilder sb, BitSet visited) {
// For the sake of many old tests, and single value prints as "return val"
- if( ret()!=null ) return ret()._print0(sb,visited);
+ ReturnNode ret1 = ret();
+ if( ret1!=null ) return ret1._print0(sb,visited);
sb.append("Stop[ ");
for( Node ret : _inputs )
- if( ret!=null )
- ret._print0(sb, visited).append(" ");
+ if( ret!=null ) {
+ String name = ((ReturnNode)ret).fun()._name;
+ if( name== null || !name.startsWith("sys.") )
+ ret._print0(sb, visited).append(" ");
+ }
return sb.append("]");
}
@@ -37,7 +41,13 @@ public class StopNode extends CFGNode {
// If a single Return, return it.
// Otherwise, null because ambiguous.
public ReturnNode ret() {
- return nIns()==1 && in(0) instanceof ReturnNode ret ? ret : null;
+ Node ret1 = this;
+ for( Node ret : _inputs ) {
+ String name = ((ReturnNode)ret).fun()._name;
+ if( name==null || !name.startsWith("sys.") )
+ ret1 = ret1==this ? ((ReturnNode)ret) : null;
+ }
+ return ret1==this ? null : (ReturnNode)ret1;
}
@Override
@@ -49,7 +59,7 @@ public class StopNode extends CFGNode {
public Node idealize() {
int len = nIns();
for( int i=0; i<nIns(); i++ )
- if( ((ReturnNode)in(i)).fun().isDead() )
+ if( addDep(((ReturnNode)in(i)).fun()).isDead() )
delDef(i--);
if( len != nIns() ) return this;
return null;
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/TFPARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/TFPARM.java
index 16b56553..76e23c30 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/TFPARM.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/TFPARM.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.node.Node;
import com.seaofnodes.simple.node.cpus.riscv.riscv;
import com.seaofnodes.simple.type.TypeFunPtr;
@@ -50,4 +51,5 @@ public class TFPARM extends ConstantNode implements MachNode, RIPRelSize {
String reg = code.reg(this);
_con.print(sb.p(reg).p(" #"));
}
+ @Override public boolean eq(Node n) { return this==n; }
}
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TFPRISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TFPRISC.java
index 17613009..a69cfbe8 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TFPRISC.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TFPRISC.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.node.Node;
import com.seaofnodes.simple.type.TypeFunPtr;
public class TFPRISC extends ConstantNode implements MachNode, RIPRelSize {
@@ -51,5 +52,5 @@ public class TFPRISC extends ConstantNode implements MachNode, RIPRelSize {
@Override public void asm(CodeGen code, SB sb) {
_con.print(sb.p(code.reg(this)).p(" #"));
}
-
+ @Override public boolean eq(Node n) { return this==n; }
}
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/TFPX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/TFPX86.java
index be4d1a83..d7566f9e 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/TFPX86.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/TFPX86.java
@@ -63,4 +63,5 @@ public class TFPX86 extends ConstantNode implements MachNode, RIPRelSize {
else
_con.print(sb.p(reg).p(" = #"));
}
+ @Override public boolean eq(Node n) { return this==n; }
}
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/TMPX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/TMPX86.java
index 70b9dbb0..c44cf2f9 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/TMPX86.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/TMPX86.java
@@ -31,4 +31,5 @@ public class TMPX86 extends ConstantNode implements MachNode, RIPRelSize{
@Override public void asm(CodeGen code, SB sb) {
_con.print(sb.p(code.reg(this)).p(" = #"));
}
+ @Override public boolean eq(Node n) { return this==n; }
}
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 0751a612..bf51f2cb 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
@@ -189,6 +189,7 @@ public class x86_64_v2 extends Machine {
static RegMask callInMask( TypeFunPtr tfp, int idx ) {
if( idx==0 ) return RPC_MASK;
if( idx==1 ) return null;
+ if( idx-2 >= tfp.nargs() ) return null; // Anti-dependence
return switch( CodeGen.CODE._callingConv ) {
case "SystemV" -> callSys5 (tfp,idx);
case "Win64" -> callWin64(tfp,idx);
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/sys/sys.smp b/chapter22/src/main/java/com/seaofnodes/simple/sys/sys.smp
index 67de77ef..50d9166e 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/sys/sys.smp
+++ b/chapter22/src/main/java/com/seaofnodes/simple/sys/sys.smp
@@ -5,7 +5,7 @@ struct sys {
// libc bindings
/** https://www.man7.org/linux/man-pages/man2/<libc call>.2.html */
struct libc {
- // fd buf len -> len
+ // fd buf len -> len
{ i32 i64 i32 -> i32 } write = "C";
// addr len prot flags fd off -> void*
{ i64 i64 i32 i32 i32 i32 -> i64 } mmap = "C";
@@ -17,4 +17,11 @@ struct sys {
i32 MAP_PRIVATE = 2;
i32 MAP_ANON = 32;
};
+ struct io {
+ val p = { u8[~] str ->
+ i64 ptr = str; // cast array base to i64
+ i32 len = str#; // cast length to signed
+ return sys.libc.write(1,ptr,len);
+ };
+ };
};
diff --git a/chapter22/src/test/java/com/seaofnodes/simple/Chapter01Test.java b/chapter22/src/test/java/com/seaofnodes/simple/Chapter01Test.java
index cddbdfcf..ac9adacc 100644
--- a/chapter22/src/test/java/com/seaofnodes/simple/Chapter01Test.java
+++ b/chapter22/src/test/java/com/seaofnodes/simple/Chapter01Test.java
@@ -25,9 +25,9 @@ public class Chapter01Test {
public void testZero() {
CodeGen code = new CodeGen("return 0;");
code.parse();
- for( Node use : code._start._outputs )
- if( use instanceof ConstantNode con && con._type instanceof TypeInteger )
- assertEquals(TypeInteger.constant(0),con._type);
+ Node use = code.expr();
+ if( use instanceof ConstantNode con && con._type instanceof TypeInteger )
+ assertEquals(TypeInteger.constant(0),con._type);
}
@Test
diff --git a/chapter22/src/test/java/com/seaofnodes/simple/Chapter18Test.java b/chapter22/src/test/java/com/seaofnodes/simple/Chapter18Test.java
index 9c8ad66c..16634580 100644
--- a/chapter22/src/test/java/com/seaofnodes/simple/Chapter18Test.java
+++ b/chapter22/src/test/java/com/seaofnodes/simple/Chapter18Test.java
@@ -78,7 +78,7 @@ var sq = { int x ->
return sq(arg)+sq(3);
""");
code.driver(Phase.LocalSched);
- assertEquals("Stop[ return (#2+#2); return (Parm_x(sq,int)*x); ]", code._stop.toString());
+ assertEquals("Stop[ return (Parm_x(sq,int)*x); return (#2+#2); ]", code._stop.toString());
assertEquals("13", Eval2.eval(code, 2));
}
@@ -116,7 +116,7 @@ var fcn = arg ? { int x -> x*x; } : { int x -> x+x; };
return fcn(3);
""");
code.parse().opto();
- assertEquals("Stop[ return #2; return (Parm_x($fun1,int,3)*x); return (Parm_x($fun2,int,3)<<1); ]", code._stop.toString());
+ assertEquals("Stop[ return (Parm_x($fun2,int,3)<<1); return #2; return (Parm_x($fun1,int,3)*x); ]", code._stop.toString());
assertEquals("6", Eval2.eval(code, 0));
assertEquals("9", Eval2.eval(code, 1));
}
@@ -126,7 +126,7 @@ return fcn(3);
public void testFcn5() {
CodeGen code = new CodeGen("val fact = { int x -> x <= 1 ? 1 : x*fact(x-1); }; return fact(arg);");
code.parse().opto().typeCheck();
- assertEquals("Stop[ return #2; return Phi(Region,1,(Parm_x(fact,int,arg,(x-1))*#2)); ]", code._stop.toString());
+ assertEquals("Stop[ return Phi(Region,1,(Parm_x(fact,int,arg,(x-1))*#2)); return #2; ]", code._stop.toString());
assertEquals( "1", Eval2.eval(code, 0));
assertEquals( "1", Eval2.eval(code, 1));
assertEquals( "2", Eval2.eval(code, 2));
@@ -158,7 +158,7 @@ val g = {->2;};
return 2;
""");
code.parse().opto().typeCheck().GCM();
- assertEquals("Stop[ return 1; return 1; return 2; ]", code._stop.toString());
+ assertEquals("Stop[ return 2; return 1; return 1; ]", code._stop.toString());
assertEquals("1", Eval2.eval(code, 0));
}
@@ -176,7 +176,7 @@ for(;;) {
}
""");
code.driver(Phase.LocalSched);
- assertEquals("Stop[ return #2; return Parm_i(x,int); ]", code._stop.toString());
+ assertEquals("Stop[ return Parm_i(x,int); return #2; ]", code._stop.toString());
assertEquals("3", Eval2.eval(code, 0));
}
@@ -348,7 +348,7 @@ if (i2i) return i2i(arg);
return f2f(o)(1);
""");
code.driver(Phase.LocalSched);
- assertEquals("Stop[ return Phi(Region,#2,#2); return Parm_i(o,int); ]", code._stop.toString());
+ assertEquals("Stop[ return Parm_i(i2i.o,int); return Phi(Region,#2,#2); ]", code._stop.toString());
assertEquals("1", Eval2.eval(code, 2));
}
diff --git a/chapter22/src/test/java/com/seaofnodes/simple/Chapter19Test.java b/chapter22/src/test/java/com/seaofnodes/simple/Chapter19Test.java
index f06d8a6a..c6a701a4 100644
--- a/chapter22/src/test/java/com/seaofnodes/simple/Chapter19Test.java
+++ b/chapter22/src/test/java/com/seaofnodes/simple/Chapter19Test.java
@@ -25,7 +25,7 @@ return 0;
public void testString() throws IOException {
String src = Files.readString(Path.of("src/test/java/com/seaofnodes/simple/progs/stringHash.smp"));
CodeGen code = new CodeGen(src).parse().opto().typeCheck().GCM().localSched();
- assertEquals("Stop[ return Phi(Region,._hashCode,Phi(Region,123456789,Phi(Loop,0,(.[]+((Phi_hash<<5)-Phi_hash))))); return Phi(Region,1,0,0,1); ]", code._stop.toString());
+ assertEquals("Stop[ return Phi(Region,1,0,0,1); return Phi(Region,._hashCode,Phi(Region,123456789,Phi(Loop,0,(.[]+((Phi_hash<<5)-Phi_hash))))); ]", code._stop.toString());
//assertEquals("-4898613127354160978", Eval2.eval(code, 2));
}
@@ -316,7 +316,7 @@ val fcn = arg ? { int x -> x*x; } : { int x -> x+x; };
return fcn(2)*10 + fcn(3);
""");
code.driver(Phase.LocalSched,"x86_64_v2", "SystemV");
- assertEquals("Stop[ return (add,#2,(muli,#2)); return (mul,Parm_x($fun1,int),x); return (shli,Parm_x($fun2,int)); ]", code.print());
+ assertEquals("Stop[ return (shli,Parm_x($fun2,int)); return (add,#2,(muli,#2)); return (mul,Parm_x($fun1,int),x); ]", code.print());
}
@Test
@@ -327,6 +327,6 @@ val sq = { int x -> x*x; };
return sq(arg) + sq(3);
""");
code.driver(Phase.LocalSched,"x86_64_v2", "SystemV");
- assertEquals("Stop[ return (add,#2,#2); return (mul,Parm_x(sq,int),x); ]", code.print());
+ assertEquals("Stop[ return (mul,Parm_x(sq,int),x); return (add,#2,#2); ]", code.print());
}
}
diff --git a/chapter22/src/test/java/com/seaofnodes/simple/Chapter20Test.java b/chapter22/src/test/java/com/seaofnodes/simple/Chapter20Test.java
index f0b31065..4c4ac4e4 100644
--- a/chapter22/src/test/java/com/seaofnodes/simple/Chapter20Test.java
+++ b/chapter22/src/test/java/com/seaofnodes/simple/Chapter20Test.java
@@ -104,7 +104,7 @@ return sqrt(arg) + sqrt(cast_int);
String src = Files.readString(Path.of("src/test/java/com/seaofnodes/simple/progs/stringHash.smp"));
testCPU(src,"x86_64_v2", "SystemV", 9,null);
testCPU(src,"riscv" , "SystemV", 5,null);
- testCPU(src,"arm" , "SystemV", 6,null);
+ testCPU(src,"arm" , "SystemV", 3,null);
}
@Test
diff --git a/chapter22/src/test/java/com/seaofnodes/simple/Chapter21Test.java b/chapter22/src/test/java/com/seaofnodes/simple/Chapter21Test.java
index 96e6c5ff..c6e0a3bd 100644
--- a/chapter22/src/test/java/com/seaofnodes/simple/Chapter21Test.java
+++ b/chapter22/src/test/java/com/seaofnodes/simple/Chapter21Test.java
@@ -65,7 +65,7 @@ public class Chapter21Test {
String src = Files.readString(Path.of("src/test/java/com/seaofnodes/simple/progs/stringHash.smp"));
testCPU(src,"x86_64_v2", "SystemV", 9,null);
testCPU(src,"riscv" , "SystemV", 5,null);
- testCPU(src,"arm" , "SystemV", 6,null);
+ testCPU(src,"arm" , "SystemV", 3,null);
}
@Test public void testStringExport() throws IOException {
diff --git a/chapter22/src/test/java/com/seaofnodes/simple/progs/helloWorld.smp b/chapter22/src/test/java/com/seaofnodes/simple/progs/helloWorld.smp
index b83a055c..07ff935f 100644
--- a/chapter22/src/test/java/com/seaofnodes/simple/progs/helloWorld.smp
+++ b/chapter22/src/test/java/com/seaofnodes/simple/progs/helloWorld.smp
@@ -1,4 +1,3 @@
// -*- mode: java; -*-
-i64 buf = "Hello, World!";
-sys.libc.write(1,buf,13);
+sys.io.p("Hello, World!");
return 0;
diff --git a/chapter22/src/test/java/com/seaofnodes/simple/progs/jig.smp b/chapter22/src/test/java/com/seaofnodes/simple/progs/jig.smp
index b3bbf722..2d8d375b 100644
--- a/chapter22/src/test/java/com/seaofnodes/simple/progs/jig.smp
+++ b/chapter22/src/test/java/com/seaofnodes/simple/progs/jig.smp
@@ -1,10 +1,15 @@
// -*- mode: java; -*-
-struct s0 {
- u16 v0;
- i16 v3;
- u32 v5;
+// theory: conservative approx to a CG will link all target fcsn.
+// unlinked *local* fcns with *no* TFP constants can be declared unreachable and removed.
+
+// Newtons approximation to the square root
+val sqrt = { int x ->
+ int guess = x;
+ while( 1 ) {
+ int next = (x/guess + guess)/2;
+ if( next == guess ) return guess;
+ guess = next;
+ }
};
-return new s0.v3;
-if(0)
- while(new s0.v5+new s0.v5) return 0;
-return new s0.v0;
+int cast_int = arg+2;
+return sqrt(arg) + sqrt(cast_int);