aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Python
diff options
context:
space:
mode:
Diffstat (limited to 'Python')
-rw-r--r--Python/assemble.c10
-rw-r--r--Python/bytecodes.c72
-rw-r--r--Python/ceval.c1
-rw-r--r--Python/compile.c37
-rw-r--r--Python/flowgraph.c4
-rw-r--r--Python/generated_cases.c.h19
-rw-r--r--Python/optimizer.c32
-rw-r--r--Python/specialize.c1
8 files changed, 93 insertions, 83 deletions
diff --git a/Python/assemble.c b/Python/assemble.c
index b6fb432aed4..569454ebf3b 100644
--- a/Python/assemble.c
+++ b/Python/assemble.c
@@ -4,7 +4,7 @@
#include "pycore_code.h" // write_location_entry_start()
#include "pycore_compile.h"
#include "pycore_opcode_utils.h" // IS_BACKWARDS_JUMP_OPCODE
-#include "pycore_opcode_metadata.h" // IS_PSEUDO_INSTR, _PyOpcode_Caches
+#include "pycore_opcode_metadata.h" // is_pseudo_target, _PyOpcode_Caches
#define DEFAULT_CODE_SIZE 128
@@ -710,13 +710,13 @@ resolve_unconditional_jumps(instr_sequence *instrs)
bool is_forward = (instr->i_oparg > i);
switch(instr->i_opcode) {
case JUMP:
- assert(SAME_OPCODE_METADATA(JUMP, JUMP_FORWARD));
- assert(SAME_OPCODE_METADATA(JUMP, JUMP_BACKWARD));
+ assert(is_pseudo_target(JUMP, JUMP_FORWARD));
+ assert(is_pseudo_target(JUMP, JUMP_BACKWARD));
instr->i_opcode = is_forward ? JUMP_FORWARD : JUMP_BACKWARD;
break;
case JUMP_NO_INTERRUPT:
- assert(SAME_OPCODE_METADATA(JUMP_NO_INTERRUPT, JUMP_FORWARD));
- assert(SAME_OPCODE_METADATA(JUMP_NO_INTERRUPT, JUMP_BACKWARD_NO_INTERRUPT));
+ assert(is_pseudo_target(JUMP_NO_INTERRUPT, JUMP_FORWARD));
+ assert(is_pseudo_target(JUMP_NO_INTERRUPT, JUMP_BACKWARD_NO_INTERRUPT));
instr->i_opcode = is_forward ?
JUMP_FORWARD : JUMP_BACKWARD_NO_INTERRUPT;
break;
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index 19e2268046f..82d7a71d498 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -330,14 +330,14 @@ dummy_func(
#endif /* ENABLE_SPECIALIZATION */
}
- op(_TO_BOOL, (unused/2, value -- res)) {
+ op(_TO_BOOL, (value -- res)) {
int err = PyObject_IsTrue(value);
DECREF_INPUTS();
ERROR_IF(err < 0, error);
res = err ? Py_True : Py_False;
}
- macro(TO_BOOL) = _SPECIALIZE_TO_BOOL + _TO_BOOL;
+ macro(TO_BOOL) = _SPECIALIZE_TO_BOOL + unused/2 + _TO_BOOL;
inst(TO_BOOL_BOOL, (unused/1, unused/2, value -- value)) {
DEOPT_IF(!PyBool_Check(value));
@@ -416,7 +416,7 @@ dummy_func(
DEOPT_IF(!PyLong_CheckExact(right));
}
- op(_BINARY_OP_MULTIPLY_INT, (unused/1, left, right -- res)) {
+ op(_BINARY_OP_MULTIPLY_INT, (left, right -- res)) {
STAT_INC(BINARY_OP, hit);
res = _PyLong_Multiply((PyLongObject *)left, (PyLongObject *)right);
_Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free);
@@ -424,7 +424,7 @@ dummy_func(
ERROR_IF(res == NULL, error);
}
- op(_BINARY_OP_ADD_INT, (unused/1, left, right -- res)) {
+ op(_BINARY_OP_ADD_INT, (left, right -- res)) {
STAT_INC(BINARY_OP, hit);
res = _PyLong_Add((PyLongObject *)left, (PyLongObject *)right);
_Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free);
@@ -432,7 +432,7 @@ dummy_func(
ERROR_IF(res == NULL, error);
}
- op(_BINARY_OP_SUBTRACT_INT, (unused/1, left, right -- res)) {
+ op(_BINARY_OP_SUBTRACT_INT, (left, right -- res)) {
STAT_INC(BINARY_OP, hit);
res = _PyLong_Subtract((PyLongObject *)left, (PyLongObject *)right);
_Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free);
@@ -441,18 +441,18 @@ dummy_func(
}
macro(BINARY_OP_MULTIPLY_INT) =
- _GUARD_BOTH_INT + _BINARY_OP_MULTIPLY_INT;
+ _GUARD_BOTH_INT + unused/1 + _BINARY_OP_MULTIPLY_INT;
macro(BINARY_OP_ADD_INT) =
- _GUARD_BOTH_INT + _BINARY_OP_ADD_INT;
+ _GUARD_BOTH_INT + unused/1 + _BINARY_OP_ADD_INT;
macro(BINARY_OP_SUBTRACT_INT) =
- _GUARD_BOTH_INT + _BINARY_OP_SUBTRACT_INT;
+ _GUARD_BOTH_INT + unused/1 + _BINARY_OP_SUBTRACT_INT;
op(_GUARD_BOTH_FLOAT, (left, right -- left, right)) {
DEOPT_IF(!PyFloat_CheckExact(left));
DEOPT_IF(!PyFloat_CheckExact(right));
}
- op(_BINARY_OP_MULTIPLY_FLOAT, (unused/1, left, right -- res)) {
+ op(_BINARY_OP_MULTIPLY_FLOAT, (left, right -- res)) {
STAT_INC(BINARY_OP, hit);
double dres =
((PyFloatObject *)left)->ob_fval *
@@ -460,7 +460,7 @@ dummy_func(
DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dres, res);
}
- op(_BINARY_OP_ADD_FLOAT, (unused/1, left, right -- res)) {
+ op(_BINARY_OP_ADD_FLOAT, (left, right -- res)) {
STAT_INC(BINARY_OP, hit);
double dres =
((PyFloatObject *)left)->ob_fval +
@@ -468,7 +468,7 @@ dummy_func(
DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dres, res);
}
- op(_BINARY_OP_SUBTRACT_FLOAT, (unused/1, left, right -- res)) {
+ op(_BINARY_OP_SUBTRACT_FLOAT, (left, right -- res)) {
STAT_INC(BINARY_OP, hit);
double dres =
((PyFloatObject *)left)->ob_fval -
@@ -477,18 +477,18 @@ dummy_func(
}
macro(BINARY_OP_MULTIPLY_FLOAT) =
- _GUARD_BOTH_FLOAT + _BINARY_OP_MULTIPLY_FLOAT;
+ _GUARD_BOTH_FLOAT + unused/1 + _BINARY_OP_MULTIPLY_FLOAT;
macro(BINARY_OP_ADD_FLOAT) =
- _GUARD_BOTH_FLOAT + _BINARY_OP_ADD_FLOAT;
+ _GUARD_BOTH_FLOAT + unused/1 + _BINARY_OP_ADD_FLOAT;
macro(BINARY_OP_SUBTRACT_FLOAT) =
- _GUARD_BOTH_FLOAT + _BINARY_OP_SUBTRACT_FLOAT;
+ _GUARD_BOTH_FLOAT + unused/1 + _BINARY_OP_SUBTRACT_FLOAT;
op(_GUARD_BOTH_UNICODE, (left, right -- left, right)) {
DEOPT_IF(!PyUnicode_CheckExact(left));
DEOPT_IF(!PyUnicode_CheckExact(right));
}
- op(_BINARY_OP_ADD_UNICODE, (unused/1, left, right -- res)) {
+ op(_BINARY_OP_ADD_UNICODE, (left, right -- res)) {
STAT_INC(BINARY_OP, hit);
res = PyUnicode_Concat(left, right);
_Py_DECREF_SPECIALIZED(left, _PyUnicode_ExactDealloc);
@@ -497,7 +497,7 @@ dummy_func(
}
macro(BINARY_OP_ADD_UNICODE) =
- _GUARD_BOTH_UNICODE + _BINARY_OP_ADD_UNICODE;
+ _GUARD_BOTH_UNICODE + unused/1 + _BINARY_OP_ADD_UNICODE;
// This is a subtle one. It's a super-instruction for
// BINARY_OP_ADD_UNICODE followed by STORE_FAST
@@ -505,7 +505,7 @@ dummy_func(
// So the inputs are the same as for all BINARY_OP
// specializations, but there is no output.
// At the end we just skip over the STORE_FAST.
- op(_BINARY_OP_INPLACE_ADD_UNICODE, (unused/1, left, right --)) {
+ op(_BINARY_OP_INPLACE_ADD_UNICODE, (left, right --)) {
TIER_ONE_ONLY
assert(next_instr->op.code == STORE_FAST);
PyObject **target_local = &GETLOCAL(next_instr->op.arg);
@@ -533,7 +533,7 @@ dummy_func(
}
macro(BINARY_OP_INPLACE_ADD_UNICODE) =
- _GUARD_BOTH_UNICODE + _BINARY_OP_INPLACE_ADD_UNICODE;
+ _GUARD_BOTH_UNICODE + unused/1 + _BINARY_OP_INPLACE_ADD_UNICODE;
family(BINARY_SUBSCR, INLINE_CACHE_ENTRIES_BINARY_SUBSCR) = {
BINARY_SUBSCR_DICT,
@@ -1295,14 +1295,14 @@ dummy_func(
#endif /* ENABLE_SPECIALIZATION */
}
- op(_STORE_ATTR, (unused/3, v, owner --)) {
+ op(_STORE_ATTR, (v, owner --)) {
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
int err = PyObject_SetAttr(owner, name, v);
DECREF_INPUTS();
ERROR_IF(err, error);
}
- macro(STORE_ATTR) = _SPECIALIZE_STORE_ATTR + _STORE_ATTR;
+ macro(STORE_ATTR) = _SPECIALIZE_STORE_ATTR + unused/3 + _STORE_ATTR;
inst(DELETE_ATTR, (owner --)) {
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
@@ -1414,7 +1414,7 @@ dummy_func(
#endif /* ENABLE_SPECIALIZATION */
}
- op(_LOAD_GLOBAL, (unused/1, unused/1, unused/1 -- res, null if (oparg & 1))) {
+ op(_LOAD_GLOBAL, ( -- res, null if (oparg & 1))) {
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
if (PyDict_CheckExact(GLOBALS())
&& PyDict_CheckExact(BUILTINS()))
@@ -1451,7 +1451,12 @@ dummy_func(
null = NULL;
}
- macro(LOAD_GLOBAL) = _SPECIALIZE_LOAD_GLOBAL + _LOAD_GLOBAL;
+ macro(LOAD_GLOBAL) =
+ _SPECIALIZE_LOAD_GLOBAL +
+ counter/1 +
+ globals_version/1 +
+ builtins_version/1 +
+ _LOAD_GLOBAL;
op(_GUARD_GLOBALS_VERSION, (version/1 --)) {
PyDictObject *dict = (PyDictObject *)GLOBALS();
@@ -1853,7 +1858,7 @@ dummy_func(
#endif /* ENABLE_SPECIALIZATION */
}
- op(_LOAD_ATTR, (unused/8, owner -- attr, self_or_null if (oparg & 1))) {
+ op(_LOAD_ATTR, (owner -- attr, self_or_null if (oparg & 1))) {
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1);
if (oparg & 1) {
/* Designed to work in tandem with CALL, pushes two values. */
@@ -1886,7 +1891,10 @@ dummy_func(
}
}
- macro(LOAD_ATTR) = _SPECIALIZE_LOAD_ATTR + _LOAD_ATTR;
+ macro(LOAD_ATTR) =
+ _SPECIALIZE_LOAD_ATTR +
+ unused/8 +
+ _LOAD_ATTR;
pseudo(LOAD_METHOD) = {
LOAD_ATTR,
@@ -2369,7 +2377,7 @@ dummy_func(
stack_pointer = _PyFrame_GetStackPointer(frame);
}
- replaced op(_POP_JUMP_IF_FALSE, (unused/1, cond -- )) {
+ replaced op(_POP_JUMP_IF_FALSE, (cond -- )) {
assert(PyBool_Check(cond));
int flag = Py_IsFalse(cond);
#if ENABLE_SPECIALIZATION
@@ -2378,7 +2386,7 @@ dummy_func(
JUMPBY(oparg * flag);
}
- replaced op(_POP_JUMP_IF_TRUE, (unused/1, cond -- )) {
+ replaced op(_POP_JUMP_IF_TRUE, (cond -- )) {
assert(PyBool_Check(cond));
int flag = Py_IsTrue(cond);
#if ENABLE_SPECIALIZATION
@@ -2397,13 +2405,13 @@ dummy_func(
}
}
- macro(POP_JUMP_IF_TRUE) = _POP_JUMP_IF_TRUE;
+ macro(POP_JUMP_IF_TRUE) = unused/1 + _POP_JUMP_IF_TRUE;
- macro(POP_JUMP_IF_FALSE) = _POP_JUMP_IF_FALSE;
+ macro(POP_JUMP_IF_FALSE) = unused/1 + _POP_JUMP_IF_FALSE;
- macro(POP_JUMP_IF_NONE) = _IS_NONE + _POP_JUMP_IF_TRUE;
+ macro(POP_JUMP_IF_NONE) = unused/1 + _IS_NONE + _POP_JUMP_IF_TRUE;
- macro(POP_JUMP_IF_NOT_NONE) = _IS_NONE + _POP_JUMP_IF_FALSE;
+ macro(POP_JUMP_IF_NOT_NONE) = unused/1 + _IS_NONE + _POP_JUMP_IF_FALSE;
inst(JUMP_BACKWARD_NO_INTERRUPT, (--)) {
TIER_ONE_ONLY
@@ -3010,7 +3018,7 @@ dummy_func(
}
// When calling Python, inline the call using DISPATCH_INLINED().
- op(_CALL, (unused/2, callable, self_or_null, args[oparg] -- res)) {
+ op(_CALL, (callable, self_or_null, args[oparg] -- res)) {
// oparg counts all of the args, but *not* self:
int total_args = oparg;
if (self_or_null != NULL) {
@@ -3079,7 +3087,7 @@ dummy_func(
CHECK_EVAL_BREAKER();
}
- macro(CALL) = _SPECIALIZE_CALL + _CALL;
+ macro(CALL) = _SPECIALIZE_CALL + unused/2 + _CALL;
op(_CHECK_CALL_BOUND_METHOD_EXACT_ARGS, (callable, null, unused[oparg] -- callable, null, unused[oparg])) {
DEOPT_IF(null != NULL);
diff --git a/Python/ceval.c b/Python/ceval.c
index 27304d31e27..1fea9747488 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -24,6 +24,7 @@
#include "pycore_sysmodule.h" // _PySys_Audit()
#include "pycore_tuple.h" // _PyTuple_ITEMS()
#include "pycore_typeobject.h" // _PySuper_Lookup()
+#include "pycore_uop_ids.h" // Uops
#include "pycore_uops.h" // _PyUOpExecutorObject
#include "pycore_pyerrors.h"
diff --git a/Python/compile.c b/Python/compile.c
index 8b9e2f02048..65ac05ad58d 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -796,35 +796,12 @@ stack_effect(int opcode, int oparg, int jump)
// Specialized instructions are not supported.
return PY_INVALID_STACK_EFFECT;
}
- int popped, pushed;
- if (jump > 0) {
- popped = _PyOpcode_num_popped(opcode, oparg, true);
- pushed = _PyOpcode_num_pushed(opcode, oparg, true);
- }
- else {
- popped = _PyOpcode_num_popped(opcode, oparg, false);
- pushed = _PyOpcode_num_pushed(opcode, oparg, false);
- }
+ int popped = _PyOpcode_num_popped(opcode, oparg);
+ int pushed = _PyOpcode_num_pushed(opcode, oparg);
if (popped < 0 || pushed < 0) {
return PY_INVALID_STACK_EFFECT;
}
- if (jump >= 0) {
- return pushed - popped;
- }
- if (jump < 0) {
- // Compute max(pushed - popped, alt_pushed - alt_popped)
- int alt_popped = _PyOpcode_num_popped(opcode, oparg, true);
- int alt_pushed = _PyOpcode_num_pushed(opcode, oparg, true);
- if (alt_popped < 0 || alt_pushed < 0) {
- return PY_INVALID_STACK_EFFECT;
- }
- int diff = pushed - popped;
- int alt_diff = alt_pushed - alt_popped;
- if (alt_diff > diff) {
- return alt_diff;
- }
- return diff;
- }
+ return pushed - popped;
}
// Pseudo ops
@@ -1125,7 +1102,7 @@ compiler_addop_name(struct compiler_unit *u, location loc,
arg <<= 1;
}
if (opcode == LOAD_METHOD) {
- assert(SAME_OPCODE_METADATA(LOAD_METHOD, LOAD_ATTR));
+ assert(is_pseudo_target(LOAD_METHOD, LOAD_ATTR));
opcode = LOAD_ATTR;
arg <<= 1;
arg |= 1;
@@ -1135,18 +1112,18 @@ compiler_addop_name(struct compiler_unit *u, location loc,
arg |= 2;
}
if (opcode == LOAD_SUPER_METHOD) {
- assert(SAME_OPCODE_METADATA(LOAD_SUPER_METHOD, LOAD_SUPER_ATTR));
+ assert(is_pseudo_target(LOAD_SUPER_METHOD, LOAD_SUPER_ATTR));
opcode = LOAD_SUPER_ATTR;
arg <<= 2;
arg |= 3;
}
if (opcode == LOAD_ZERO_SUPER_ATTR) {
- assert(SAME_OPCODE_METADATA(LOAD_ZERO_SUPER_ATTR, LOAD_SUPER_ATTR));
+ assert(is_pseudo_target(LOAD_ZERO_SUPER_ATTR, LOAD_SUPER_ATTR));
opcode = LOAD_SUPER_ATTR;
arg <<= 2;
}
if (opcode == LOAD_ZERO_SUPER_METHOD) {
- assert(SAME_OPCODE_METADATA(LOAD_ZERO_SUPER_METHOD, LOAD_SUPER_ATTR));
+ assert(is_pseudo_target(LOAD_ZERO_SUPER_METHOD, LOAD_SUPER_ATTR));
opcode = LOAD_SUPER_ATTR;
arg <<= 2;
arg |= 1;
diff --git a/Python/flowgraph.c b/Python/flowgraph.c
index d2e3a7ae441..e6c824a85ef 100644
--- a/Python/flowgraph.c
+++ b/Python/flowgraph.c
@@ -2258,11 +2258,11 @@ convert_pseudo_ops(basicblock *entryblock)
INSTR_SET_OP0(instr, NOP);
}
else if (instr->i_opcode == LOAD_CLOSURE) {
- assert(SAME_OPCODE_METADATA(LOAD_CLOSURE, LOAD_FAST));
+ assert(is_pseudo_target(LOAD_CLOSURE, LOAD_FAST));
instr->i_opcode = LOAD_FAST;
}
else if (instr->i_opcode == STORE_FAST_MAYBE_NULL) {
- assert(SAME_OPCODE_METADATA(STORE_FAST_MAYBE_NULL, STORE_FAST));
+ assert(is_pseudo_target(STORE_FAST_MAYBE_NULL, STORE_FAST));
instr->i_opcode = STORE_FAST;
}
}
diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h
index a274427a699..e935f33fa21 100644
--- a/Python/generated_cases.c.h
+++ b/Python/generated_cases.c.h
@@ -153,6 +153,7 @@
DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP);
DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP);
}
+ /* Skip 1 cache entry */
// _BINARY_OP_ADD_FLOAT
{
STAT_INC(BINARY_OP, hit);
@@ -181,6 +182,7 @@
DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP);
DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP);
}
+ /* Skip 1 cache entry */
// _BINARY_OP_ADD_INT
{
STAT_INC(BINARY_OP, hit);
@@ -209,6 +211,7 @@
DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP);
DEOPT_IF(!PyUnicode_CheckExact(right), BINARY_OP);
}
+ /* Skip 1 cache entry */
// _BINARY_OP_ADD_UNICODE
{
STAT_INC(BINARY_OP, hit);
@@ -236,6 +239,7 @@
DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP);
DEOPT_IF(!PyUnicode_CheckExact(right), BINARY_OP);
}
+ /* Skip 1 cache entry */
// _BINARY_OP_INPLACE_ADD_UNICODE
{
TIER_ONE_ONLY
@@ -282,6 +286,7 @@
DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP);
DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP);
}
+ /* Skip 1 cache entry */
// _BINARY_OP_MULTIPLY_FLOAT
{
STAT_INC(BINARY_OP, hit);
@@ -310,6 +315,7 @@
DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP);
DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP);
}
+ /* Skip 1 cache entry */
// _BINARY_OP_MULTIPLY_INT
{
STAT_INC(BINARY_OP, hit);
@@ -338,6 +344,7 @@
DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP);
DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP);
}
+ /* Skip 1 cache entry */
// _BINARY_OP_SUBTRACT_FLOAT
{
STAT_INC(BINARY_OP, hit);
@@ -366,6 +373,7 @@
DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP);
DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP);
}
+ /* Skip 1 cache entry */
// _BINARY_OP_SUBTRACT_INT
{
STAT_INC(BINARY_OP, hit);
@@ -763,6 +771,7 @@
DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
}
+ /* Skip 2 cache entries */
// _CALL
{
// oparg counts all of the args, but *not* self:
@@ -3400,6 +3409,7 @@
DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
}
+ /* Skip 8 cache entries */
// _LOAD_ATTR
{
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1);
@@ -4096,6 +4106,9 @@
DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
}
+ /* Skip 1 cache entry */
+ /* Skip 1 cache entry */
+ /* Skip 1 cache entry */
// _LOAD_GLOBAL
{
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
@@ -4564,6 +4577,7 @@
next_instr += 2;
INSTRUCTION_STATS(POP_JUMP_IF_FALSE);
PyObject *cond;
+ /* Skip 1 cache entry */
cond = stack_pointer[-1];
assert(PyBool_Check(cond));
int flag = Py_IsFalse(cond);
@@ -4582,6 +4596,7 @@
PyObject *value;
PyObject *b;
PyObject *cond;
+ /* Skip 1 cache entry */
// _IS_NONE
value = stack_pointer[-1];
{
@@ -4614,6 +4629,7 @@
PyObject *value;
PyObject *b;
PyObject *cond;
+ /* Skip 1 cache entry */
// _IS_NONE
value = stack_pointer[-1];
{
@@ -4644,6 +4660,7 @@
next_instr += 2;
INSTRUCTION_STATS(POP_JUMP_IF_TRUE);
PyObject *cond;
+ /* Skip 1 cache entry */
cond = stack_pointer[-1];
assert(PyBool_Check(cond));
int flag = Py_IsTrue(cond);
@@ -5117,6 +5134,7 @@
DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
}
+ /* Skip 3 cache entries */
// _STORE_ATTR
v = stack_pointer[-2];
{
@@ -5509,6 +5527,7 @@
DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
}
+ /* Skip 2 cache entries */
// _TO_BOOL
{
int err = PyObject_IsTrue(value);
diff --git a/Python/optimizer.c b/Python/optimizer.c
index d44e733bc34..0ff16191680 100644
--- a/Python/optimizer.c
+++ b/Python/optimizer.c
@@ -6,14 +6,20 @@
#include "pycore_opcode_utils.h" // MAX_REAL_OPCODE
#include "pycore_optimizer.h" // _Py_uop_analyze_and_optimize()
#include "pycore_pystate.h" // _PyInterpreterState_GET()
+#include "pycore_uop_ids.h"
#include "pycore_uops.h"
#include "cpython/optimizer.h"
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
+#define NEED_OPCODE_METADATA
+#include "pycore_uop_metadata.h" // Uop tables
+#undef NEED_OPCODE_METADATA
+
#define MAX_EXECUTORS_SIZE 256
+
static bool
has_space_for_executor(PyCodeObject *code, _Py_CODEUNIT *instr)
{
@@ -327,9 +333,6 @@ uop_dealloc(_PyUOpExecutorObject *self) {
const char *
_PyUOpName(int index)
{
- if (index <= MAX_REAL_OPCODE) {
- return _PyOpcode_OpName[index];
- }
return _PyOpcode_uop_name[index];
}
@@ -388,7 +391,7 @@ PyTypeObject _PyUOpExecutor_Type = {
/* TO DO -- Generate these tables */
static const uint16_t
-_PyUOp_Replacements[OPCODE_METADATA_SIZE] = {
+_PyUOp_Replacements[MAX_UOP_ID + 1] = {
[_ITER_JUMP_RANGE] = _GUARD_NOT_EXHAUSTED_RANGE,
[_ITER_JUMP_LIST] = _GUARD_NOT_EXHAUSTED_LIST,
[_ITER_JUMP_TUPLE] = _GUARD_NOT_EXHAUSTED_TUPLE,
@@ -629,14 +632,6 @@ top: // Jump here after _PUSH_FRAME or likely branches
oparg += extras;
}
}
- if (_PyUOp_Replacements[uop]) {
- uop = _PyUOp_Replacements[uop];
- if (uop == _FOR_ITER_TIER_TWO) {
- target += 1 + INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1;
- assert(_PyCode_CODE(code)[target-1].op.code == END_FOR ||
- _PyCode_CODE(code)[target-1].op.code == INSTRUMENTED_END_FOR);
- }
- }
break;
case OPARG_CACHE_1:
operand = read_u16(&instr[offset].cache);
@@ -657,7 +652,15 @@ top: // Jump here after _PUSH_FRAME or likely branches
oparg = offset;
assert(uop == _SAVE_RETURN_OFFSET);
break;
-
+ case OPARG_REPLACED:
+ uop = _PyUOp_Replacements[uop];
+ assert(uop != 0);
+ if (uop == _FOR_ITER_TIER_TWO) {
+ target += 1 + INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1;
+ assert(_PyCode_CODE(code)[target-1].op.code == END_FOR ||
+ _PyCode_CODE(code)[target-1].op.code == INSTRUMENTED_END_FOR);
+ }
+ break;
default:
fprintf(stderr,
"opcode=%d, oparg=%d; nuops=%d, i=%d; size=%d, offset=%d\n",
@@ -799,7 +802,8 @@ compute_used(_PyUOpInstruction *buffer, uint32_t *used)
}
/* All other micro-ops fall through, so i+1 is reachable */
SET_BIT(used, i+1);
- if (OPCODE_HAS_JUMP(opcode)) {
+ assert(opcode <= MAX_UOP_ID);
+ if (_PyUop_Flags[opcode] & HAS_JUMP_FLAG) {
/* Mark target as reachable */
SET_BIT(used, buffer[i].oparg);
}
diff --git a/Python/specialize.c b/Python/specialize.c
index 7c2a4a42b1d..369b962a545 100644
--- a/Python/specialize.c
+++ b/Python/specialize.c
@@ -10,6 +10,7 @@
#include "pycore_moduleobject.h"
#include "pycore_object.h"
#include "pycore_opcode_metadata.h" // _PyOpcode_Caches
+#include "pycore_uop_metadata.h" // _PyOpcode_uop_name
#include "pycore_opcode_utils.h" // RESUME_AT_FUNC_START
#include "pycore_pylifecycle.h" // _PyOS_URandomNonblock()
#include "pycore_runtime.h" // _Py_ID()