diff options
| author | Cliff Click <cliffc@acm.org> | 2026-10-19 14:56:14 -0700 |
|---|---|---|
| committer | Cliff Click <cliffc@acm.org> | 2026-10-19 14:56:14 -0700 |
| commit | 7edca9823ec8ef0aed10c88fa07ef969792aab77 (patch) | |
| tree | d95e308cac7a9c5039a59be636d881982a9b4878 /chapter-interprocedural-sccp/src/test/java/com/seaofnodes/simple/Chapter11Test.java | |
| parent | 3617495d8efbcce23bbc9f1754c7d27d34d30a52 (diff) | |
| download | Simple-main.tar.gz Simple-main.zip | |
Split from ch25, SCCP and interprocedural SCCPmain
Diffstat (limited to 'chapter-interprocedural-sccp/src/test/java/com/seaofnodes/simple/Chapter11Test.java')
| -rw-r--r-- | chapter-interprocedural-sccp/src/test/java/com/seaofnodes/simple/Chapter11Test.java | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/chapter-interprocedural-sccp/src/test/java/com/seaofnodes/simple/Chapter11Test.java b/chapter-interprocedural-sccp/src/test/java/com/seaofnodes/simple/Chapter11Test.java new file mode 100644 index 00000000..7c5e05f8 --- /dev/null +++ b/chapter-interprocedural-sccp/src/test/java/com/seaofnodes/simple/Chapter11Test.java @@ -0,0 +1,61 @@ +package com.seaofnodes.simple; + +import com.seaofnodes.simple.codegen.*; +import com.seaofnodes.simple.node.*; +import org.junit.Test; +import static org.junit.Assert.*; + +public class Chapter11Test { + @Test public void testIndependentField() { + var code = new CodeGen(""" + struct S { int x; int y; }; + !S !s = new S; + s.x = 42; + while (arg > 0) { s.y = s.y + arg; arg = arg - 1; } + return s.x; + """).driver(CodeGen.Phase.FinalizeIR); + var stop = code._stop; + assertEquals("return 42;",stop.toString()); + assertEquals("42",Eval2.eval(code,5)); + assertNull(stop.walk(n -> n instanceof LoadNode ? n : null)); + } + + @Test public void testParallelMemoryPhis() { + var code = new CodeGen(""" + struct S { int x; int y; int z; }; + !S !a = new S; !S !b = new S; + !S !p = a; if (arg) p = b; + while (arg > 0) { + a.x = p.x + arg; + a.y = p.y + 2; + a.z = p.z + 3; + arg = arg - 1; + } + return a; + """).driver(CodeGen.Phase.FinalizeIR); + var stop = code._stop; + int[] phis = {0}; + stop.walk(n -> { + // Store sinking can replace field memory Phis with value Phis. + if (n instanceof PhiNode) phis[0]++; + if (n instanceof MemMergeNode m && m.in(1) instanceof BulkMemPhiNode b) + for(int a=b._aliases.nextSetBit(0); a>=0; a=b._aliases.nextSetBit(a+1)) + assertTrue(a<m.nIns() && m.in(a)!=null); + assertFalse(n instanceof PhiNode && n.isMem() && + !(n instanceof MemPhiNode) && !(n instanceof BulkMemPhiNode) && !(n instanceof ParmNode)); + return null; + }); + assertTrue(phis[0]>=4); // Three fields and the loop counter. + assertEquals("S{x=1,y=2,z=3}",Eval2.eval(code,4)); + } + + @Test public void testLateSliceWorklist() { + // Seed 97 exposed a store selecting a bulk predecessor without queuing + // it. Keep both the worklist assertion and the final heap check. + for (int seed : new int[]{0,97,123,456}) { + var code = new CodeGen(Chapter10Test.NESTED_MEMORY,com.seaofnodes.simple.type.TypeInteger.BOT,seed,false).parse(); + code.iter().opto().iterPostOpto().finalizeIR(); + assertEquals("S{x=9,y=25,z=17}",Eval2.eval(code,4)); + } + } +} |
