Skip to content

Commit 8fc38dd

Browse files
committed
Fix handling of NOT_TAKEN for backward conditional branches
1 parent 10ee198 commit 8fc38dd

File tree

3 files changed

+18
-12
lines changed

3 files changed

+18
-12
lines changed

Lib/test/test_compiler_codegen.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def test_if_expression(self):
2929
('LOAD_CONST', 0, 1),
3030
('TO_BOOL', 0, 1),
3131
('POP_JUMP_IF_FALSE', false_lbl := self.Label(), 1),
32-
('NOT_TAKEN', None, 1, 1),
32+
('NOT_TAKEN', None, -1, -1),
3333
('LOAD_CONST', 1, 1),
3434
('JUMP_NO_INTERRUPT', exit_lbl := self.Label()),
3535
false_lbl,
@@ -50,7 +50,7 @@ def test_for_loop(self):
5050
('GET_ITER', None, 1),
5151
loop_lbl := self.Label(),
5252
('FOR_ITER', exit_lbl := self.Label(), 1),
53-
('NOT_TAKEN', None, 1, 1),
53+
('NOT_TAKEN', None, -1, -1),
5454
('NOP', None, 1, 1),
5555
('STORE_NAME', 1, 1),
5656
('LOAD_NAME', 2, 2),

Python/compile.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1476,7 +1476,7 @@ codegen_setup_annotations_scope(struct compiler *c, location loc,
14761476
ADDOP_I(c, loc, COMPARE_OP, (Py_NE << 5) | compare_masks[Py_NE]);
14771477
NEW_JUMP_TARGET_LABEL(c, body);
14781478
ADDOP_JUMP(c, loc, POP_JUMP_IF_FALSE, body);
1479-
ADDOP(c, loc, NOT_TAKEN);
1479+
ADDOP(c, NO_LOCATION, NOT_TAKEN);
14801480
ADDOP_I(c, loc, LOAD_COMMON_CONSTANT, CONSTANT_NOTIMPLEMENTEDERROR);
14811481
ADDOP_I(c, loc, RAISE_VARARGS, 1);
14821482
USE_LABEL(c, body);
@@ -2806,13 +2806,13 @@ codegen_jump_if(struct compiler *c, location loc,
28062806
ADDOP_COMPARE(c, LOC(e), asdl_seq_GET(e->v.Compare.ops, i));
28072807
ADDOP(c, LOC(e), TO_BOOL);
28082808
ADDOP_JUMP(c, LOC(e), POP_JUMP_IF_FALSE, cleanup);
2809-
ADDOP(c, loc, NOT_TAKEN);
2809+
ADDOP(c, NO_LOCATION, NOT_TAKEN);
28102810
}
28112811
VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n));
28122812
ADDOP_COMPARE(c, LOC(e), asdl_seq_GET(e->v.Compare.ops, n));
28132813
ADDOP(c, LOC(e), TO_BOOL);
28142814
ADDOP_JUMP(c, LOC(e), cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next);
2815-
ADDOP(c, LOC(e), NOT_TAKEN);
2815+
ADDOP(c, NO_LOCATION, NOT_TAKEN);
28162816
NEW_JUMP_TARGET_LABEL(c, end);
28172817
ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
28182818

@@ -2837,7 +2837,7 @@ codegen_jump_if(struct compiler *c, location loc,
28372837
VISIT(c, expr, e);
28382838
ADDOP(c, LOC(e), TO_BOOL);
28392839
ADDOP_JUMP(c, LOC(e), cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next);
2840-
ADDOP(c, LOC(e), NOT_TAKEN);
2840+
ADDOP(c, NO_LOCATION, NOT_TAKEN);
28412841
return SUCCESS;
28422842
}
28432843

@@ -2961,7 +2961,7 @@ codegen_for(struct compiler *c, stmt_ty s)
29612961

29622962
USE_LABEL(c, start);
29632963
ADDOP_JUMP(c, loc, FOR_ITER, cleanup);
2964-
ADDOP(c, loc, NOT_TAKEN);
2964+
ADDOP(c, NO_LOCATION, NOT_TAKEN);
29652965

29662966
/* Add NOP to ensure correct line tracing of multiline for statements.
29672967
* It will be removed later if redundant.
@@ -3342,7 +3342,7 @@ codegen_try_except(struct compiler *c, stmt_ty s)
33423342
VISIT(c, expr, handler->v.ExceptHandler.type);
33433343
ADDOP(c, loc, CHECK_EXC_MATCH);
33443344
ADDOP_JUMP(c, loc, POP_JUMP_IF_FALSE, except);
3345-
ADDOP(c, loc, NOT_TAKEN);
3345+
ADDOP(c, NO_LOCATION, NOT_TAKEN);
33463346
}
33473347
if (handler->v.ExceptHandler.name) {
33483348
NEW_JUMP_TARGET_LABEL(c, cleanup_end);
@@ -3537,7 +3537,7 @@ codegen_try_star_except(struct compiler *c, stmt_ty s)
35373537
ADDOP(c, loc, CHECK_EG_MATCH);
35383538
ADDOP_I(c, loc, COPY, 1);
35393539
ADDOP_JUMP(c, loc, POP_JUMP_IF_NONE, no_match);
3540-
ADDOP(c, loc, NOT_TAKEN);
3540+
ADDOP(c, NO_LOCATION, NOT_TAKEN);
35413541
}
35423542

35433543
NEW_JUMP_TARGET_LABEL(c, cleanup_end);
@@ -4502,7 +4502,7 @@ codegen_compare(struct compiler *c, expr_ty e)
45024502
ADDOP_I(c, loc, COPY, 1);
45034503
ADDOP(c, loc, TO_BOOL);
45044504
ADDOP_JUMP(c, loc, POP_JUMP_IF_FALSE, cleanup);
4505-
ADDOP(c, loc, NOT_TAKEN);
4505+
ADDOP(c, NO_LOCATION, NOT_TAKEN);
45064506
ADDOP(c, loc, POP_TOP);
45074507
}
45084508
VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n));
@@ -5201,7 +5201,7 @@ compiler_sync_comprehension_generator(struct compiler *c, location loc,
52015201
depth++;
52025202
USE_LABEL(c, start);
52035203
ADDOP_JUMP(c, LOC(gen->iter), FOR_ITER, anchor);
5204-
ADDOP(c, loc, NOT_TAKEN);
5204+
ADDOP(c, NO_LOCATION, NOT_TAKEN);
52055205
}
52065206
VISIT(c, expr, gen->target);
52075207

@@ -6590,7 +6590,7 @@ jump_to_fail_pop(struct compiler *c, location loc,
65906590
RETURN_IF_ERROR(ensure_fail_pop(c, pc, pops));
65916591
ADDOP_JUMP(c, loc, op, pc->fail_pop[pops]);
65926592
if (op != JUMP) {
6593-
ADDOP(c, loc, NOT_TAKEN);
6593+
ADDOP(c, NO_LOCATION, NOT_TAKEN);
65946594
}
65956595
return SUCCESS;
65966596
}

Python/flowgraph.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,12 @@ normalize_jumps_in_block(cfg_builder *g, basicblock *b) {
575575
if (backwards_jump == NULL) {
576576
return ERROR;
577577
}
578+
assert(b->b_next->b_iused > 0);
579+
assert(b->b_next->b_instr[0].i_opcode == NOT_TAKEN);
580+
b->b_next->b_instr[0].i_opcode = NOP;
581+
b->b_next->b_instr[0].i_loc = NO_LOCATION;
582+
RETURN_IF_ERROR(
583+
basicblock_addop(backwards_jump, NOT_TAKEN, 0, last->i_loc));
578584
RETURN_IF_ERROR(
579585
basicblock_add_jump(backwards_jump, JUMP, target, last->i_loc));
580586
last->i_opcode = reversed_opcode;

0 commit comments

Comments
 (0)