From 81b654d76444d747fdf1d053760e507b50f26e18 Mon Sep 17 00:00:00 2001 From: Cliff Click Date: Mon, 5 Oct 2026 15:38:06 -0700 Subject: Small peep to drop simple store-updates out of loops --- .../java/com/seaofnodes/simple/Chapter11Test.java | 5 ++- .../java/com/seaofnodes/simple/Chapter17bTest.java | 48 ++++++++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) (limited to 'chapter17b/src/test/java/com/seaofnodes') 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=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 { + 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;"); -- cgit v1.2.3