summaryrefslogtreecommitdiff
path: root/chapter23/src/main/java/com/seaofnodes
diff options
context:
space:
mode:
Diffstat (limited to 'chapter23/src/main/java/com/seaofnodes')
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/Var.java2
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/codegen/Encoding.java4
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/codegen/RegAlloc.java12
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/CallNode.java2
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/ConstantNode.java2
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/MemMergeNode.java2
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/ScopeNode.java2
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/print/ASMPrinter.java13
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/print/IRPrinter.java25
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/type/TypeFunPtr.java2
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/type/TypeInteger.java4
11 files changed, 53 insertions, 17 deletions
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/Var.java b/chapter23/src/main/java/com/seaofnodes/simple/Var.java
index cf549cd6..14295395 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/Var.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/Var.java
@@ -28,6 +28,8 @@ public class Var {
_fref = fref;
_loc = loc;
}
+ // Raw declared type, without resolving a forward reference while printing.
+ public Type _type() { return _type; }
public Type type() {
if( !_type.isFRef() ) return _type;
// Update self to no longer use the forward ref type
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/codegen/Encoding.java b/chapter23/src/main/java/com/seaofnodes/simple/codegen/Encoding.java
index 1065cd9f..6a16d56b 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/codegen/Encoding.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/codegen/Encoding.java
@@ -52,12 +52,16 @@ public class Encoding {
public static class Relo {
public final Node _op;
public final Type _t; // Constant type
+ public final int _align; // Log alignment, captured for diagnostic display
+ public final int _structSize; // Capture layout during encoding, not printing
public final byte _off; // Offset from start of opcode
public final byte _elf; // ELF relocation type, e.g. 2/PC32
public int _target; // Where constant is finally placed
public int _opStart; // Opcode start
Relo( Node op, Type t, byte off, byte elf ) {
_op=op; _t=t; _off=off; _elf=elf;
+ _align = t.alignment();
+ _structSize = t instanceof TypeStruct ts ? ts.size() : 0;
}
}
public final HashMap<Node,Relo> _bigCons = new HashMap<>();
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/codegen/RegAlloc.java b/chapter23/src/main/java/com/seaofnodes/simple/codegen/RegAlloc.java
index da521082..10297a9a 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/codegen/RegAlloc.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/codegen/RegAlloc.java
@@ -124,15 +124,23 @@ public class RegAlloc {
}
+ // Diagnostic lookup: do not compress leaders or rewrite the node mapping.
+ private LRG _lrg(Node n) {
+ LRG lrg = _lrgs.get(n);
+ if( lrg != null )
+ while( lrg._leader != null ) lrg = lrg._leader;
+ return lrg;
+ }
+
public short regnum( Node n ) {
- LRG lrg = lrg(n);
+ LRG lrg = _lrg(n);
return lrg==null ? -1 : lrg._reg;
}
// Printable register number for node n
String reg( Node n ) { return reg(n,null); }
String reg( Node n, FunNode fun ) {
- LRG lrg = lrg(n);
+ LRG lrg = _lrg(n);
if( lrg==null ) return null;
// No register yet, use LRG
if( lrg._reg == -1 ) return "V"+lrg._lrg;
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/CallNode.java b/chapter23/src/main/java/com/seaofnodes/simple/node/CallNode.java
index ba08c87a..633197fa 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/CallNode.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/CallNode.java
@@ -32,7 +32,7 @@ public class CallNode extends CFGNode {
return sb.append(")");
}
public String name() {
- if( fptr()._type instanceof TypeFunPtr tfp && tfp.isConstant() ) {
+ if( fptr()._type instanceof TypeFunPtr tfp && tfp._isConstant() && tfp.notNull() ) {
FunNode fun = CodeGen.CODE.link(tfp);
if( fun !=null ) return fun._name;
if( fptr() instanceof ExternNode ex ) return ex._extern;
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/ConstantNode.java b/chapter23/src/main/java/com/seaofnodes/simple/node/ConstantNode.java
index 22bf03c4..15d98a67 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/ConstantNode.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/ConstantNode.java
@@ -36,7 +36,7 @@ public class ConstantNode extends Node {
@Override
public StringBuilder _print1(StringBuilder sb, BitSet visited) {
- if( _con instanceof TypeFunPtr tfp && tfp.isConstant() ) {
+ if( _con instanceof TypeFunPtr tfp && tfp._isConstant() && tfp.notNull() ) {
FunNode fun = CodeGen.CODE.link(tfp);
if( fun!=null && fun._name != null )
return sb.append("{ ").append(fun._name).append("}");
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/MemMergeNode.java b/chapter23/src/main/java/com/seaofnodes/simple/node/MemMergeNode.java
index 19acc5b9..20aeb454 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/MemMergeNode.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/MemMergeNode.java
@@ -38,7 +38,7 @@ public class MemMergeNode extends Node {
Node n = in(j);
while( n instanceof ScopeNode loop ) {
sb.append("Lazy_");
- n = loop.mem(j);
+ n = loop.mem().alias(j);
}
if( n==null ) sb.append("___ ");
else n._print0(sb, visited).append(" ");
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/ScopeNode.java b/chapter23/src/main/java/com/seaofnodes/simple/node/ScopeNode.java
index d8c07a92..04666956 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/ScopeNode.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/ScopeNode.java
@@ -65,7 +65,7 @@ public class ScopeNode extends MemMergeNode {
for( int i=0; i<nIns(); i++ ) {
if( j < depth() && i == _kinds.at(j)._lexSize ) { sb.append("| "); j++; }
Var v = _vars.at(i);
- sb.append(v.type());
+ sb.append(v._type());
sb.append(" ");
if( v._final ) sb.append("!");
sb.append(v._name);
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/print/ASMPrinter.java b/chapter23/src/main/java/com/seaofnodes/simple/print/ASMPrinter.java
index a9f86ce8..9ee26039 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/print/ASMPrinter.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/print/ASMPrinter.java
@@ -8,7 +8,9 @@ import com.seaofnodes.simple.type.*;
import com.seaofnodes.simple.util.Ary;
import com.seaofnodes.simple.util.SB;
import com.seaofnodes.simple.util.Utils;
-import java.util.HashSet;
+import java.util.Collections;
+import java.util.IdentityHashMap;
+import java.util.Set;
public abstract class ASMPrinter {
@@ -28,14 +30,13 @@ public abstract class ASMPrinter {
if( enc!=null && !enc._bigCons.isEmpty() && iadr < enc._bits.size() ) {
// radix sort the big constants by alignment
Ary<Relo>[] raligns = new Ary[5];
- for( Node op : enc._bigCons.keySet() ) {
- Relo relo = enc._bigCons.get(op);
- int align = relo._t.alignment();
+ for( Relo relo : enc._bigCons.values() ) {
+ int align = relo._align;
Ary<Relo> relos = raligns[align]==null ? (raligns[align]=new Ary<>( Relo.class)) : raligns[align];
relos.add(relo);
}
- HashSet<Type> targets = new HashSet<>();
+ Set<Type> targets = Collections.newSetFromMap(new IdentityHashMap<>());
sb.p("--- Constant Pool ------").nl();
// By alignment
@@ -55,7 +56,7 @@ public abstract class ASMPrinter {
}
case TypeStruct ts -> {
- int sz = ts.size();
+ int sz = relo._structSize;
int log = 1<<align;
sz = (sz + (log -1)) & -log; // Round up final padding
for( int i=0; i<sz; i++ )
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/print/IRPrinter.java b/chapter23/src/main/java/com/seaofnodes/simple/print/IRPrinter.java
index d1265bef..336cf500 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/print/IRPrinter.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/print/IRPrinter.java
@@ -221,6 +221,26 @@ public abstract class IRPrinter {
return sb.toString();
}
+ // Diagnostic block ordering from raw control edges. Do not call idepth():
+ // it fills compiler caches (and can walk lazy dominator accessors).
+ private static int _idepth(CFGNode cfg, HashMap<Integer,Integer> depths) {
+ if( cfg == null || cfg instanceof StartNode || cfg instanceof FunNode ) return cfg instanceof FunNode ? 1 : 0;
+ Integer old = depths.get(cfg._nid);
+ if( old != null ) return old;
+ depths.put(cfg._nid,0); // Break cycles in partially constructed graphs.
+ int d = 0;
+ if( cfg instanceof LoopNode ) {
+ d = _idepth((CFGNode)cfg.in(1),depths)+1;
+ } else if( cfg instanceof RegionNode || cfg instanceof StopNode ) {
+ for( Node n : cfg._inputs )
+ if( n instanceof CFGNode pred ) d = Math.max(d,_idepth(pred,depths)+1);
+ } else if( cfg.in(0) instanceof CFGNode pred ) {
+ d = _idepth(pred,depths)+1;
+ }
+ depths.put(cfg._nid,d);
+ return d;
+ }
+
// Bulk pretty printer, knowing scheduling information is available
private static String _prettyPrintScheduled( Node node, int depth ) {
// Backwards DFS walk to depth.
@@ -234,14 +254,15 @@ public abstract class IRPrinter {
ds.remove(proj._nid);
}
}
- // Print by block with least idepth
+ // Print by block with least diagnostic depth
+ HashMap<Integer,Integer> depths = new HashMap<>();
SB sb = new SB();
Ary<Node> bns = new Ary<>(Node.class);
while( !ds.isEmpty() ) {
CFGNode blk = null;
for( Node n : ns ) {
CFGNode cfg = n instanceof CFGNode cfg0 && cfg0.blockHead() ? cfg0 : n.cfg0();
- if( blk==null || cfg.idepth() < blk.idepth() )
+ if( blk==null || _idepth(cfg,depths) < _idepth(blk,depths) )
blk = cfg;
}
Integer d = ds.remove(blk._nid);
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/type/TypeFunPtr.java b/chapter23/src/main/java/com/seaofnodes/simple/type/TypeFunPtr.java
index b21dd451..88ac35c5 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/type/TypeFunPtr.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/type/TypeFunPtr.java
@@ -135,7 +135,7 @@ public class TypeFunPtr extends TypeNil {
@Override public boolean isHigh() { return _nil <= 1 || (_nil==2 && _fidxs==0); }
- @Override boolean _isConstant() { return (_nil==2 && Long.bitCount(_fidxs)==1) || (_nil==3 && _fidxs==0); }
+ @Override public boolean _isConstant() { return (_nil==2 && Long.bitCount(_fidxs)==1) || (_nil==3 && _fidxs==0); }
@Override boolean _isFinal() { return true; }
@Override boolean _isGLB(boolean mem) { return true; }
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/type/TypeInteger.java b/chapter23/src/main/java/com/seaofnodes/simple/type/TypeInteger.java
index 99f237a9..1d398e3b 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/type/TypeInteger.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/type/TypeInteger.java
@@ -89,7 +89,7 @@ public class TypeInteger extends Type {
if( this==I16 || this==U16 ) return 1; // 1<<1 == 2 bytes
if( this==I32 || this==U32 ) return 2; // 1<<2 == 4 bytes
if( this==BOT ) return 3; // 1<<3 == 8 bytes
- if( isConstant() ) { // just const here
+ if( _isConstant() ) { // just const here
if (-0xFF <= _min && _min <= 0xFF) return 0;
else if (-0xFFFF <= _min && _min <= 0xFFFF) return 1;
else if (-0xFFFFFFFFL <= _min && _min <= 0xFFFFFFFFL) return 2;
@@ -98,7 +98,7 @@ public class TypeInteger extends Type {
throw Utils.TODO();
}
- public long value() { assert isConstant(); return _min; }
+ public long value() { assert _isConstant(); return _min; }
// AND-mask of forced zeros. e.g. unsigned types will return their mask;
// u8 will return 0xFF. But also a range of 16-18 (0x10-0x12) will return