8000 gh-106149: move unconditional jump direction resolution from optimize… · python/cpython@200f255 · GitHub
[go: up one dir, main page]

Skip to content
Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 200f255

Browse files
authored
gh-106149: move unconditional jump direction resolution from optimizer to assembler (#106291)
1 parent d3abc9b commit 200f255

File tree

4 files changed

+44
-20
lines changed

4 files changed

+44
-20
lines changed

Python/assemble.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -674,11 +674,45 @@ resolve_jump_offsets(instr_sequence *instrs)
674674
return SUCCESS;
675675
}
676676

677+
static int
678+
resolve_unconditional_jumps(instr_sequence *instrs)
679+
{
680+
/* Resolve directions of unconditional jumps */
681+
682+
for (int i = 0; i < instrs->s_used; i++) {
683+
instruction *instr = &instrs->s_instrs[i];
684+
bool is_forward = (instr->i_oparg > i);
685+
switch(instr->i_opcode) {
686+
case JUMP:
687+
assert(SAME_OPCODE_METADATA(JUMP, JUMP_FORWARD));
688+
assert(SAME_OPCODE_METADATA(JUMP, JUMP_BACKWARD));
689+
instr->i_opcode = is_forward ? JUMP_FORWARD : JUMP_BACKWARD;
690+
break;
691+
case JUMP_NO_INTERRUPT:
692+
assert(SAME_OPCODE_METADATA(JUMP_NO_INTERRUPT, JUMP_FORWARD));
693+
assert(SAME_OPCODE_METADATA(JUMP_NO_INTERRUPT, JUMP_BACKWARD_NO_INTERRUPT));
694+
instr->i_opcode = is_forward ?
695+
JUMP_FORWARD : JUMP_BACKWARD_NO_INTERRUPT;
696+
break;
697+
default:
698+
if (OPCODE_HAS_JUMP(instr->i_opcode) &&
699+
IS_PSEUDO_INSTR(instr->i_opcode)) {
700+
Py_UNREACHABLE();
701+
}
702+
}
703+
}
704+
return SUCCESS;
705+
}
706+
677707
PyCodeObject *
678708
_PyAssemble_MakeCodeObject(_PyCompile_CodeUnitMetadata *umd, PyObject *const_cache,
679709
PyObject *consts, int maxdepth, instr_sequence *instrs,
680710
int nlocalsplus, int code_flags, PyObject *filename)
681711
{
712+
713+
if (resolve_unconditional_jumps(instrs) < 0) {
714+
return NULL;
715+
}
682716
if (resolve_jump_offsets(instrs) < 0) {
683717
return NULL;
684718
}

Python/flowgraph.c

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -393,24 +393,17 @@ no_redundant_jumps(cfg_builder *g) {
393393
static int
394394
normalize_jumps_in_block(cfg_builder *g, basicblock *b) {
395395
cfg_instr *last = _PyCfg_BasicblockLastInstr(b);
396-
if (last == NULL || !is_jump(last)) {
396+
if (last == NULL || !is_jump(last) ||
397+
IS_UNCONDITIONAL_JUMP_OPCODE(last->i_opcode)) {
397398
return SUCCESS;
398399
}
399400
assert(!IS_ASSEMBLER_OPCODE(last->i_opcode));
401+
400402
bool is_forward = last->i_target->b_visited == 0;
401-
switch(last->i_opcode) {
402-
case JUMP:
403-
assert(SAME_OPCODE_METADATA(JUMP, JUMP_FORWARD));
404-
assert(SAME_OPCODE_METADATA(JUMP, JUMP_BACKWARD));
405-
last->i_opcode = is_forward ? JUMP_FORWARD : JUMP_BACKWARD;
406-
return SUCCESS;
407-
case JUMP_NO_INTERRUPT:
408-
assert(SAME_OPCODE_METADATA(JUMP_NO_INTERRUPT, JUMP_FORWARD));
409-
assert(SAME_OPCODE_METADATA(JUMP_NO_INTERRUPT, JUMP_BACKWARD_NO_INTERRUPT));
410-
last->i_opcode = is_forward ?
411-
JUMP_FORWARD : JUMP_BACKWARD_NO_INTERRUPT;
412-
return SUCCESS;
403+
if (is_forward) {
404+
return SUCCESS;
413405
}
406+
414407
int reversed_opcode = 0;
415408
switch(last->i_opcode) {
416409
case POP_JUMP_IF_NOT_NONE:
@@ -426,9 +419,6 @@ normalize_jumps_in_block(cfg_builder *g, basicblock *b) {
426419
reversed_opcode = POP_JUMP_IF_FALSE;
427420
break;
428421
}
429-
if (is_forward) {
430-
return SUCCESS;
431-
}
432422
/* transform 'conditional jump T' to
433423
* 'reversed_jump b_next' followed by 'jump_backwards T'
434424
*/

Python/opcode_metadata.h

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Tools/cases_generator/generate_cases.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1310,10 +1310,10 @@ def write_metadata(self) -> None:
13101310

13111311
def write_pseudo_instrs(self) -> None:
13121312
"""Write the IS_PSEUDO_INSTR macro"""
1313-
self.out.emit("\n\n#define IS_PSEUDO_INSTR(OP) \\")
1313+
self.out.emit("\n\n#define IS_PSEUDO_INSTR(OP) ( \\")
13141314
for op in self.pseudos:
13151315
self.out.emit(f" ((OP) == {op}) || \\")
1316-
self.out.emit(f" 0")
1316+
self.out.emit(f" 0)")
13171317

13181318
def write_uop_items(self, make_text: typing.Callable[[str, int], str]) -> None:
13191319
"""Write '#define XXX NNN' for each uop"""

0 commit comments

Comments
 (0)
0