@@ -22,6 +22,7 @@ public enum Phase {
22
22
Parse , // Parse ASCII text into Sea-of-Nodes IR
23
23
Opto , // Run ideal optimizations
24
24
TypeCheck , // Last check for bad programs
25
+ LoopTree , // Build a loop tree; break infinite loops
25
26
InstSelect , // Convert to target hardware nodes
26
27
Schedule , // Global schedule (code motion) nodes
27
28
LocalSched , // Local schedule
@@ -52,6 +53,27 @@ public CodeGen( String src, SONTypeInteger arg, long workListSeed ) {
52
53
}
53
54
54
55
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
+
55
77
// ---------------------------
56
78
/**
57
79
* A counter, for unique node id generation. Starting with value 1, to
@@ -125,6 +147,7 @@ public CodeGen parse() {
125
147
assert _phase == null ;
126
148
_phase = Phase .Parse ;
127
149
long t0 = System .currentTimeMillis ();
150
+
128
151
P .parse ();
129
152
_tParse = (int )(System .currentTimeMillis () - t0 );
130
153
return this ;
@@ -180,18 +203,42 @@ public CodeGen typeCheck() {
180
203
return this ;
181
204
}
182
205
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
+ }
183
218
184
219
// ---------------------------
185
220
// Code generation CPU target
186
221
public Machine _mach ;
187
- //
222
+ // Chosen calling convention (usually either Win64 or SystemV)
188
223
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 ;
189
236
190
237
// Convert to target hardware nodes
191
238
public int _tInsSel ;
192
239
public CodeGen instSelect ( String cpu , String callingConv ) { return instSelect (cpu ,callingConv ,PORTS ); }
193
240
public CodeGen instSelect ( String cpu , String callingConv , String base ) {
194
- assert _phase .ordinal () <= Phase .TypeCheck .ordinal ();
241
+ assert _phase .ordinal () == Phase .LoopTree .ordinal ();
195
242
_phase = Phase .InstSelect ;
196
243
197
244
_callingConv = callingConv ;
@@ -203,6 +250,27 @@ public CodeGen instSelect( String cpu, String callingConv, String base ) {
203
250
try { _mach = ((Class <Machine >) Class .forName ( clzFile )).getDeclaredConstructor (new Class []{CodeGen .class }).newInstance (this ); }
204
251
catch ( Exception e ) { throw new RuntimeException (e ); }
205
252
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
+
206
274
// Convert to machine ops
207
275
long t0 = System .currentTimeMillis ();
208
276
_uid = 1 ; // All new machine nodes reset numbering
@@ -258,7 +326,7 @@ private void _instOuts( Node n, BitSet visit ) {
258
326
259
327
260
328
// ---------------------------
261
- // Control Flow Graph in RPO order .
329
+ // Control Flow Graph in Reverse Post Order .
262
330
public int _tGCM ;
263
331
public Ary <CFGNode > _cfg = new Ary <>(CFGNode .class );
264
332
@@ -269,8 +337,6 @@ public CodeGen GCM( boolean show) {
269
337
_phase = Phase .Schedule ;
270
338
long t0 = System .currentTimeMillis ();
271
339
272
- // Build the loop tree, fix never-exit loops
273
- _start .buildLoopTree (_stop );
274
340
GlobalCodeMotion .buildCFG (this );
275
341
_tGCM = (int )(System .currentTimeMillis () - t0 );
276
342
if ( show )
@@ -305,34 +371,32 @@ public CodeGen regAlloc() {
305
371
return this ;
306
372
}
307
373
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 ) {
309
377
if ( _phase .ordinal () >= Phase .RegAlloc .ordinal () ) {
310
- String s = _regAlloc .reg (n );
378
+ String s = _regAlloc .reg (n , fun );
311
379
if ( s !=null ) return s ;
312
380
}
313
381
return "N" + n ._nid ;
314
382
}
315
383
384
+
316
385
// ---------------------------
317
386
// Encoding
318
387
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 () {
322
391
assert _phase == Phase .RegAlloc ;
323
392
_phase = Phase .Encoding ;
324
393
long t0 = System .currentTimeMillis ();
325
394
_encoding = new Encoding (this );
326
- _JIT = jit ;
395
+ preEncode () ;
327
396
_encoding .encode ();
328
397
_tEncode = (int )(System .currentTimeMillis () - t0 );
329
398
return this ;
330
399
}
331
- public CodeGen encode () {
332
- return encode (false );
333
- }
334
- // Encoded binary, no relocation info
335
- public byte [] binary () { return _encoding .bits (); }
336
400
337
401
// ---------------------------
338
402
// Exporting to external formats
@@ -365,6 +429,15 @@ public CodeGen exportELF(String fname) throws IOException {
365
429
// Debugging helper
366
430
public Node f (int idx ) { return _stop .find (idx ); }
367
431
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
+
368
441
public static void print_as_hex (Encoding enc ) {
369
442
for (byte b : enc ._bits .toByteArray ()) {
370
443
System .out .print (String .format ("%02X" , b ));
0 commit comments