summaryrefslogtreecommitdiffstats
path: root/Python/optimizer_analysis.c
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2024-02-13 16:28:19 (GMT)
committerGitHub <noreply@github.com>2024-02-13 16:28:19 (GMT)
commit681778c56a9204d65b8857e7ceba57f2c638671d (patch)
tree7d0f520a767a175e40f09f6aa40decc56fce7608 /Python/optimizer_analysis.c
parentde07941729b8899b187b8ef9690f9a74b2d6286b (diff)
downloadcpython-681778c56a9204d65b8857e7ceba57f2c638671d.zip
cpython-681778c56a9204d65b8857e7ceba57f2c638671d.tar.gz
cpython-681778c56a9204d65b8857e7ceba57f2c638671d.tar.bz2
GH-113710: Improve `_SET_IP` and `_CHECK_VALIDITY` (GH-115248)
Diffstat (limited to 'Python/optimizer_analysis.c')
-rw-r--r--Python/optimizer_analysis.c75
1 files changed, 51 insertions, 24 deletions
diff --git a/Python/optimizer_analysis.c b/Python/optimizer_analysis.c
index e02ca4d..4997452 100644
--- a/Python/optimizer_analysis.c
+++ b/Python/optimizer_analysis.c
@@ -652,35 +652,62 @@ error:
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;
}
}
}