diff options
| author | Cliff Click <cliffc@acm.org> | 2025-01-09 12:08:51 -0800 |
|---|---|---|
| committer | Cliff Click <cliffc@acm.org> | 2025-01-15 15:07:30 -0800 |
| commit | 64ebe7529f9798ce036ab86ad4e09071152fe64d (patch) | |
| tree | e4b3bba870ff2f9b838ef3a00918f1ae5081449f /chapter18/src/main | |
| parent | dd67005904ab8f93bacd595290159b20d10f75a5 (diff) | |
| download | Simple-64ebe7529f9798ce036ab86ad4e09071152fe64d.tar.gz Simple-64ebe7529f9798ce036ab86ad4e09071152fe64d.zip | |
Final vars and forced constants do not lazy-phi
Better comments on why a field is final
Diffstat (limited to 'chapter18/src/main')
| -rw-r--r-- | chapter18/src/main/java/com/seaofnodes/simple/Parser.java | 12 | ||||
| -rw-r--r-- | chapter18/src/main/java/com/seaofnodes/simple/node/ScopeNode.java | 5 |
2 files changed, 13 insertions, 4 deletions
diff --git a/chapter18/src/main/java/com/seaofnodes/simple/Parser.java b/chapter18/src/main/java/com/seaofnodes/simple/Parser.java index 3f4484f5..a6185aa0 100644 --- a/chapter18/src/main/java/com/seaofnodes/simple/Parser.java +++ b/chapter18/src/main/java/com/seaofnodes/simple/Parser.java @@ -694,10 +694,16 @@ public class Parser { Node expr; if( match("=") ) { expr = parseAsgn(); - // `val` is always final + // TOP means val and val is always final xfinal = (t==Type.TOP) || - // var is always not-final, final if no Bang AND TMP since primitives are not-final by default - (t!=Type.BOTTOM && !hasBang && (t instanceof TypeMemPtr)); + // BOTTOM is var and var is always not-final + (t!=Type.BOTTOM && + // no Bang AND + !hasBang && + // not-null (expecting null to be set to not-null) + expr._type != Type.NIL && + // Pointers are final by default; int/flt are not-final by default. + (t instanceof TypeNil)); // var/val, then type comes from expression if( inferType ) { if( expr._type==Type.NIL ) diff --git a/chapter18/src/main/java/com/seaofnodes/simple/node/ScopeNode.java b/chapter18/src/main/java/com/seaofnodes/simple/node/ScopeNode.java index 5620a2d2..d0d86b79 100644 --- a/chapter18/src/main/java/com/seaofnodes/simple/node/ScopeNode.java +++ b/chapter18/src/main/java/com/seaofnodes/simple/node/ScopeNode.java @@ -209,6 +209,7 @@ public class ScopeNode extends MemMergeNode { : loop.setDef(v._idx,new PhiNode(v._name, v.lazyGLB(), loop.ctrl(), loop.in(loop.update(v,null)._idx),null).peephole()); setDef(v._idx,old); } + assert !v._final || st==null; if( st!=null ) setDef(v._idx,st); // Set new value return v; } @@ -258,7 +259,7 @@ public class ScopeNode extends MemMergeNode { for( int i=2; i<nIns(); i++ ) // For lazy phis on loops we use a sentinel // that will trigger phi creation on update - dup.addDef(loop ? this : in(i)); + dup.addDef(loop && !_vars.at(i)._final ? this : in(i)); return dup; } @@ -327,6 +328,8 @@ public class ScopeNode extends MemMergeNode { // Fill in the backedge of any inserted Phis void _endLoop( ScopeNode scope, Node back, Node exit ) { for( int i=2; i<nIns(); i++ ) { + if( _vars.at(i)._final ) continue; // Final vars did not get modified in the loop + if( _vars.at(i).type().isHighOrConst() ) continue; // Cannot lift higher than a constant, so no Phi if( back.in(i) != scope ) { PhiNode phi = (PhiNode)in(i); assert phi.region()==scope.ctrl() && phi.in(2)==null; |
