summaryrefslogtreecommitdiff
path: root/chapter17b/src/test/java/com/seaofnodes
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2026-10-05 15:38:06 -0700
committerCliff Click <cliffc@acm.org>2026-10-05 15:38:06 -0700
commit81b654d76444d747fdf1d053760e507b50f26e18 (patch)
tree594fa806fc31d848f172d0413de0e431fde6e22a /chapter17b/src/test/java/com/seaofnodes
parent3b8ad2977ef3911aed7c681037e4640dca59749b (diff)
downloadSimple-81b654d76444d747fdf1d053760e507b50f26e18.tar.gz
Simple-81b654d76444d747fdf1d053760e507b50f26e18.zip
Small peep to drop simple store-updates out of loops
Diffstat (limited to 'chapter17b/src/test/java/com/seaofnodes')
-rw-r--r--chapter17b/src/test/java/com/seaofnodes/simple/Chapter11Test.java5
-rw-r--r--chapter17b/src/test/java/com/seaofnodes/simple/Chapter17bTest.java48
2 files changed, 51 insertions, 2 deletions
diff --git a/chapter17b/src/test/java/com/seaofnodes/simple/Chapter11Test.java b/chapter17b/src/test/java/com/seaofnodes/simple/Chapter11Test.java
index 60ff05d8..f0caed02 100644
--- a/chapter17b/src/test/java/com/seaofnodes/simple/Chapter11Test.java
+++ b/chapter17b/src/test/java/com/seaofnodes/simple/Chapter11Test.java
@@ -34,7 +34,8 @@ public class Chapter11Test {
""").parse().iterate();
int[] phis = {0};
stop.walk(n -> {
- if (n instanceof MemPhiNode) phis[0]++;
+ // 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);
@@ -42,7 +43,7 @@ public class Chapter11Test {
!(n instanceof MemPhiNode) && !(n instanceof BulkMemPhiNode));
return null;
});
- assertTrue(phis[0]>=3);
+ assertTrue(phis[0]>=4); // Three fields and the loop counter.
assertArrayEquals(new Object[]{1L,2L,3L},((Evaluator.Obj)Evaluator.evaluate(stop,4)).fields());
}
diff --git a/chapter17b/src/test/java/com/seaofnodes/simple/Chapter17bTest.java b/chapter17b/src/test/java/com/seaofnodes/simple/Chapter17bTest.java
index 976691fc..08c210fb 100644
--- a/chapter17b/src/test/java/com/seaofnodes/simple/Chapter17bTest.java
+++ b/chapter17b/src/test/java/com/seaofnodes/simple/Chapter17bTest.java
@@ -2,6 +2,7 @@ package com.seaofnodes.simple;
import com.seaofnodes.simple.evaluator.Evaluator;
import com.seaofnodes.simple.node.StopNode;
+import com.seaofnodes.simple.node.StoreNode;
import org.junit.Test;
import org.junit.Ignore;
import static org.junit.Assert.assertEquals;
@@ -9,6 +10,53 @@ import static org.junit.Assert.fail;
public class Chapter17bTest {
+ @Test public void testSinkLoopStores() {
+ StopNode stop = new Parser("""
+ struct Totals { int sum; int visits; };
+ val t = new Totals { sum=7; visits=2; };
+ val data = new int[4];
+ for( int i=0; i<data#; i++ ) data[i]=arg+i;
+ for( int i=0; i<(arg<data# ? arg : data#); i++ ) {
+ t.sum = t.sum + data[i];
+ t.visits++;
+ }
+ return t;
+ """).parse().iterate();
+ stop.typeCheck();
+ int[] stores = {0};
+ stop.walk(n -> {
+ if( n instanceof StoreNode st && !st._name.equals("[]") ) {
+ assertEquals(stop.in(0).in(0),st.in(0)); // Both stores at the exit.
+ stores[0]++;
+ }
+ return null;
+ });
+ assertEquals(2,stores[0]);
+ for( int arg : new int[]{-1,0,1,3,4,5} ) {
+ long n = Math.max(0,Math.min(arg,4));
+ var obj = (Evaluator.Obj)Evaluator.evaluate(stop,arg);
+ org.junit.Assert.assertArrayEquals(new Object[]{7+n*arg+n*(n-1)/2,2+n},obj.fields());
+ }
+ }
+
+ @Test public void testKeepObservedLoopStore() {
+ StopNode stop = new Parser("""
+ struct S { int x; };
+ val a = new S;
+ val b = new S;
+ val p = arg ? a : b;
+ int sum=0;
+ for( int i=0; i<4; i++ ) {
+ a.x=i+1;
+ sum+=p.x;
+ }
+ return sum;
+ """).parse().iterate();
+ stop.typeCheck();
+ assertEquals(0L,Evaluator.evaluate(stop,0));
+ assertEquals(10L,Evaluator.evaluate(stop,1));
+ }
+
@Test
public void testJig() {
Parser parser = new Parser("return 1;");