Skip to content

Sync up with finalized chapter 21 #46

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Apr 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ public class IterPeeps {

public IterPeeps( long seed ) { _work = new WorkList<>(seed); }

@SuppressWarnings("unchecked")
public <N extends Node> N add( N n ) { return (N)_work.push(n); }

public void addAll( Ary<Node> ary ) { _work.addAll(ary); }
Expand Down Expand Up @@ -127,7 +126,6 @@ private boolean progressOnList(CodeGen code) {
* Classic WorkList, with a fast add/remove, dup removal, random pull.
* The Node's nid is used to check membership in the worklist.
*/
@SuppressWarnings("unchecked")
public static class WorkList<E extends Node> {

private Node[] _es;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,28 +29,21 @@ else if( Double.isInfinite(s) ) {
public SB p( int s ) { _sb.append(s); return this; }
public SB p( long s ) { _sb.append(s); return this; }
public SB p( boolean s) { _sb.append(s); return this; }
// 1 byte, 2 hex digits, 8 bits
public SB hex1(int s) {
int digit = (s>>4) & 0xf;
_sb.append((char)((digit <= 9 ? '0' : ('A'-10))+digit));
digit = s & 0xf;
_sb.append((char)((digit <= 9 ? '0' : ('A'-10))+digit));
// 4 hex digits
public SB hex4(int s) {
assert (s>>4*4)==0; // Fits in 16 bits
for( int i=0; i<4; i++ ) {
int digit = (s>>((3-i)*4)) & 0xf;
_sb.append((char)((digit <= 9 ? '0' : ('A'-10))+digit));
}
return this;
}
// 2 bytes, 4 hex digits, 16 bits, Big Endian
public SB hex2(int s) { return hex1(s>> 8).hex1(s); }
// 4 bytes, 8 hex digits, 32 bits, Big Endian
public SB hex4(int s) { return hex2(s>>16).hex2(s); }
// 8 bytes, 16 hex digits, 64 bits, Big Endian
public SB hex8(long s) { return hex4((int)(s>>32)).hex4((int)s); }

// Fixed width field
public SB fix( int sz, String s ) {
for( int i=0; i<sz; i++ )
_sb.append( i < s.length() ? s.charAt(i) : ' ');
return this;
}
public char at(int idx ) { return _sb.charAt(idx); }

// Not spelled "p" on purpose: too easy to accidentally say "p(1.0)" and
// suddenly call the autoboxed version.
Expand Down Expand Up @@ -90,8 +83,6 @@ public boolean was_nl() {
//
public SB unchar() { return unchar(1); }
public SB unchar(int x) { _sb.setLength(_sb.length()-x); return this; }
public SB setLen(int len) { _sb.setLength(len); return this; }
public String subString(int start, int end ) { return _sb.substring(start,end); }

public SB clear() { _sb.setLength(0); return this; }
public int len() { return _sb.length(); }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ public static boolean run(int round, RegAlloc alloc) {
if( n.in(i)!=null ) {
LRG lrg2 = alloc.lrg(n.in(i));
if( lrg2 != null ) { // Anti-dep or other, no LRG
RegMask use_mask = mach.regmap(i);
if( !lrg2.machUse(mach,(short)i,use_mask.size1()).and(use_mask) )
RegMask use_mask = mach.regmap(i); // use_mask is also null for anti-dep
if( use_mask!=null && !lrg2.machUse(mach,(short)i,use_mask.size1()).and(use_mask) )
alloc.fail(lrg2); // Empty register mask, must split
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public enum Phase {
Parse, // Parse ASCII text into Sea-of-Nodes IR
Opto, // Run ideal optimizations
TypeCheck, // Last check for bad programs
LoopTree, // Build a loop tree; break infinite loops
InstSelect, // Convert to target hardware nodes
Schedule, // Global schedule (code motion) nodes
LocalSched, // Local schedule
Expand Down Expand Up @@ -52,6 +53,27 @@ public CodeGen( String src, SONTypeInteger arg, long workListSeed ) {
}


// All passes up to Phase, except ELF
public CodeGen driver( Phase phase ) { return driver(phase,null,null); }
public CodeGen driver( Phase phase, String cpu, String callingConv ) {
if( _phase==null ) parse();
if( _phase.ordinal() < phase.ordinal() ) opto();
if( _phase.ordinal() < phase.ordinal() ) typeCheck();
if( _phase.ordinal() < phase.ordinal() ) loopTree();
if( _phase.ordinal() < phase.ordinal() && cpu != null ) instSelect(cpu,callingConv);
if( _phase.ordinal() < phase.ordinal() ) GCM();
if( _phase.ordinal() < phase.ordinal() ) localSched();
if( _phase.ordinal() < phase.ordinal() ) regAlloc();
if( _phase.ordinal() < phase.ordinal() ) encode();
return this;
}

// Run all the phases through final ELF emission
public CodeGen driver( String cpu, String callingConv, String obj ) throws IOException {
return driver(Phase.Encoding,cpu,callingConv).exportELF(obj);
}


// ---------------------------
/**
* A counter, for unique node id generation. Starting with value 1, to
Expand Down Expand Up @@ -125,6 +147,7 @@ public CodeGen parse() {
assert _phase == null;
_phase = Phase.Parse;
long t0 = System.currentTimeMillis();

P.parse();
_tParse = (int)(System.currentTimeMillis() - t0);
return this;
Expand Down Expand Up @@ -180,18 +203,42 @@ public CodeGen typeCheck() {
return this;
}

// ---------------------------
// Build the loop tree; break never-exit loops
public int _tLoopTree;
public CodeGen loopTree() {
assert _phase.ordinal() <= Phase.TypeCheck.ordinal();
_phase = Phase.LoopTree;
long t0 = System.currentTimeMillis();
// Build the loop tree, fix never-exit loops
_start.buildLoopTree(_stop);
_tLoopTree = (int)(System.currentTimeMillis() - t0);
return this;
}

// ---------------------------
// Code generation CPU target
public Machine _mach;
//
// Chosen calling convention (usually either Win64 or SystemV)
public String _callingConv;
// Callee save registers
public RegMask _callerSave;

// All returns have the following inputs:
// 0 - ctrl
// 1 - memory
// 2 - varies with returning GPR,FPR
// 3 - RPC
// 4+- Caller save registers
public RegMask[] _retMasks;
// Return Program Counter
public RegMask _rpcMask;

// Convert to target hardware nodes
public int _tInsSel;
public CodeGen instSelect( String cpu, String callingConv ) { return instSelect(cpu,callingConv,PORTS); }
public CodeGen instSelect( String cpu, String callingConv, String base ) {
assert _phase.ordinal() <= Phase.TypeCheck.ordinal();
assert _phase.ordinal() == Phase.LoopTree.ordinal();
_phase = Phase.InstSelect;

_callingConv = callingConv;
Expand All @@ -203,6 +250,27 @@ public CodeGen instSelect( String cpu, String callingConv, String base ) {
try { _mach = ((Class<Machine>) Class.forName( clzFile )).getDeclaredConstructor(new Class[]{CodeGen.class}).newInstance(this); }
catch( Exception e ) { throw new RuntimeException(e); }

// Build global copies of common register masks.
long callerSave = _mach.callerSave();
long neverSave = _mach. neverSave();
int maxReg = Math.min(64,_mach.regs().length);
assert maxReg>=64 || (-1L << maxReg & callerSave)==0; // No stack slots in callerSave
_callerSave = new RegMask(callerSave);

// Build a Return RegMask array. All returns have the following inputs:
// 0 - ctrl
// 1 - memory
// 2 - varies with returning GPR,FPR
// 3 - RPC
// 4+- Caller save registers
_retMasks = new RegMask[(maxReg-_callerSave.size()-Long.bitCount( neverSave ))+4];
for( int reg=0, i=4; reg<maxReg; reg++ )
if( !_callerSave.test(reg) && ((1L<<reg)&neverSave)==0 )
_retMasks[i++] = new RegMask(reg);
_rpcMask = new RegMask(_mach.rpc());
_retMasks[3] = _rpcMask;


// Convert to machine ops
long t0 = System.currentTimeMillis();
_uid = 1; // All new machine nodes reset numbering
Expand Down Expand Up @@ -258,7 +326,7 @@ private void _instOuts( Node n, BitSet visit ) {


// ---------------------------
// Control Flow Graph in RPO order.
// Control Flow Graph in Reverse Post Order.
public int _tGCM;
public Ary<CFGNode> _cfg = new Ary<>(CFGNode.class);

Expand All @@ -269,8 +337,6 @@ public CodeGen GCM( boolean show) {
_phase = Phase.Schedule;
long t0 = System.currentTimeMillis();

// Build the loop tree, fix never-exit loops
_start.buildLoopTree(_stop);
GlobalCodeMotion.buildCFG(this);
_tGCM = (int)(System.currentTimeMillis() - t0);
if( show )
Expand Down Expand Up @@ -305,34 +371,32 @@ public CodeGen regAlloc() {
return this;
}

public String reg(Node n) {
// Human readable register name
public String reg(Node n) { return reg(n,null); }
public String reg(Node n, FunNode fun) {
if( _phase.ordinal() >= Phase.RegAlloc.ordinal() ) {
String s = _regAlloc.reg(n);
String s = _regAlloc.reg(n,fun);
if( s!=null ) return s;
}
return "N"+ n._nid;
}


// ---------------------------
// Encoding
public int _tEncode;
public boolean _JIT;
public Encoding _encoding;
public CodeGen encode(boolean jit) {
public Encoding _encoding; // Encoding object
public void preEncode() { } // overridden by alternative ports
public CodeGen encode() {
assert _phase == Phase.RegAlloc;
_phase = Phase.Encoding;
long t0 = System.currentTimeMillis();
_encoding = new Encoding(this);
_JIT = jit;
preEncode();
_encoding.encode();
_tEncode = (int)(System.currentTimeMillis() - t0);
return this;
}
public CodeGen encode() {
return encode(false);
}
// Encoded binary, no relocation info
public byte[] binary() { return _encoding.bits(); }

// ---------------------------
// Exporting to external formats
Expand Down Expand Up @@ -365,6 +429,15 @@ public CodeGen exportELF(String fname) throws IOException {
// Debugging helper
public Node f(int idx) { return _stop.find(idx); }


String printCFG() {
if( _cfg==null ) return "no CFG";
SB sb = new SB();
for( CFGNode cfg : _cfg )
IRPrinter.printLine(cfg,sb);
return sb.toString();
}

public static void print_as_hex(Encoding enc) {
for (byte b : enc._bits.toByteArray()) {
System.out.print(String.format("%02X", b));
Expand Down
Loading