@@ -5373,7 +5373,7 @@ compiler_visit_slice(struct compiler *c, slice_ty s, expr_context_ty ctx)
5373
5373
/* End of the compiler section, beginning of the assembler section */
5374
5374
5375
5375
/* do depth-first search of basic block graph, starting with block.
5376
- a_order records the block indices in order.
5376
+ post records the block indices in post- order.
5377
5377
5378
5378
XXX must handle implicit jumps from one block to next
5379
5379
*/
@@ -5382,29 +5382,36 @@ struct assembler {
5382
5382
PyObject * a_bytecode ; /* string containing bytecode */
5383
5383
int a_offset ; /* offset into bytecode */
5384
5384
int a_nblocks ; /* number of reachable blocks */
5385
- basicblock * * a_order ; /* list of blocks in dfs order */
5385
+ basicblock * * a_postorder ; /* list of blocks in dfs postorder */
5386
5386
PyObject * a_lnotab ; /* string containing lnotab */
5387
5387
int a_lnotab_off ; /* offset into lnotab */
5388
5388
int a_lineno ; /* last lineno of emitted instruction */
5389
5389
int a_lineno_off ; /* bytecode offset of last lineno */
5390
5390
};
5391
5391
5392
5392
static void
5393
- dfs (struct compiler * c , basicblock * entry , struct assembler * a )
5393
+ dfs (struct compiler * c , basicblock * b , struct assembler * a , int end )
5394
5394
{
5395
- /* Avoid excessive recursion by following 'next' links to the
5396
- * end of the chain before handling any branches */
5397
- for (basicblock * b = entry ; b ; b = b -> b_next ) {
5395
+ int i , j ;
5396
+
5397
+ /* Get rid of recursion for normal control flow.
5398
+ Since the number of blocks is limited, unused space in a_postorder
5399
+ (from a_nblocks to end) can be used as a stack for still not ordered
5400
+ blocks. */
5401
+ for (j = end ; b && !b -> b_seen ; b = b -> b_next ) {
5398
5402
b -> b_seen = 1 ;
5399
- a -> a_order [a -> a_nblocks ++ ] = b ;
5403
+ assert (a -> a_nblocks < j );
5404
+ a -> a_postorder [-- j ] = b ;
5400
5405
}
5401
- for ( basicblock * b = entry ; b ; b = b -> b_next ) {
5402
- for ( int i = 0 ; i < b -> b_iused ; i ++ ) {
5403
- basicblock * target = b -> b_instr [ i ]. i_target ;
5404
- if ( target && ! target -> b_seen ) {
5405
- dfs ( c , target , a );
5406
- }
5406
+ while ( j < end ) {
5407
+ b = a -> a_postorder [ j ++ ];
5408
+ for ( i = 0 ; i < b -> b_iused ; i ++ ) {
5409
+ struct instr * instr = & b -> b_instr [ i ];
5410
+ if ( instr -> i_jrel || instr -> i_jabs )
5411
+ dfs ( c , instr -> i_target , a , j );
5407
5412
}
5413
+ assert (a -> a_nblocks < j );
5414
+ a -> a_postorder [a -> a_nblocks ++ ] = b ;
5408
5415
}
5409
5416
}
5410
5417
@@ -5510,9 +5517,9 @@ assemble_init(struct assembler *a, int nblocks, int firstlineno)
5510
5517
PyErr_NoMemory ();
5511
5518
return 0 ;
5512
5519
}
5513
- a -> a_order = (basicblock * * )PyObject_Malloc (
5520
+ a -> a_postorder = (basicblock * * )PyObject_Malloc (
5514
5521
sizeof (basicblock * ) * nblocks );
5515
- if (!a -> a_order ) {
5522
+ if (!a -> a_postorder ) {
5516
5523
PyErr_NoMemory ();
5517
5524
return 0 ;
5518
5525
}
@@ -5524,8 +5531,8 @@ assemble_free(struct assembler *a)
5524
5531
{
5525
5532
Py_XDECREF (a -> a_bytecode );
5526
5533
Py_XDECREF (a -> a_lnotab );
5527
- if (a -> a_order )
5528
- PyObject_Free (a -> a_order );
5534
+ if (a -> a_postorder )
5535
+ PyObject_Free (a -> a_postorder );
5529
5536
}
5530
5537
5531
5538
static int
@@ -5686,8 +5693,8 @@ assemble_jump_offsets(struct assembler *a, struct compiler *c)
5686
5693
Replace block pointer with position in bytecode. */
5687
5694
do {
5688
5695
totsize = 0 ;
5689
- for (i = 0 ; i < a -> a_nblocks ; i ++ ) {
5690
- b = a -> a_order [i ];
5696
+ for (i = a -> a_nblocks - 1 ; i >= 0 ; i -- ) {
5697
+ b = a -> a_postorder [i ];
5691
5698
bsize = blocksize (b );
5692
5699
b -> b_offset = totsize ;
5693
5700
totsize += bsize ;
@@ -5991,15 +5998,14 @@ assemble(struct compiler *c, int addNone)
5991
5998
}
5992
5999
if (!assemble_init (& a , nblocks , c -> u -> u_firstlineno ))
5993
6000
goto error ;
5994
- dfs (c , entryblock , & a );
5995
- assert (a .a_nblocks <= nblocks );
6001
+ dfs (c , entryblock , & a , nblocks );
5996
6002
5997
6003
/* Can't modify the bytecode after computing jump offsets. */
5998
6004
assemble_jump_offsets (& a , c );
5999
6005
6000
- /* Emit code in order from dfs. */
6001
- for (i = 0 ; i < a . a_nblocks ; i ++ ) {
6002
- b = a .a_order [i ];
6006
+ /* Emit code in reverse postorder from dfs. */
6007
+ for (i = a . a_nblocks - 1 ; i >= 0 ; i -- ) {
6008
+ b = a .a_postorder [i ];
6003
6009
for (j = 0 ; j < b -> b_iused ; j ++ )
6004
6010
if (!assemble_emit (& a , & b -> b_instr [j ]))
6005
6011
goto error ;
0 commit comments