summaryrefslogtreecommitdiff
path: root/chapter27/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'chapter27/src/main/java')
-rw-r--r--chapter27/src/main/java/com/seaofnodes/simple/node/ArithNode.java20
-rw-r--r--chapter27/src/main/java/com/seaofnodes/simple/node/ConvertNode.java14
2 files changed, 18 insertions, 16 deletions
diff --git a/chapter27/src/main/java/com/seaofnodes/simple/node/ArithNode.java b/chapter27/src/main/java/com/seaofnodes/simple/node/ArithNode.java
index 5f0862b2..bdd918fd 100644
--- a/chapter27/src/main/java/com/seaofnodes/simple/node/ArithNode.java
+++ b/chapter27/src/main/java/com/seaofnodes/simple/node/ArithNode.java
@@ -106,12 +106,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 )
@@ -121,12 +125,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/chapter27/src/main/java/com/seaofnodes/simple/node/ConvertNode.java b/chapter27/src/main/java/com/seaofnodes/simple/node/ConvertNode.java
index c5be0123..7e527de2 100644
--- a/chapter27/src/main/java/com/seaofnodes/simple/node/ConvertNode.java
+++ b/chapter27/src/main/java/com/seaofnodes/simple/node/ConvertNode.java
@@ -3,7 +3,6 @@ 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;
@@ -29,14 +28,15 @@ 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.
+ // The declaration bounds the result; preserve dead inputs and stronger
+ // scalar facts so SCCP can propagate constants through loop conversions.
+ // Managed pointers keep the declared type until idealize checks access:
+ // array element access must agree in both directions, so it cannot gate
+ // precision in this monotone transfer function.
@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;
}