diff options
| author | Cliff Click <cliffc@acm.org> | 2026-10-28 12:26:28 -0700 |
|---|---|---|
| committer | Cliff Click <cliffc@acm.org> | 2026-10-28 12:26:28 -0700 |
| commit | e481e3d215882faa82b19f29cfde5746d4e51863 (patch) | |
| tree | d6035c13e4ee471b67d7dd4732a62bc04020fbd1 /chapter24a/src/main/java/com/seaofnodes | |
| parent | 07a87b4461015dd81f1d40cef1e2378882c86479 (diff) | |
| download | Simple-e481e3d215882faa82b19f29cfde5746d4e51863.tar.gz Simple-e481e3d215882faa82b19f29cfde5746d4e51863.zip | |
Backport Opto speedups and Minus fix
Diffstat (limited to 'chapter24a/src/main/java/com/seaofnodes')
3 files changed, 29 insertions, 7 deletions
diff --git a/chapter24a/src/main/java/com/seaofnodes/simple/codegen/Opto.java b/chapter24a/src/main/java/com/seaofnodes/simple/codegen/Opto.java index e6334414..f67babcc 100644 --- a/chapter24a/src/main/java/com/seaofnodes/simple/codegen/Opto.java +++ b/chapter24a/src/main/java/com/seaofnodes/simple/codegen/Opto.java @@ -1,6 +1,7 @@ package com.seaofnodes.simple.codegen; import com.seaofnodes.simple.node.*; +import com.seaofnodes.simple.IterPeeps.WorkList; import com.seaofnodes.simple.type.*; import com.seaofnodes.simple.util.Ary; @@ -9,6 +10,8 @@ abstract public class Opto { public static void opto(CodeGen code) { Ary<Type> oldTypes = new Ary<>(Type.class); + WorkList<Node> deps = new WorkList<>(); + WorkList<Node> changes = new WorkList<>(); code._start.walk(n -> { oldTypes.setX(n._nid,n._type); if( n instanceof CallEndNode cend ) cend.freezeResult(); @@ -26,20 +29,37 @@ abstract public class Opto { while( (n = code._iter._work.pop()) != null ) { if( n.isDead() ) continue; Type old = n._type, next = n.compute(); + if( next!=oldTypes.atX(n._nid) || n.isUnlocked() ) changes.push(n); if( old == next ) continue; assert old.isa(next); // Optimistic types only fall. assert next.isa(oldTypes.at(n._nid)) : n.getClass().getSimpleName()+"#"+n._nid+" old="+oldTypes.at(n._nid)+" next="+next; n._type = next; code.addAll(n._outputs); + // SCCP consumes these without running peepholes. Save them for + // the following Iter pass before moving clears the dependency list. + for( int i=0; i<n.nDeps(); i++ ) deps.push(n.dep(i)); n.moveDepsToWorklist(code._iter); assert check(code); } - code._start.walk(x -> { - assert x.compute() == x._type; - assert x._type.isa(oldTypes.at(x._nid)); - code.add(x); // Run the rewrites enabled by the new types. - return null; - }); + Node dep; + while( (dep=deps.pop())!=null ) code.add(dep); + moveChangesToWorklist(code, oldTypes, changes); + } + + private static void moveChangesToWorklist(CodeGen code, Ary<Type> oldTypes, WorkList<Node> changes) { + Node n; + while( (n=changes.pop())!=null ) { + if( n.isDead() ) continue; + assert n.compute() == n._type; // Hit the fixed point. + Type old = oldTypes.atX(n._nid); + assert old==null || n._type.isa(old); + if( n._type!=old || n.isUnlocked() ) { + code.add(n); + code.addAll(n._inputs); + code.addAll(n._outputs); + n.moveDepsToWorklist(); + } + } } private static boolean check(CodeGen code) { diff --git a/chapter24a/src/main/java/com/seaofnodes/simple/node/FunNode.java b/chapter24a/src/main/java/com/seaofnodes/simple/node/FunNode.java index 70e1c200..6a4b6d9e 100644 --- a/chapter24a/src/main/java/com/seaofnodes/simple/node/FunNode.java +++ b/chapter24a/src/main/java/com/seaofnodes/simple/node/FunNode.java @@ -114,7 +114,7 @@ public class FunNode extends RegionNode { } // Upgrade inferred or user-written return type to actual - if( _ret!=null && _ret._type instanceof TypeTuple tt && tt.ret() != _sig.ret() ) { + if( _ret!=null && addDep(_ret)._type instanceof TypeTuple tt && tt.ret() != _sig.ret() ) { setSig(_sig.makeFrom(tt.ret())); return this; } diff --git a/chapter24a/src/main/java/com/seaofnodes/simple/node/Node.java b/chapter24a/src/main/java/com/seaofnodes/simple/node/Node.java index 414530b4..d42b70ed 100644 --- a/chapter24a/src/main/java/com/seaofnodes/simple/node/Node.java +++ b/chapter24a/src/main/java/com/seaofnodes/simple/node/Node.java @@ -557,6 +557,8 @@ public abstract class Node extends BaseNode<Node> implements Cloneable { // probed to see if it can be inserted. His edges are "locked", because // hacking his edges will change his hash. int _hash; + // Edge and mode edits remove the node from GVN, even if its type is unchanged. + public boolean isUnlocked() { return _hash==0; } // If the _hash is set, then the Node is in the GVN table; remove it. void unlock() { |
