summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2024-11-13 16:12:16 -0800
committerCliff Click <cliffc@acm.org>2024-11-23 09:03:20 -0800
commit3652f49f679de25a2544225d6a3600a63b693ba0 (patch)
tree9856f1de1d2a24789242bc21fff6a6b350c2a76b
parent01afee4d48b05dee7686090716e23d467fae9838 (diff)
downloadSimple-3652f49f679de25a2544225d6a3600a63b693ba0.tar.gz
Simple-3652f49f679de25a2544225d6a3600a63b693ba0.zip
Bug fix loop depth on infinite split-tail loops
-rw-r--r--chapter17/README.md63
-rw-r--r--chapter17/src/main/java/com/seaofnodes/simple/node/IfNode.java3
-rw-r--r--chapter17/src/main/java/com/seaofnodes/simple/node/LoopNode.java16
3 files changed, 9 insertions, 73 deletions
diff --git a/chapter17/README.md b/chapter17/README.md
index bf998ab8..1bac940b 100644
--- a/chapter17/README.md
+++ b/chapter17/README.md
@@ -125,7 +125,6 @@ return i; // ERROR: Undefined name 'i'
-finalize final
oper-assign +=, -=
TODO
switch
@@ -134,65 +133,3 @@ switch
-# Chapter 18: Functions
-
-Some thinking on function syntax:
-
-Function Types:
-```
-{ argtype, argtype, ... -> rettype }
-```
-
-Leading `{` character denotes the start of a function or function type.
-
-Functions are normal variables and assigned the same way:
-
-```functiontype var = function-typed-expr```
-
-Functions themselves using the same syntax with as types, but filled in:
-
-```
-{ int x, int y ->
- sqrt(x*x+y*y);
-}
-```
-
-Used in a declaration statement:
-```
-// TYPE VAR = EXPR
-{flt,flt->flt} dist = { flt x, flt y ->
- sqrt(x*x+y*y);
-}
-```
-
-Because it gets clunky to write the function type, and because it can be
-directly inferred from forwards-flow analysis (not even HM) which we're already
-doing at parse-time, we add a new variable declaration syntax: "var" - for
-auto-inferring variable types. Not allowed in function headers.
-```
-var dist = { flt x, flt y -> sqrt(x*x*,y*y); }
-```
-
-`var` can be used for normal variables as well:
-
-```
-// Newtons approximation to the square root
-var sqrt = { flt x ->
- var guess = x*x/2;
- while( 1 ) {
- var next = (x/guess + guess)/2;
- if( next == guess ) break;
- guess = next;
- }
- guess;
-}
-```
-
-When inferring pointer types, it will use the `glb` of the initial expression
-type, which may not be what you want:
-
-```
-struct LLI { LLI? next; int i; };
-var head = LLI(); // Want this declared not-null, but GLB will allow null
-head = null; // Allowed
-``` \ No newline at end of file
diff --git a/chapter17/src/main/java/com/seaofnodes/simple/node/IfNode.java b/chapter17/src/main/java/com/seaofnodes/simple/node/IfNode.java
index 41de4c82..2f3798d7 100644
--- a/chapter17/src/main/java/com/seaofnodes/simple/node/IfNode.java
+++ b/chapter17/src/main/java/com/seaofnodes/simple/node/IfNode.java
@@ -43,6 +43,9 @@ public class IfNode extends CFGNode implements MultiNode {
// Else true branch is reachable
if( t.isConstant() )
return t.makeInit()==t ? TypeTuple.IF_FALSE : TypeTuple.IF_TRUE;
+ // Integers allow non-zero ranges: "1-65535"
+ if( t.makeZero().meet(t) != t )
+ return TypeTuple.IF_TRUE;
return TypeTuple.IF_BOTH;
}
diff --git a/chapter17/src/main/java/com/seaofnodes/simple/node/LoopNode.java b/chapter17/src/main/java/com/seaofnodes/simple/node/LoopNode.java
index 27134420..e5f34833 100644
--- a/chapter17/src/main/java/com/seaofnodes/simple/node/LoopNode.java
+++ b/chapter17/src/main/java/com/seaofnodes/simple/node/LoopNode.java
@@ -39,15 +39,12 @@ public class LoopNode extends RegionNode {
for( CFGNode idom = back(); idom!=this; idom = idom.idom() ) {
// Walk idom in loop, setting depth
idom._loopDepth = _loopDepth;
- // Loop exit hits the CProj before the If, instead of jumping from
- // Region directly to If.
- if( idom instanceof CProjNode proj ) {
- assert proj.in(0) instanceof IfNode; // Loop exit test
- // Find the loop exit CProj, and set loop_depth
- for( Node use : proj.in(0)._outputs )
- if( use instanceof CProjNode proj2 && proj2 != idom )
- proj2._loopDepth = _loopDepth-1;
- }
+ // Mark backedge loop depth. The loop exit hits the CProj before the
+ // If, instead of jumping from Region directly to If. The other
+ // arm is either a loop exit OR if this is a split tail the other
+ // arm leads to a inner loop.
+ if( idom instanceof CProjNode cproj )
+ break;
}
return _loopDepth;
}
@@ -62,7 +59,6 @@ public class LoopNode extends RegionNode {
while( x != this ) {
if( x instanceof CProjNode exit && exit.in(0) instanceof IfNode iff ) {
CFGNode other = iff.cproj(1-exit._idx);
- //if( !(other.out(0) instanceof LoopNode loop) || loop.entry()==exit )
if( other.loopDepth() < loopDepth() )
return; // Found an exit, not an infinite loop
}