Skip to content

Commit

Permalink
pythonGH-113710: Improve _SET_IP and _CHECK_VALIDITY (pythonGH-11…
Browse files Browse the repository at this point in the history
  • Loading branch information
markshannon authored Feb 13, 2024
1 parent de07941 commit 681778c
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 35 deletions.
3 changes: 2 additions & 1 deletion Include/internal/pycore_uop_ids.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Include/internal/pycore_uop_metadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
[_GUARD_IS_NONE_POP] = HAS_DEOPT_FLAG,
[_GUARD_IS_NOT_NONE_POP] = HAS_DEOPT_FLAG,
[_JUMP_TO_TOP] = HAS_EVAL_BREAK_FLAG,
[_SET_IP] = HAS_ARG_FLAG | HAS_ESCAPES_FLAG,
[_SET_IP] = 0,
[_SAVE_RETURN_OFFSET] = HAS_ARG_FLAG,
[_EXIT_TRACE] = HAS_DEOPT_FLAG,
[_CHECK_VALIDITY] = HAS_DEOPT_FLAG,
Expand All @@ -209,6 +209,7 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
[_CHECK_GLOBALS] = HAS_DEOPT_FLAG,
[_CHECK_BUILTINS] = HAS_DEOPT_FLAG,
[_INTERNAL_INCREMENT_OPT_COUNTER] = 0,
[_CHECK_VALIDITY_AND_SET_IP] = HAS_DEOPT_FLAG,
};

const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = {
Expand Down Expand Up @@ -264,6 +265,7 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = {
[_CHECK_PEP_523] = "_CHECK_PEP_523",
[_CHECK_STACK_SPACE] = "_CHECK_STACK_SPACE",
[_CHECK_VALIDITY] = "_CHECK_VALIDITY",
[_CHECK_VALIDITY_AND_SET_IP] = "_CHECK_VALIDITY_AND_SET_IP",
[_COMPARE_OP] = "_COMPARE_OP",
[_COMPARE_OP_FLOAT] = "_COMPARE_OP_FLOAT",
[_COMPARE_OP_INT] = "_COMPARE_OP_INT",
Expand Down
10 changes: 7 additions & 3 deletions Python/bytecodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -4037,10 +4037,9 @@ dummy_func(
CHECK_EVAL_BREAKER();
}

op(_SET_IP, (--)) {
op(_SET_IP, (instr_ptr/4 --)) {
TIER_TWO_ONLY
// TODO: Put the code pointer in `operand` to avoid indirection via `frame`
frame->instr_ptr = _PyCode_CODE(_PyFrame_GetCode(frame)) + oparg;
frame->instr_ptr = (_Py_CODEUNIT *)instr_ptr;
}

op(_SAVE_RETURN_OFFSET, (--)) {
Expand Down Expand Up @@ -4100,6 +4099,11 @@ dummy_func(
exe->count++;
}

op(_CHECK_VALIDITY_AND_SET_IP, (instr_ptr/4 --)) {
TIER_TWO_ONLY
DEOPT_IF(!current_executor->vm_data.valid);
frame->instr_ptr = (_Py_CODEUNIT *)instr_ptr;
}

// END BYTECODES //

Expand Down
13 changes: 10 additions & 3 deletions Python/executor_cases.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 2 additions & 3 deletions Python/optimizer.c
Original file line number Diff line number Diff line change
Expand Up @@ -432,9 +432,8 @@ translate_bytecode_to_trace(
top: // Jump here after _PUSH_FRAME or likely branches
for (;;) {
target = INSTR_IP(instr, code);
RESERVE_RAW(3, "epilogue"); // Always need space for _SET_IP, _CHECK_VALIDITY and _EXIT_TRACE
ADD_TO_TRACE(_SET_IP, target, 0, target);
ADD_TO_TRACE(_CHECK_VALIDITY, 0, 0, target);
RESERVE_RAW(2, "epilogue"); // Always need space for _SET_IP, _CHECK_VALIDITY and _EXIT_TRACE
ADD_TO_TRACE(_CHECK_VALIDITY_AND_SET_IP, 0, (uintptr_t)instr, target);

uint32_t opcode = instr->op.code;
uint32_t oparg = instr->op.arg;
Expand Down
75 changes: 51 additions & 24 deletions Python/optimizer_analysis.c
Original file line number Diff line number Diff line change
Expand Up @@ -652,35 +652,62 @@ uop_redundancy_eliminator(
static void
remove_unneeded_uops(_PyUOpInstruction *buffer, int buffer_size)
{
/* Remove _SET_IP and _CHECK_VALIDITY where possible.
* _SET_IP is needed if the following instruction escapes or
* could error. _CHECK_VALIDITY is needed if the previous
* instruction could have escaped. */
int last_set_ip = -1;
bool maybe_invalid = false;
bool may_have_escaped = false;
for (int pc = 0; pc < buffer_size; pc++) {
int opcode = buffer[pc].opcode;
if (opcode == _SET_IP) {
buffer[pc].opcode = NOP;
last_set_ip = pc;
}
else if (opcode == _CHECK_VALIDITY) {
if (maybe_invalid) {
maybe_invalid = false;
}
else {
switch (opcode) {
case _SET_IP:
buffer[pc].opcode = NOP;
}
}
else if (op_is_end(opcode)) {
break;
}
else {
if (_PyUop_Flags[opcode] & HAS_ESCAPES_FLAG) {
maybe_invalid = true;
if (last_set_ip >= 0) {
buffer[last_set_ip].opcode = _SET_IP;
last_set_ip = pc;
break;
case _CHECK_VALIDITY:
if (may_have_escaped) {
may_have_escaped = false;
}
}
if ((_PyUop_Flags[opcode] & HAS_ERROR_FLAG) || opcode == _PUSH_FRAME) {
if (last_set_ip >= 0) {
buffer[last_set_ip].opcode = _SET_IP;
else {
buffer[pc].opcode = NOP;
}
break;
case _CHECK_VALIDITY_AND_SET_IP:
if (may_have_escaped) {
may_have_escaped = false;
buffer[pc].opcode = _CHECK_VALIDITY;
}
else {
buffer[pc].opcode = NOP;
}
last_set_ip = pc;
break;
case _JUMP_TO_TOP:
case _EXIT_TRACE:
return;
default:
{
bool needs_ip = false;
if (_PyUop_Flags[opcode] & HAS_ESCAPES_FLAG) {
needs_ip = true;
may_have_escaped = true;
}
if (_PyUop_Flags[opcode] & HAS_ERROR_FLAG) {
needs_ip = true;
}
if (opcode == _PUSH_FRAME) {
needs_ip = true;
}
if (needs_ip && last_set_ip >= 0) {
if (buffer[last_set_ip].opcode == _CHECK_VALIDITY) {
buffer[last_set_ip].opcode = _CHECK_VALIDITY_AND_SET_IP;
}
else {
assert(buffer[last_set_ip].opcode == _NOP);
buffer[last_set_ip].opcode = _SET_IP;
}
last_set_ip = -1;
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions Python/tier2_redundancy_eliminator_cases.c.h
Original file line number Diff line number Diff line change
Expand Up @@ -1674,3 +1674,7 @@
break;
}

case _CHECK_VALIDITY_AND_SET_IP: {
break;
}

0 comments on commit 681778c

Please sign in to comment.