@@ -1432,28 +1432,32 @@ compiler_addop_i(struct compiler *c, int opcode, Py_ssize_t oparg)
1432
1432
return 1 ;
1433
1433
}
1434
1434
1435
- static int
1436
- compiler_addop_j (struct compiler * c , int opcode , basicblock * b )
1435
+ static int add_jump_to_block (basicblock * b , int opcode , int lineno , basicblock * target )
1437
1436
{
1438
- struct instr * i ;
1439
- int off ;
1440
-
1441
- if (c -> c_do_not_emit_bytecode ) {
1442
- return 1 ;
1443
- }
1444
-
1445
1437
assert (HAS_ARG (opcode ));
1446
1438
assert (b != NULL );
1447
- off = compiler_next_instr (c -> u -> u_curblock );
1448
- if (off < 0 )
1439
+ assert (target != NULL );
1440
+
1441
+ int off = compiler_next_instr (b );
1442
+ struct instr * i = & b -> b_instr [off ];
1443
+ if (off < 0 ) {
1449
1444
return 0 ;
1450
- i = & c -> u -> u_curblock -> b_instr [ off ];
1445
+ }
1451
1446
i -> i_opcode = opcode ;
1452
- i -> i_target = b ;
1453
- i -> i_lineno = c -> u -> u_lineno ;
1447
+ i -> i_target = target ;
1448
+ i -> i_lineno = lineno ;
1454
1449
return 1 ;
1455
1450
}
1456
1451
1452
+ static int
1453
+ compiler_addop_j (struct compiler * c , int opcode , basicblock * b )
1454
+ {
1455
+ if (c -> c_do_not_emit_bytecode ) {
1456
+ return 1 ;
1457
+ }
1458
+ return add_jump_to_block (c -> u -> u_curblock , opcode , c -> u -> u_lineno , b );
1459
+ }
1460
+
1457
1461
/* NEXT_BLOCK() creates an implicit jump from the current block
1458
1462
to the new block.
1459
1463
@@ -6067,6 +6071,27 @@ fold_tuple_on_constants(struct instr *inst,
6067
6071
return 0 ;
6068
6072
}
6069
6073
6074
+
6075
+ static int
6076
+ eliminate_jump_to_jump (basicblock * bb , int opcode ) {
6077
+ assert (bb -> b_iused > 0 );
6078
+ struct instr * inst = & bb -> b_instr [bb -> b_iused - 1 ];
6079
+ assert (is_jump (inst ));
6080
+ assert (inst -> i_target -> b_iused > 0 );
6081
+ struct instr * target = & inst -> i_target -> b_instr [0 ];
6082
+ if (inst -> i_target == target -> i_target ) {
6083
+ /* Nothing to do */
6084
+ return 0 ;
6085
+ }
6086
+ int lineno = target -> i_lineno ;
6087
+ if (add_jump_to_block (bb , opcode , lineno , target -> i_target ) == 0 ) {
6088
+ return -1 ;
6089
+ }
6090
+ assert (bb -> b_iused >= 2 );
6091
+ bb -> b_instr [bb -> b_iused - 2 ].i_opcode = NOP ;
6092
+ return 0 ;
6093
+ }
6094
+
6070
6095
/* Maximum size of basic block that should be copied in optimizer */
6071
6096
#define MAX_COPY_SIZE 4
6072
6097
@@ -6183,45 +6208,55 @@ optimize_basic_block(basicblock *bb, PyObject *consts)
6183
6208
case JUMP_IF_FALSE_OR_POP :
6184
6209
switch (target -> i_opcode ) {
6185
6210
case POP_JUMP_IF_FALSE :
6186
- * inst = * target ;
6187
- -- i ;
6211
+ if (inst -> i_lineno == target -> i_lineno ) {
6212
+ * inst = * target ;
6213
+ i -- ;
6214
+ }
6188
6215
break ;
6189
6216
case JUMP_ABSOLUTE :
6190
6217
case JUMP_FORWARD :
6191
6218
case JUMP_IF_FALSE_OR_POP :
6192
- if (inst -> i_target != target -> i_target ) {
6219
+ if (inst -> i_lineno == target -> i_lineno &&
6220
+ inst -> i_target != target -> i_target ) {
6193
6221
inst -> i_target = target -> i_target ;
6194
- -- i ;
6222
+ i -- ;
6195
6223
}
6196
6224
break ;
6197
6225
case JUMP_IF_TRUE_OR_POP :
6198
6226
assert (inst -> i_target -> b_iused == 1 );
6199
- inst -> i_opcode = POP_JUMP_IF_FALSE ;
6200
- inst -> i_target = inst -> i_target -> b_next ;
6201
- -- i ;
6227
+ if (inst -> i_lineno == target -> i_lineno ) {
6228
+ inst -> i_opcode = POP_JUMP_IF_FALSE ;
6229
+ inst -> i_target = inst -> i_target -> b_next ;
6230
+ -- i ;
6231
+ }
6202
6232
break ;
6203
6233
}
6204
6234
break ;
6205
6235
6206
6236
case JUMP_IF_TRUE_OR_POP :
6207
6237
switch (target -> i_opcode ) {
6208
6238
case POP_JUMP_IF_TRUE :
6209
- * inst = * target ;
6210
- -- i ;
6239
+ if (inst -> i_lineno == target -> i_lineno ) {
6240
+ * inst = * target ;
6241
+ i -- ;
6242
+ }
6211
6243
break ;
6212
6244
case JUMP_ABSOLUTE :
6213
6245
case JUMP_FORWARD :
6214
6246
case JUMP_IF_TRUE_OR_POP :
6215
- if (inst -> i_target != target -> i_target ) {
6247
+ if (inst -> i_lineno == target -> i_lineno &&
6248
+ inst -> i_target != target -> i_target ) {
6216
6249
inst -> i_target = target -> i_target ;
6217
- -- i ;
6250
+ i -- ;
6218
6251
}
6219
6252
break ;
6220
6253
case JUMP_IF_FALSE_OR_POP :
6221
6254
assert (inst -> i_target -> b_iused == 1 );
6222
- inst -> i_opcode = POP_JUMP_IF_TRUE ;
6223
- inst -> i_target = inst -> i_target -> b_next ;
6224
- -- i ;
6255
+ if (inst -> i_lineno == target -> i_lineno ) {
6256
+ inst -> i_opcode = POP_JUMP_IF_TRUE ;
6257
+ inst -> i_target = inst -> i_target -> b_next ;
6258
+ -- i ;
6259
+ }
6225
6260
break ;
6226
6261
}
6227
6262
break ;
@@ -6230,9 +6265,9 @@ optimize_basic_block(basicblock *bb, PyObject *consts)
6230
6265
switch (target -> i_opcode ) {
6231
6266
case JUMP_ABSOLUTE :
6232
6267
case JUMP_FORWARD :
6233
- if (inst -> i_target != target -> i_target ) {
6268
+ if (inst -> i_lineno == target -> i_lineno ) {
6234
6269
inst -> i_target = target -> i_target ;
6235
- -- i ;
6270
+ i -- ;
6236
6271
}
6237
6272
break ;
6238
6273
}
@@ -6242,9 +6277,9 @@ optimize_basic_block(basicblock *bb, PyObject *consts)
6242
6277
switch (target -> i_opcode ) {
6243
6278
case JUMP_ABSOLUTE :
6244
6279
case JUMP_FORWARD :
6245
- if (inst -> i_target != target -> i_target ) {
6280
+ if (inst -> i_lineno == target -> i_lineno ) {
6246
6281
inst -> i_target = target -> i_target ;
6247
- -- i ;
6282
+ i -- ;
6248
6283
}
6249
6284
break ;
6250
6285
}
@@ -6255,32 +6290,30 @@ optimize_basic_block(basicblock *bb, PyObject *consts)
6255
6290
assert (i == bb -> b_iused - 1 );
6256
6291
switch (target -> i_opcode ) {
6257
6292
case JUMP_FORWARD :
6258
- if (inst -> i_target != target -> i_target ) {
6259
- inst -> i_target = target -> i_target ;
6260
- // --i;
6293
+ if (eliminate_jump_to_jump (bb , inst -> i_opcode )) {
6294
+ goto error ;
6261
6295
}
6262
6296
break ;
6297
+
6263
6298
case JUMP_ABSOLUTE :
6264
- if (inst -> i_target != target -> i_target ) {
6265
- inst -> i_target = target -> i_target ;
6266
- inst -> i_opcode = target -> i_opcode ;
6267
- -- i ;
6299
+ if (eliminate_jump_to_jump (bb , JUMP_ABSOLUTE )) {
6300
+ goto error ;
6268
6301
}
6269
6302
break ;
6270
- }
6271
- if (inst -> i_target -> b_exit && inst -> i_target -> b_iused <= MAX_COPY_SIZE ) {
6272
- basicblock * to_copy = inst -> i_target ;
6273
- inst -> i_opcode = NOP ;
6274
- for (i = 0 ; i < to_copy -> b_iused ; i ++ ) {
6275
- int index = compiler_next_instr (bb );
6276
- if (index < 0 ) {
6277
- return -1 ;
6303
+ default :
6304
+ if (inst -> i_target -> b_exit && inst -> i_target -> b_iused <= MAX_COPY_SIZE ) {
6305
+ basicblock * to_copy = inst -> i_target ;
6306
+ inst -> i_opcode = NOP ;
6307
+ for (i = 0 ; i < to_copy -> b_iused ; i ++ ) {
6308
+ int index = compiler_next_instr (bb );
6309
+ if (index < 0 ) {
6310
+ return -1 ;
6311
+ }
6312
+ bb -> b_instr [index ] = to_copy -> b_instr [i ];
6313
+ }
6314
+ bb -> b_exit = 1 ;
6278
6315
}
6279
- bb -> b_instr [index ] = to_copy -> b_instr [i ];
6280
- }
6281
- bb -> b_exit = 1 ;
6282
6316
}
6283
- break ;
6284
6317
}
6285
6318
}
6286
6319
return 0 ;
0 commit comments