summaryrefslogtreecommitdiff
path: root/chapter29/src/test/java/com/seaofnodes/simple/CallEndTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'chapter29/src/test/java/com/seaofnodes/simple/CallEndTest.java')
-rw-r--r--chapter29/src/test/java/com/seaofnodes/simple/CallEndTest.java85
1 files changed, 85 insertions, 0 deletions
diff --git a/chapter29/src/test/java/com/seaofnodes/simple/CallEndTest.java b/chapter29/src/test/java/com/seaofnodes/simple/CallEndTest.java
new file mode 100644
index 00000000..a174bdf7
--- /dev/null
+++ b/chapter29/src/test/java/com/seaofnodes/simple/CallEndTest.java
@@ -0,0 +1,85 @@
+package com.seaofnodes.simple;
+
+import com.seaofnodes.simple.codegen.CodeGen;
+import com.seaofnodes.simple.node.*;
+import com.seaofnodes.simple.type.*;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+public class CallEndTest {
+ @Test public void testReturnWideningMonotonicity() {
+ new CodeGen("return 0;").parse();
+ TypeFunPtr sig = TypeFunPtr.make1((byte)2,true,TypeFunPtr.TEMPTY,TypeInteger.I32,100);
+ FunNode fun = new FunNode(null,sig,"f",null);
+ Node value = ConstantNode.raw(Type.TOP);
+ ReturnNode ret = new ReturnNode(ConstantNode.raw(Type.CONTROL),
+ ConstantNode.raw(TypeMem.START),value,null,fun);
+ Type[] inputs = new Type[]{Type.TOP,TypeInteger.TOP,TypeInteger.I32.dual(),
+ TypeInteger.ZERO,TypeInteger.constant(Long.MAX_VALUE),
+ TypeInteger.make(-1,1,(byte)0),TypeInteger.make(-1,1,(byte)1),
+ TypeInteger.make(-1,1,(byte)2),TypeInteger.make(-1,1,(byte)3),
+ TypeInteger.I32,TypeInteger.BOT,TypeScalar.BOT,Type.BOTTOM};
+ Type[] outputs = new Type[inputs.length];
+ for( int i=0; i<inputs.length; i++ ) {
+ value._type = inputs[i];
+ outputs[i] = ret.compute();
+ }
+ for( int i=0; i<inputs.length; i++ )
+ for( int j=0; j<inputs.length; j++ )
+ if( inputs[i].isa(inputs[j]) )
+ assertTrue(inputs[i]+" -> "+inputs[j],outputs[i].isa(outputs[j]));
+ }
+
+ // Growing the target set must not narrow the result, even when the linked
+ // return has exhausted its integer widening budget.
+ @Test public void testUnknownTargetMonotonicity() {
+ CodeGen code = new CodeGen("return 0;").parse();
+ TypeFunPtr sig = TypeFunPtr.make1((byte)2,true,TypeFunPtr.TEMPTY,TypeInteger.BOT,100);
+ FunNode fun = new FunNode(null,sig,"f",null);
+ code._linker.setX(100,fun);
+ Node ctrl = ConstantNode.raw(Type.CONTROL);
+ Node mem = ConstantNode.raw(TypeMem.START);
+ Node value = ConstantNode.raw(TypeInteger.I32);
+ ReturnNode ret = new ReturnNode(ctrl,mem,value,null,fun);
+ ret._type = ret.compute();
+ Node fptr = ConstantNode.raw(sig.makeFrom(TypeInteger.I32));
+ CallNode call = new CallNode(null,ctrl,mem,fptr).init();
+ CallEndNode end = new CallEndNode(call,TypeRPC.BOT);
+ end.addDef(ret);
+ Type linked = end.compute();
+ TypeFunPtr unknown = TypeFunPtr.make(false,TypeFunPtr.TEMPTY,TypeInteger.I32);
+ assertTrue(fptr._type.isa(unknown));
+ fptr._type = unknown;
+ assertTrue("Adding unknown targets must only lose precision",linked.isa(end.compute()));
+ }
+
+ @Test public void testUnlinkedCallIsPhaseIndependent() {
+ CodeGen code = new CodeGen("return 0;").parse();
+ TypeFunPtr sig = TypeFunPtr.make1((byte)2,true,TypeFunPtr.TEMPTY,TypeInteger.I32,100);
+ CallNode call = new CallNode(null,ConstantNode.raw(Type.CONTROL),
+ ConstantNode.raw(TypeMem.START),ConstantNode.raw(sig)).init();
+ CallEndNode end = new CallEndNode(call,TypeRPC.BOT);
+ Type expected = TypeTuple.make(Type.CONTROL,TypeMem.BOT,TypeInteger.I32);
+ for( CodeGen.Phase phase : new CodeGen.Phase[]{CodeGen.Phase.Parse,
+ CodeGen.Phase.Opto,CodeGen.Phase.IterPostOpto} ) {
+ code._phase = phase;
+ assertSame(phase.toString(),expected,end.compute());
+ }
+ }
+
+ @Test public void testExternalTargets() {
+ CodeGen code = new CodeGen("return 0;").parse();
+ code.externFunc(100,"first");
+ code.externFunc(101,"second");
+ TypeFunPtr sig = TypeFunPtr.make1((byte)2,true,TypeFunPtr.TEMPTY,TypeInteger.I32,100);
+ Node fptr = ConstantNode.raw(sig);
+ CallNode call = new CallNode(null,ConstantNode.raw(Type.CONTROL),
+ ConstantNode.raw(TypeMem.START),fptr).init();
+ CallEndNode end = new CallEndNode(call,TypeRPC.BOT);
+ Type first = end.compute();
+ fptr._type = sig.meet(sig.makeFrom(101));
+ assertTrue(first.isa(end.compute()));
+ assertSame(TypeInteger.I32,((TypeTuple)end.compute()).ret());
+ assertSame(Type.BOTTOM,((TypeMem)((TypeTuple)end.compute()).mem())._t);
+ }
+}