From cdc1ac01c3935587f4c11140d8afb22bec0e7581 Mon Sep 17 00:00:00 2001 From: Cliff Click Date: Sun, 13 Sep 2026 15:48:17 -0700 Subject: Resolve numeric needs more Opto Missing Arith mode picks high or low according to pre/post Opto FunPtr improves sig return based on Opto return type. Minus with missing mode is optimistic, same as Arith --- .../src/main/java/com/seaofnodes/simple/IterPeeps.java | 2 +- chapter25/src/main/java/com/seaofnodes/simple/Parser.java | 2 +- .../src/main/java/com/seaofnodes/simple/codegen/Opto.java | 14 +++++++++----- .../main/java/com/seaofnodes/simple/node/ArithNode.java | 4 ++-- .../main/java/com/seaofnodes/simple/node/CallEndNode.java | 1 - .../main/java/com/seaofnodes/simple/node/FunPtrNode.java | 7 ++++++- .../src/main/java/com/seaofnodes/simple/node/LoadNode.java | 4 +++- .../main/java/com/seaofnodes/simple/node/MinusNode.java | 9 +++++++-- 8 files changed, 29 insertions(+), 14 deletions(-) (limited to 'chapter25/src/main/java') diff --git a/chapter25/src/main/java/com/seaofnodes/simple/IterPeeps.java b/chapter25/src/main/java/com/seaofnodes/simple/IterPeeps.java index d4b84828..be8cc9ed 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/IterPeeps.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/IterPeeps.java @@ -335,7 +335,7 @@ public class IterPeeps { return x; } - //boolean isEmpty() { return _len==0; } + public boolean isEmpty() { return _len==0; } //Node[] asAry() { return Arrays.copyOf(_es,_len); } //public void clear() { // _len = 0; diff --git a/chapter25/src/main/java/com/seaofnodes/simple/Parser.java b/chapter25/src/main/java/com/seaofnodes/simple/Parser.java index a9b7c84b..2b6e5ddf 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/Parser.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/Parser.java @@ -2156,7 +2156,7 @@ public class Parser { // Self method call? Self is a TMP-not-CLZ, then assume and pass self. if( match("(") ) { expr = parsePostfix(require(functionCall(expr,self),")")); - } else + } else if( expr != self ) self.isKill(); // Not a method call, no need for self return parsePostfix(expr); } diff --git a/chapter25/src/main/java/com/seaofnodes/simple/codegen/Opto.java b/chapter25/src/main/java/com/seaofnodes/simple/codegen/Opto.java index 6e00d02c..7c14965c 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/codegen/Opto.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/codegen/Opto.java @@ -34,15 +34,18 @@ abstract public class Opto { // OPTIMISTIC INTERPROCEDURAL SCCP sccp(code, oldTypes); - // After SCCP add everything changed to the worklist and see if - // peepholes can make more progress. - moveChangesToWorklist(code, oldTypes); - // SCCP can leave a recursive numeric component at BOTTOM with no // arithmetic mode selected. Resolve the whole component from all // available int/float evidence before IterPeeps consumes the types. resolveNumericModes(code); + if( !code._iter._work.isEmpty() ) + sccp(code, oldTypes); + + // After SCCP add everything changed to the worklist and see if + // peepholes can make more progress. + moveChangesToWorklist(code, oldTypes); + // Progress with improved types. E.g. since we have a full Call Graph // here, we might do better inlining. code._iter.iterate(code); @@ -311,8 +314,9 @@ abstract public class Opto { mode = 1; if( mode != 0 ) { // If both evidence, FP wins - modeNode.setMode((byte)((mode&2)==2 ? 2 : 1)).init(); + modeNode.setMode((byte)((mode&2)==2 ? 2 : 1)); code.add(n); + code.addAll(n.outs()); } } return null; diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/ArithNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/ArithNode.java index 995b4743..ffba1f16 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/ArithNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/ArithNode.java @@ -94,7 +94,7 @@ public abstract class ArithNode extends Node implements ModeNode { // Arithmetic subclasses which have a floating-point interpretation override. boolean allowFloat() { return false; } - // Generic airthmetic op math: high returns high; low returns low; 2 + // Generic arithmetic op math: high returns high; low returns low; 2 // constants fold; only 2 non-constants call specialized math. @Override public final Type compute() { @@ -107,7 +107,7 @@ public abstract class ArithNode extends Node implements ModeNode { TypeFloat.F64.dual(); byte mode = _mode==0 ? mode(t1,t2) : _mode; if( mode==0 ) - return Type.BOTTOM; + return CodeGen.CODE._phase.ordinal() < CodeGen.Phase.Opto.ordinal() ? Type.BOTTOM : Type.TOP; if( mode==1 ) { if( t1 instanceof TypeInteger x && t2 instanceof TypeInteger y ) diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/CallEndNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/CallEndNode.java index c9029049..abf80288 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/CallEndNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/CallEndNode.java @@ -57,7 +57,6 @@ public class CallEndNode extends CFGNode implements MultiNode { public CallNode call() { return (CallNode)in(0); } boolean folding() { return _folding; } - public byte inline() { return _inline; } @Override public CFGNode idom(Node dep) { // Folding the idom is the one inlining Return diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/FunPtrNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/FunPtrNode.java index 33757640..ce53b073 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/FunPtrNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/FunPtrNode.java @@ -45,7 +45,12 @@ public class FunPtrNode extends TypeNode { @Override public boolean isPinned() { return true; } @Override public Type compute() { ReturnNode ret = ret(); - return ret == null ? _con : ret.fun().sig(); + if( ret == null ) return _con; + if( !(ret._type instanceof TypeTuple tt) ) return ret._type.oob(); + TypeFunPtr tfp = ret.fun().sig(); + // Both the sig and the return value must be true, so JOIN both + Type tret = tfp._ret.join(tt.ret()); + return tfp.makeFrom(tret); } @Override public Node idealize() { ReturnNode ret = ret(); diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/LoadNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/LoadNode.java index d625b898..b27da676 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/LoadNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/LoadNode.java @@ -268,7 +268,9 @@ public class LoadNode extends MemOpNode { private boolean profit(PhiNode memphi, int idx) { Node px = memphi.in(idx); if( px==null ) return false; - assert !(px._type instanceof TypeMem mem && mem._t.isHighOrConst() ); + // Memory is collapsing, no bother + if( px._type instanceof TypeMem mem && mem._t.isHighOrConst() ) + return false; if( px instanceof StoreNode st1 && ptr()==addDep(st1.nnptr() ) && off()==st1.off() && addDep(st1.val())._type.isa(_type) ) // To avoid cyclic pushing a Load up then down, getting here means // the load *must* match against the Store diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/MinusNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/MinusNode.java index 642fc2b2..4df68a3b 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/MinusNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/MinusNode.java @@ -43,9 +43,14 @@ public class MinusNode extends Node implements ModeNode { return _mode==0 ? Type.TOP : _mode==1 ? TypeInteger.TOP : t instanceof TypeFloat ? t : TypeFloat.F64.dual(); - if( _mode==0 ) + byte mode = _mode; + if( mode==0 ) { + if( t instanceof TypeFloat ) mode=2; + if( t instanceof TypeInteger ) mode=1; + } + if( mode==0 ) return Type.BOTTOM; - if( _mode==1 ) { + if( mode==1 ) { if( t instanceof TypeInteger i0 && i0._min != Long.MIN_VALUE && i0._max != Long.MIN_VALUE ) return TypeInteger.make(-i0._max,-i0._min,i0._widen); -- cgit v1.2.3