Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff line change
Expand Up@@ -4034,10 +4034,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 DownExpand Up@@ -4097,6 +4096,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 numberDiff line numberDiff line change
Expand Up@@ -414,9 +414,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 numberDiff line numberDiff 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 numberDiff line numberDiff line change
Expand Up@@ -1674,3 +1674,7 @@
break;
}

case _CHECK_VALIDITY_AND_SET_IP:{
break;
}