Skip to content

Commit 044886d

Browse files
Sync with final ch21
1 parent 741396f commit 044886d

File tree

12 files changed

+394
-204
lines changed

12 files changed

+394
-204
lines changed

seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/codegen/BuildLRG.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ public static boolean run(int round, RegAlloc alloc) {
5555
if( n.in(i)!=null ) {
5656
LRG lrg2 = alloc.lrg(n.in(i));
5757
if( lrg2 != null ) { // Anti-dep or other, no LRG
58-
RegMask use_mask = mach.regmap(i);
59-
if( !lrg2.machUse(mach,(short)i,use_mask.size1()).and(use_mask) )
58+
RegMask use_mask = mach.regmap(i); // use_mask is also null for anti-dep
59+
if( use_mask!=null && !lrg2.machUse(mach,(short)i,use_mask.size1()).and(use_mask) )
6060
alloc.fail(lrg2); // Empty register mask, must split
6161
}
6262
}

seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/codegen/CodeGen.java

Lines changed: 89 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ public enum Phase {
2222
Parse, // Parse ASCII text into Sea-of-Nodes IR
2323
Opto, // Run ideal optimizations
2424
TypeCheck, // Last check for bad programs
25+
LoopTree, // Build a loop tree; break infinite loops
2526
InstSelect, // Convert to target hardware nodes
2627
Schedule, // Global schedule (code motion) nodes
2728
LocalSched, // Local schedule
@@ -52,6 +53,27 @@ public CodeGen( String src, SONTypeInteger arg, long workListSeed ) {
5253
}
5354

5455

56+
// All passes up to Phase, except ELF
57+
public CodeGen driver( Phase phase ) { return driver(phase,null,null); }
58+
public CodeGen driver( Phase phase, String cpu, String callingConv ) {
59+
if( _phase==null ) parse();
60+
if( _phase.ordinal() < phase.ordinal() ) opto();
61+
if( _phase.ordinal() < phase.ordinal() ) typeCheck();
62+
if( _phase.ordinal() < phase.ordinal() ) loopTree();
63+
if( _phase.ordinal() < phase.ordinal() && cpu != null ) instSelect(cpu,callingConv);
64+
if( _phase.ordinal() < phase.ordinal() ) GCM();
65+
if( _phase.ordinal() < phase.ordinal() ) localSched();
66+
if( _phase.ordinal() < phase.ordinal() ) regAlloc();
67+
if( _phase.ordinal() < phase.ordinal() ) encode();
68+
return this;
69+
}
70+
71+
// Run all the phases through final ELF emission
72+
public CodeGen driver( String cpu, String callingConv, String obj ) throws IOException {
73+
return driver(Phase.Encoding,cpu,callingConv).exportELF(obj);
74+
}
75+
76+
5577
// ---------------------------
5678
/**
5779
* A counter, for unique node id generation. Starting with value 1, to
@@ -125,6 +147,7 @@ public CodeGen parse() {
125147
assert _phase == null;
126148
_phase = Phase.Parse;
127149
long t0 = System.currentTimeMillis();
150+
128151
P.parse();
129152
_tParse = (int)(System.currentTimeMillis() - t0);
130153
return this;
@@ -180,18 +203,42 @@ public CodeGen typeCheck() {
180203
return this;
181204
}
182205

206+
// ---------------------------
207+
// Build the loop tree; break never-exit loops
208+
public int _tLoopTree;
209+
public CodeGen loopTree() {
210+
assert _phase.ordinal() <= Phase.TypeCheck.ordinal();
211+
_phase = Phase.LoopTree;
212+
long t0 = System.currentTimeMillis();
213+
// Build the loop tree, fix never-exit loops
214+
_start.buildLoopTree(_stop);
215+
_tLoopTree = (int)(System.currentTimeMillis() - t0);
216+
return this;
217+
}
183218

184219
// ---------------------------
185220
// Code generation CPU target
186221
public Machine _mach;
187-
//
222+
// Chosen calling convention (usually either Win64 or SystemV)
188223
public String _callingConv;
224+
// Callee save registers
225+
public RegMask _callerSave;
226+
227+
// All returns have the following inputs:
228+
// 0 - ctrl
229+
// 1 - memory
230+
// 2 - varies with returning GPR,FPR
231+
// 3 - RPC
232+
// 4+- Caller save registers
233+
public RegMask[] _retMasks;
234+
// Return Program Counter
235+
public RegMask _rpcMask;
189236

190237
// Convert to target hardware nodes
191238
public int _tInsSel;
192239
public CodeGen instSelect( String cpu, String callingConv ) { return instSelect(cpu,callingConv,PORTS); }
193240
public CodeGen instSelect( String cpu, String callingConv, String base ) {
194-
assert _phase.ordinal() <= Phase.TypeCheck.ordinal();
241+
assert _phase.ordinal() == Phase.LoopTree.ordinal();
195242
_phase = Phase.InstSelect;
196243

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

253+
// Build global copies of common register masks.
254+
long callerSave = _mach.callerSave();
255+
long neverSave = _mach. neverSave();
256+
int maxReg = Math.min(64,_mach.regs().length);
257+
assert maxReg>=64 || (-1L << maxReg & callerSave)==0; // No stack slots in callerSave
258+
_callerSave = new RegMask(callerSave);
259+
260+
// Build a Return RegMask array. All returns have the following inputs:
261+
// 0 - ctrl
262+
// 1 - memory
263+
// 2 - varies with returning GPR,FPR
264+
// 3 - RPC
265+
// 4+- Caller save registers
266+
_retMasks = new RegMask[(maxReg-_callerSave.size()-Long.bitCount( neverSave ))+4];
267+
for( int reg=0, i=4; reg<maxReg; reg++ )
268+
if( !_callerSave.test(reg) && ((1L<<reg)&neverSave)==0 )
269+
_retMasks[i++] = new RegMask(reg);
270+
_rpcMask = new RegMask(_mach.rpc());
271+
_retMasks[3] = _rpcMask;
272+
273+
206274
// Convert to machine ops
207275
long t0 = System.currentTimeMillis();
208276
_uid = 1; // All new machine nodes reset numbering
@@ -258,7 +326,7 @@ private void _instOuts( Node n, BitSet visit ) {
258326

259327

260328
// ---------------------------
261-
// Control Flow Graph in RPO order.
329+
// Control Flow Graph in Reverse Post Order.
262330
public int _tGCM;
263331
public Ary<CFGNode> _cfg = new Ary<>(CFGNode.class);
264332

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

272-
// Build the loop tree, fix never-exit loops
273-
_start.buildLoopTree(_stop);
274340
GlobalCodeMotion.buildCFG(this);
275341
_tGCM = (int)(System.currentTimeMillis() - t0);
276342
if( show )
@@ -305,34 +371,32 @@ public CodeGen regAlloc() {
305371
return this;
306372
}
307373

308-
public String reg(Node n) {
374+
// Human readable register name
375+
public String reg(Node n) { return reg(n,null); }
376+
public String reg(Node n, FunNode fun) {
309377
if( _phase.ordinal() >= Phase.RegAlloc.ordinal() ) {
310-
String s = _regAlloc.reg(n);
378+
String s = _regAlloc.reg(n,fun);
311379
if( s!=null ) return s;
312380
}
313381
return "N"+ n._nid;
314382
}
315383

384+
316385
// ---------------------------
317386
// Encoding
318387
public int _tEncode;
319-
public boolean _JIT;
320-
public Encoding _encoding;
321-
public CodeGen encode(boolean jit) {
388+
public Encoding _encoding; // Encoding object
389+
public void preEncode() { } // overridden by alternative ports
390+
public CodeGen encode() {
322391
assert _phase == Phase.RegAlloc;
323392
_phase = Phase.Encoding;
324393
long t0 = System.currentTimeMillis();
325394
_encoding = new Encoding(this);
326-
_JIT = jit;
395+
preEncode();
327396
_encoding.encode();
328397
_tEncode = (int)(System.currentTimeMillis() - t0);
329398
return this;
330399
}
331-
public CodeGen encode() {
332-
return encode(false);
333-
}
334-
// Encoded binary, no relocation info
335-
public byte[] binary() { return _encoding.bits(); }
336400

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

432+
433+
String printCFG() {
434+
if( _cfg==null ) return "no CFG";
435+
SB sb = new SB();
436+
for( CFGNode cfg : _cfg )
437+
IRPrinter.printLine(cfg,sb);
438+
return sb.toString();
439+
}
440+
368441
public static void print_as_hex(Encoding enc) {
369442
for (byte b : enc._bits.toByteArray()) {
370443
System.out.print(String.format("%02X", b));

0 commit comments

Comments
 (0)