From e481e3d215882faa82b19f29cfde5746d4e51863 Mon Sep 17 00:00:00 2001 From: Cliff Click Date: Wed, 28 Oct 2026 12:26:28 -0700 Subject: Backport Opto speedups and Minus fix --- .../java/com/seaofnodes/simple/codegen/Opto.java | 32 ++++++++++++++++++---- .../java/com/seaofnodes/simple/node/FunNode.java | 2 +- .../main/java/com/seaofnodes/simple/node/Node.java | 2 ++ 3 files changed, 29 insertions(+), 7 deletions(-) (limited to 'chapter24a/src') 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 oldTypes = new Ary<>(Type.class); + WorkList deps = new WorkList<>(); + WorkList 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 { - 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 oldTypes, WorkList 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 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() { -- cgit v1.2.3