diff options
| author | Cliff Click <cliffc@acm.org> | 2024-11-13 16:12:16 -0800 |
|---|---|---|
| committer | Cliff Click <cliffc@acm.org> | 2024-11-23 09:03:20 -0800 |
| commit | 3652f49f679de25a2544225d6a3600a63b693ba0 (patch) | |
| tree | 9856f1de1d2a24789242bc21fff6a6b350c2a76b /chapter17 | |
| parent | 01afee4d48b05dee7686090716e23d467fae9838 (diff) | |
| download | Simple-3652f49f679de25a2544225d6a3600a63b693ba0.tar.gz Simple-3652f49f679de25a2544225d6a3600a63b693ba0.zip | |
Bug fix loop depth on infinite split-tail loops
Diffstat (limited to 'chapter17')
| -rw-r--r-- | chapter17/README.md | 63 | ||||
| -rw-r--r-- | chapter17/src/main/java/com/seaofnodes/simple/node/IfNode.java | 3 | ||||
| -rw-r--r-- | chapter17/src/main/java/com/seaofnodes/simple/node/LoopNode.java | 16 |
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 } |
