summaryrefslogtreecommitdiff
path: root/chapter15/src
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2024-10-13 16:50:30 -0700
committerCliff Click <cliffc@acm.org>2024-10-14 08:52:32 -0700
commiteb18b6eab34d71a9041030959473c1ec0409c170 (patch)
tree19fdc41d3c2b3c39d6dc3c651aede58fcf597b69 /chapter15/src
parentf2be9faaef2f3fd4465924eaa0236fc832003469 (diff)
downloadSimple-eb18b6eab34d71a9041030959473c1ec0409c170.tar.gz
Simple-eb18b6eab34d71a9041030959473c1ec0409c170.zip
fix lifetime issues with GVN gone wild
Diffstat (limited to 'chapter15/src')
-rw-r--r--chapter15/src/main/java/com/seaofnodes/simple/Parser.java13
-rw-r--r--chapter15/src/main/java/com/seaofnodes/simple/node/Node.java2
-rw-r--r--chapter15/src/test/java/com/seaofnodes/simple/Chapter15Test.java20
3 files changed, 27 insertions, 8 deletions
diff --git a/chapter15/src/main/java/com/seaofnodes/simple/Parser.java b/chapter15/src/main/java/com/seaofnodes/simple/Parser.java
index 728aaca7..4bb18d6b 100644
--- a/chapter15/src/main/java/com/seaofnodes/simple/Parser.java
+++ b/chapter15/src/main/java/com/seaofnodes/simple/Parser.java
@@ -785,6 +785,7 @@ public class Parser {
TypeStruct base = tmp._obj;
int fidx = base.find(name);
if( fidx == -1 ) throw error("Accessing unknown field '" + name + "' from '" + ptr.str() + "'");
+ expr.keep();
// Get field type and layout offset from base type and field index fidx
Field f = base._fields[fidx]; // Field from field index
@@ -792,7 +793,8 @@ public class Parser {
if( name.equals("[]") ) { // If field is an array body
// Array index math
Node idx = require(parseExpression(),"]");
- off = new AddNode(con(base.aryBase()),new ShlNode(idx,con(base.aryScale())).peephole()).peephole();
+ Node shl = new ShlNode(idx,con(base.aryScale())).peephole();
+ off = new AddNode(con(base.aryBase()),shl).peephole();
} else { // Else normal struct field
// Hardwired field offset
off = con(base.offset(fidx));
@@ -802,20 +804,21 @@ public class Parser {
// Disambiguate "obj.fld==x" boolean test from "obj.fld=x" field assignment
if( peek('=') ) _lexer._position--;
else {
+ off.keep();
Node val = parseExpression();
// Auto-truncate when storing to narrow fields
- val = zsMask(val,f._type);
- Node st = new StoreNode(name, f._alias, f._type, memAlias(f._alias), expr, off, val, false);
+ val = zsMask(val,f._type).keep();
+ Node st = new StoreNode(name, f._alias, f._type, memAlias(f._alias), expr.unkeep(), off.unkeep(), val, false);
// Arrays include control, as a proxy for a safety range check.
// Structs don't need this; they only need a NPE check which is
// done via the type system.
if( base.isAry() ) st.setDef(0,ctrl());
memAlias(f._alias, st.peephole());
- return val; // "obj.a = expr" returns the expression while updating memory
+ return val.unkeep(); // "obj.a = expr" returns the expression while updating memory
}
}
- Node load = new LoadNode(name, f._alias, f._type.glb(), memAlias(f._alias), expr, off);
+ Node load = new LoadNode(name, f._alias, f._type.glb(), memAlias(f._alias), expr.unkeep(), off);
// Arrays include control, as a proxy for a safety range check
// Structs don't need this; they only need a NPE check which is
// done via the type system.
diff --git a/chapter15/src/main/java/com/seaofnodes/simple/node/Node.java b/chapter15/src/main/java/com/seaofnodes/simple/node/Node.java
index e4b887a0..461f153d 100644
--- a/chapter15/src/main/java/com/seaofnodes/simple/node/Node.java
+++ b/chapter15/src/main/java/com/seaofnodes/simple/node/Node.java
@@ -294,7 +294,7 @@ public abstract class Node implements OutNode {
return this; // Peephole optimizations turned off
}
Node n = peepholeOpt();
- return n==null ? this : deadCodeElim(n.peephole()); // Cannot return null for no-progress
+ return n==null ? this : deadCodeElim(n.peephole().keep()).unkeep(); // Cannot return null for no-progress
}
/**
diff --git a/chapter15/src/test/java/com/seaofnodes/simple/Chapter15Test.java b/chapter15/src/test/java/com/seaofnodes/simple/Chapter15Test.java
index 3a379084..6ec7cc1a 100644
--- a/chapter15/src/test/java/com/seaofnodes/simple/Chapter15Test.java
+++ b/chapter15/src/test/java/com/seaofnodes/simple/Chapter15Test.java
@@ -14,8 +14,7 @@ public class Chapter15Test {
@Test
public void testJig() {
- Parser parser = new Parser(
-"""
+ Parser parser = new Parser("""
return 3.14;
""");
StopNode stop = parser.parse().iterate();
@@ -24,6 +23,23 @@ return 3.14;
}
@Test
+ public void testLifetime() {
+ Parser parser = new Parser("""
+u8[] b = new u8[5];
+if (arg) {
+ b[0] = b[0] + 1;
+} else {
+ b[1] = b[1] * 2;
+}
+return b[0] + b[1];
+""");
+ StopNode stop = parser.parse().iterate();
+ assertEquals("return Phi(Region69,1,0);", stop.toString());
+ assertEquals(0L, Evaluator.evaluate(stop, 0));
+ assertEquals(1L, Evaluator.evaluate(stop, 1));
+ }
+
+ @Test
public void testCyclic() {
Parser parser = new Parser(
"""