summaryrefslogtreecommitdiffstats
path: root/Python/optimizer_analysis.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/optimizer_analysis.c')
-rw-r--r--Python/optimizer_analysis.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/Python/optimizer_analysis.c b/Python/optimizer_analysis.c
index 7db51f0..d122599 100644
--- a/Python/optimizer_analysis.c
+++ b/Python/optimizer_analysis.c
@@ -13,6 +13,39 @@
#include "pycore_optimizer.h"
static void
+peephole_opt(PyCodeObject *co, _PyUOpInstruction *buffer, int buffer_size)
+{
+ for (int pc = 0; pc < buffer_size; pc++) {
+ int opcode = buffer[pc].opcode;
+ switch(opcode) {
+ case _LOAD_CONST: {
+ assert(co != NULL);
+ PyObject *val = PyTuple_GET_ITEM(co->co_consts, buffer[pc].oparg);
+ buffer[pc].opcode = _Py_IsImmortal(val) ? _LOAD_CONST_INLINE_BORROW : _LOAD_CONST_INLINE;
+ buffer[pc].operand = (uintptr_t)val;
+ break;
+ }
+ case _CHECK_PEP_523:
+ {
+ /* Setting the eval frame function invalidates
+ * all executors, so no need to check dynamically */
+ if (_PyInterpreterState_GET()->eval_frame == NULL) {
+ buffer[pc].opcode = _NOP;
+ }
+ break;
+ }
+ case _PUSH_FRAME:
+ case _POP_FRAME:
+ co = (PyCodeObject *)buffer[pc].operand;
+ break;
+ case _JUMP_TO_TOP:
+ case _EXIT_TRACE:
+ return;
+ }
+ }
+}
+
+static void
remove_unneeded_uops(_PyUOpInstruction *buffer, int buffer_size)
{
int last_set_ip = -1;
@@ -59,6 +92,7 @@ _Py_uop_analyze_and_optimize(
int curr_stacklen
)
{
+ peephole_opt(co, buffer, buffer_size);
remove_unneeded_uops(buffer, buffer_size);
return 0;
}