diff options
Diffstat (limited to 'chapter28b/src/main/java/com/seaofnodes')
| -rw-r--r-- | chapter28b/src/main/java/com/seaofnodes/simple/node/ArithNode.java | 20 | ||||
| -rw-r--r-- | chapter28b/src/main/java/com/seaofnodes/simple/node/ConvertNode.java | 21 |
2 files changed, 23 insertions, 18 deletions
diff --git a/chapter28b/src/main/java/com/seaofnodes/simple/node/ArithNode.java b/chapter28b/src/main/java/com/seaofnodes/simple/node/ArithNode.java index 92ebd587..e2a88944 100644 --- a/chapter28b/src/main/java/com/seaofnodes/simple/node/ArithNode.java +++ b/chapter28b/src/main/java/com/seaofnodes/simple/node/ArithNode.java @@ -111,12 +111,16 @@ public abstract class ArithNode extends Node implements ModeNode { @Override public final Type compute() { Type t1 = in(1)._type, t2 = in(2)._type; + // Constant array payloads lie below their element ranges in the lattice. + if( t1 instanceof TypeConAry ary ) t1 = ary.elem(); + if( t2 instanceof TypeConAry ary ) t2 = ary.elem(); if( t1==null || t2==null ) return Type.TOP; if( t1.isHigh() || t2.isHigh() ) return Type.TOP; - if( t1==Type.BOTTOM || t2==Type.BOTTOM ) return Type.BOTTOM; + // Without numeric inputs, stay below both possible result families. + // Pointer modes belong to comparisons, not arithmetic. + if( !(t1 instanceof TypeInteger || t1 instanceof TypeFloat) || + !(t2 instanceof TypeInteger || t2 instanceof TypeFloat) ) return Type.BOTTOM; byte mode = _mode==0 ? mode(t1,t2) : _mode; - if( mode==0 ) - 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 ) @@ -126,12 +130,10 @@ public abstract class ArithNode extends Node implements ModeNode { return TypeInteger.BOT; } // FP handling - if( t1 instanceof TypeFloat f1 && - t2 instanceof TypeFloat f2 ) { - if( f1.isConstant() && f2.isConstant() ) - return TypeFloat.constant(doOp(f1.value(),f2.value())); - return t1.meet(t2); - } + if( t1 instanceof TypeFloat f1 && t2 instanceof TypeFloat f2 && + f1.isConstant() && f2.isConstant() ) + return TypeFloat.constant(doOp(f1.value(),f2.value())); + // Two f32 inputs can still produce a result needing f64 precision. return TypeFloat.F64; } diff --git a/chapter28b/src/main/java/com/seaofnodes/simple/node/ConvertNode.java b/chapter28b/src/main/java/com/seaofnodes/simple/node/ConvertNode.java index cdc890a7..7f5398ef 100644 --- a/chapter28b/src/main/java/com/seaofnodes/simple/node/ConvertNode.java +++ b/chapter28b/src/main/java/com/seaofnodes/simple/node/ConvertNode.java @@ -3,13 +3,17 @@ package com.seaofnodes.simple.node; import com.seaofnodes.print.ExprPrinter; import com.seaofnodes.simple.Parser; -import com.seaofnodes.simple.codegen.CodeGen; import com.seaofnodes.simple.type.*; import java.util.HashMap; -// Convert a value to an authoritative destination type. The destination is -// known structurally from a declaration; the source family might sharpen later. +// Convert the incoming value; actual conversion depends on the _dst type. +// Convert ints to floats, ptrs to ints, nullable to not-null, etc. Once the +// input type is known precisely enough, the idealize() call triggers and +// replaces the Convert with a concrete conversion (e.g. toFloatNode). +// +// Convert has no runtime dynamic behavior; it must *always* get replaced with +// some concrete behavior (or its an error). public class ConvertNode extends Node { private Type _dst; @@ -29,14 +33,13 @@ public class ConvertNode extends Node { return p.p(label()).open().n(val()).close(); } - // The declaration fixes the result family during pessimistic parsing. - // From SCCP onward, preserve dead inputs and stronger facts in that family. + + // Not much to do here, if the input type is not sharp enough to fold into + // the proper conversion, its not sharp enough to do much else. @Override public Type compute() { Type src = val()._type; - if( CodeGen.CODE._phase.ordinal() >= CodeGen.Phase.Opto.ordinal() ) { - if( src.isHigh() ) return Type.TOP; - if( (src.isa(_dst) && src.accessISA(_dst)) ) return src; - } + if( src.isHigh() ) return Type.TOP; + if( !(_dst instanceof TypeMemPtr) && src.isa(_dst) ) return src; return _dst; } |
