Skip to content

Commit f483964

Browse files
committed
Make the peephole pass way simpler
1 parent 2f8dad9 commit f483964

File tree

6 files changed

+104
-78
lines changed

6 files changed

+104
-78
lines changed

Include/internal/pycore_uop_ids.h

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

Include/internal/pycore_uop_metadata.h

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

Python/bytecodes.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,11 @@ dummy_func(
393393
PyStackRef_CLOSE(value);
394394
}
395395

396+
tier2 op(_POP_TWO, (nos, tos --)) {
397+
PyStackRef_CLOSE(tos);
398+
PyStackRef_CLOSE(nos);
399+
}
400+
396401
pure inst(PUSH_NULL, (-- res)) {
397402
res = PyStackRef_NULL;
398403
}

Python/executor_cases.c.h

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

Python/optimizer_analysis.c

Lines changed: 33 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,25 @@ optimize_uops(
523523

524524
}
525525

526+
const uint16_t op_without_pop[MAX_UOP_ID] = {
527+
[_POP_TOP] = _NOP,
528+
[_POP_TOP_LOAD_CONST_INLINE] = _LOAD_CONST_INLINE,
529+
[_POP_TOP_LOAD_CONST_INLINE_BORROW] = _LOAD_CONST_INLINE_BORROW,
530+
[_POP_TWO_LOAD_CONST_INLINE_BORROW] = _POP_TOP_LOAD_CONST_INLINE_BORROW,
531+
};
532+
533+
const uint16_t remove_push[MAX_UOP_ID] = {
534+
[_COPY] = _NOP,
535+
[_LOAD_CONST_INLINE] = _NOP,
536+
[_LOAD_CONST_INLINE_BORROW] = _NOP,
537+
[_LOAD_FAST] = _NOP,
538+
[_LOAD_FAST_BORROW] = _NOP,
539+
[_LOAD_SMALL_INT] = _NOP,
540+
[_POP_TOP_LOAD_CONST_INLINE] = _POP_TOP,
541+
[_POP_TOP_LOAD_CONST_INLINE_BORROW] = _POP_TOP,
542+
[_POP_TWO_LOAD_CONST_INLINE_BORROW] = _POP_TWO,
543+
};
544+
526545

527546
static int
528547
remove_unneeded_uops(_PyUOpInstruction *buffer, int buffer_size)
@@ -551,50 +570,23 @@ remove_unneeded_uops(_PyUOpInstruction *buffer, int buffer_size)
551570
buffer[pc].opcode = _NOP;
552571
}
553572
break;
554-
case _POP_TOP:
555-
case _POP_TOP_LOAD_CONST_INLINE:
556-
case _POP_TOP_LOAD_CONST_INLINE_BORROW:
557-
case _POP_TWO_LOAD_CONST_INLINE_BORROW:
558-
optimize_pop_top_again:
573+
default:
559574
{
560-
_PyUOpInstruction *last = &buffer[pc-1];
561-
while (last->opcode == _NOP) {
562-
last--;
563-
}
564-
switch (last->opcode) {
565-
case _POP_TWO_LOAD_CONST_INLINE_BORROW:
566-
last->opcode = _POP_TOP;
575+
// Cancel out pushes and pops, repeatedly. So:
576+
// _LOAD_FAST + _POP_TWO_LOAD_CONST_INLINE_BORROW + _POP_TOP
577+
// ...becomes:
578+
// _NOP + _POP_TOP + _NOP
579+
while (op_without_pop[opcode]) {
580+
_PyUOpInstruction *last = &buffer[pc - 1];
581+
while (last->opcode == _NOP) {
582+
last--;
583+
}
584+
if (!remove_push[last->opcode]) {
567585
break;
568-
case _POP_TOP_LOAD_CONST_INLINE:
569-
case _POP_TOP_LOAD_CONST_INLINE_BORROW:
570-
last->opcode = _NOP;
571-
goto optimize_pop_top_again;
572-
case _COPY:
573-
case _LOAD_CONST_INLINE:
574-
case _LOAD_CONST_INLINE_BORROW:
575-
case _LOAD_FAST:
576-
case _LOAD_FAST_BORROW:
577-
case _LOAD_SMALL_INT:
578-
last->opcode = _NOP;
579-
if (opcode == _POP_TOP) {
580-
opcode = buffer[pc].opcode = _NOP;
581-
}
582-
else if (opcode == _POP_TOP_LOAD_CONST_INLINE) {
583-
opcode = buffer[pc].opcode = _LOAD_CONST_INLINE;
584-
}
585-
else if (opcode == _POP_TOP_LOAD_CONST_INLINE_BORROW) {
586-
opcode = buffer[pc].opcode = _LOAD_CONST_INLINE_BORROW;
587-
}
588-
else {
589-
assert(opcode == _POP_TWO_LOAD_CONST_INLINE_BORROW);
590-
opcode = buffer[pc].opcode = _POP_TOP_LOAD_CONST_INLINE_BORROW;
591-
goto optimize_pop_top_again;
592-
}
586+
}
587+
last->opcode = remove_push[last->opcode];
588+
opcode = buffer[pc].opcode = op_without_pop[opcode];
593589
}
594-
_Py_FALLTHROUGH;
595-
}
596-
default:
597-
{
598590
/* _PUSH_FRAME doesn't escape or error, but it
599591
* does need the IP for the return address */
600592
bool needs_ip = opcode == _PUSH_FRAME;

Python/optimizer_cases.c.h

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

0 commit comments

Comments
 (0)