Skip to content

Commit 7f7c575

Browse files
Always use a new block after jumps.
1 parent a8025f0 commit 7f7c575

1 file changed

Lines changed: 18 additions & 47 deletions

File tree

‎Python/compile.c‎

Lines changed: 18 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -788,30 +788,6 @@ compiler_use_next_block(struct compiler *c, basicblock *block)
788788
return block;
789789
}
790790

791-
static basicblock *
792-
compiler_split_block(struct compiler *c, basicblock *b, int off)
793-
{
794-
basicblock *b2 = compiler_new_block(c);
795-
if (b2 == NULL) {
796-
return NULL;
797-
}
798-
assert(off < b->b_iused);
799-
int size = b->b_iused - off;
800-
b2->b_instr = (struct instr *)PyObject_Malloc(sizeof(struct instr) * size);
801-
if (b2->b_instr == NULL) {
802-
PyErr_NoMemory();
803-
return NULL;
804-
}
805-
b2->b_iused = b2->b_ialloc = size;
806-
memcpy(b2->b_instr, b->b_instr + off, sizeof(struct instr) * size);
807-
b->b_iused = off;
808-
b2->b_next = b->b_next;
809-
b->b_next = b2;
810-
b->b_return = 0;
811-
812-
return b2;
813-
}
814-
815791
/* Returns the offset of the next instruction in the current block's
816792
b_instr array. Resizes the b_instr as necessary.
817793
Returns -1 on failure.
@@ -2412,6 +2388,7 @@ compiler_jump_if(struct compiler *c, expr_ty e, basicblock *next, int cond)
24122388
ADDOP_I(c, COMPARE_OP,
24132389
cmpop((cmpop_ty)(asdl_seq_GET(e->v.Compare.ops, n))));
24142390
ADDOP_JABS(c, cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next);
2391+
NEXT_BLOCK(c);
24152392
basicblock *end = compiler_new_block(c);
24162393
if (end == NULL)
24172394
return 0;
@@ -2432,6 +2409,7 @@ compiler_jump_if(struct compiler *c, expr_ty e, basicblock *next, int cond)
24322409
if (constant >= 0) {
24332410
if (constant == cond) {
24342411
ADDOP_JABS(c, JUMP_ABSOLUTE, next);
2412+
NEXT_BLOCK(c);
24352413
}
24362414
return 1;
24372415
}
@@ -2443,6 +2421,7 @@ compiler_jump_if(struct compiler *c, expr_ty e, basicblock *next, int cond)
24432421
/* general implementation */
24442422
VISIT(c, expr, e);
24452423
ADDOP_JABS(c, cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next);
2424+
NEXT_BLOCK(c);
24462425
return 1;
24472426
}
24482427

@@ -2684,6 +2663,8 @@ compiler_while(struct compiler *c, stmt_ty s)
26842663

26852664
if (constant == -1)
26862665
compiler_use_next_block(c, anchor);
2666+
else if (orelse != NULL)
2667+
NEXT_BLOCK(c);
26872668
compiler_pop_fblock(c, WHILE_LOOP, loop);
26882669

26892670
if (orelse != NULL) /* what if orelse is just pass? */
@@ -2736,6 +2717,7 @@ compiler_break(struct compiler *c)
27362717
return 0;
27372718
if (info->fb_type == WHILE_LOOP || info->fb_type == FOR_LOOP) {
27382719
ADDOP_JABS(c, JUMP_ABSOLUTE, info->fb_exit);
2720+
NEXT_BLOCK(c);
27392721
return 1;
27402722
}
27412723
}
@@ -2750,6 +2732,7 @@ compiler_continue(struct compiler *c)
27502732

27512733
if (info->fb_type == WHILE_LOOP || info->fb_type == FOR_LOOP) {
27522734
ADDOP_JABS(c, JUMP_ABSOLUTE, info->fb_block);
2735+
NEXT_BLOCK(c);
27532736
return 1;
27542737
}
27552738
if (!compiler_unwind_fblock(c, info, 0))
@@ -2897,6 +2880,7 @@ compiler_try_except(struct compiler *c, stmt_ty s)
28972880
VISIT(c, expr, handler->v.ExceptHandler.type);
28982881
ADDOP_I(c, COMPARE_OP, PyCmp_EXC_MATCH);
28992882
ADDOP_JABS(c, POP_JUMP_IF_FALSE, except);
2883+
NEXT_BLOCK(c);
29002884
}
29012885
ADDOP(c, POP_TOP);
29022886
if (handler->v.ExceptHandler.name) {
@@ -3511,6 +3495,7 @@ compiler_boolop(struct compiler *c, expr_ty e)
35113495
for (i = 0; i < n; ++i) {
35123496
VISIT(c, expr, (expr_ty)asdl_seq_GET(s, i));
35133497
ADDOP_JABS(c, jumpi, end);
3498+
NEXT_BLOCK(c);
35143499
}
35153500
VISIT(c, expr, (expr_ty)asdl_seq_GET(s, n));
35163501
compiler_use_next_block(c, end);
@@ -5483,8 +5468,9 @@ optimize_jumps(struct compiler *c)
54835468
case JUMP_FORWARD:
54845469
case JUMP_ABSOLUTE:
54855470
assert(instr->i_target != NULL);
5486-
while (1) {
5487-
/* Skip empty blocks */
5471+
int count = 10;
5472+
while (count--) {
5473+
/* Skip empty blocks. */
54885474
while (!instr->i_target->b_iused) {
54895475
assert(instr->i_target->b_next);
54905476
instr->i_target = instr->i_target->b_next;
@@ -5495,7 +5481,7 @@ optimize_jumps(struct compiler *c)
54955481
break;
54965482
}
54975483

5498-
/* Replace jumps to unconditional jumps */
5484+
/* Replace jumps to unconditional jumps. */
54995485
if (UNCONDITIONAL_JUMP(tgt->i_opcode)) {
55005486
if (instr->i_opcode == JUMP_FORWARD) {
55015487
/* JUMP_ABSOLUTE can go backwards */
@@ -5507,7 +5493,8 @@ optimize_jumps(struct compiler *c)
55075493
continue;
55085494
}
55095495

5510-
/* Replace JUMP_* to a RETURN into just a RETURN */
5496+
/* Replace JUMP_* to a RETURN into just a RETURN.
5497+
Arises in code like "return a if b else c". */
55115498
if (UNCONDITIONAL_JUMP(instr->i_opcode)) {
55125499
if (tgt->i_opcode == RETURN_VALUE) {
55135500
*instr = *tgt;
@@ -5537,32 +5524,16 @@ optimize_jumps(struct compiler *c)
55375524
if (JUMPS_ON_TRUE(tgt->i_opcode) == JUMPS_ON_TRUE(instr->i_opcode)) {
55385525
/* The second jump will be taken iff the first is.
55395526
The current opcode inherits its target's
5540-
stack effect */
5527+
stack effect. */
55415528
instr->i_target = tgt->i_target;
55425529
continue;
55435530
}
5544-
else {
5531+
else if (instr->i_target->b_iused == 1) {
55455532
/* The second jump is not taken if the first is (so
55465533
jump past it), and all conditional jumps pop their
55475534
argument when they're not taken (so change the
55485535
first jump to pop its argument when it's taken). */
5549-
basicblock *b2;
5550-
if (instr->i_target->b_iused > 1) {
5551-
b2 = compiler_split_block(c, instr->i_target, 1);
5552-
if (!b2) {
5553-
PyErr_Clear();
5554-
break;
5555-
}
5556-
/* Move b2 after b so it will be processed in future iterations */
5557-
assert(c->u->u_blocks == b2);
5558-
c->u->u_blocks = b2->b_list;
5559-
b2->b_list = b->b_list;
5560-
b->b_list = b2;
5561-
}
5562-
else {
5563-
b2 = instr->i_target->b_next;
5564-
}
5565-
instr->i_target = b2;
5536+
instr->i_target = instr->i_target->b_next;
55665537
instr->i_opcode = instr->i_opcode == JUMP_IF_TRUE_OR_POP ?
55675538
POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE;
55685539
continue;

0 commit comments

Comments
 (0)