gh-101632: Add the new RETURN_CONST opcode (#101633)

This commit is contained in:
penguin_wwy 2023-02-08 06:32:21 +08:00 committed by GitHub
parent 0d3d5007b1
commit 753fc8a5d6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 186 additions and 154 deletions

View file

@ -555,6 +555,23 @@ dummy_func(
goto resume_frame;
}
inst(RETURN_CONST, (--)) {
PyObject *retval = GETITEM(consts, oparg);
Py_INCREF(retval);
assert(EMPTY());
_PyFrame_SetStackPointer(frame, stack_pointer);
TRACE_FUNCTION_EXIT();
DTRACE_FUNCTION_EXIT();
_Py_LeaveRecursiveCallPy(tstate);
assert(frame != &entry_frame);
// GH-99729: We need to unlink the frame *before* clearing it:
_PyInterpreterFrame *dying = frame;
frame = cframe.current_frame = dying->previous;
_PyEvalFrameClearAndPop(tstate, dying);
_PyFrame_StackPush(frame, retval);
goto resume_frame;
}
inst(GET_AITER, (obj -- iter)) {
unaryfunc getter = NULL;
PyTypeObject *type = Py_TYPE(obj);

View file

@ -124,6 +124,7 @@
#define IS_SCOPE_EXIT_OPCODE(opcode) \
((opcode) == RETURN_VALUE || \
(opcode) == RETURN_CONST || \
(opcode) == RAISE_VARARGS || \
(opcode) == RERAISE)
@ -354,7 +355,7 @@ basicblock_last_instr(const basicblock *b) {
static inline int
basicblock_returns(const basicblock *b) {
struct instr *last = basicblock_last_instr(b);
return last && last->i_opcode == RETURN_VALUE;
return last && (last->i_opcode == RETURN_VALUE || last->i_opcode == RETURN_CONST);
}
static inline int
@ -1119,6 +1120,8 @@ stack_effect(int opcode, int oparg, int jump)
case RETURN_VALUE:
return -1;
case RETURN_CONST:
return 0;
case SETUP_ANNOTATIONS:
return 0;
case YIELD_VALUE:
@ -9261,6 +9264,10 @@ optimize_basic_block(PyObject *const_cache, basicblock *bb, PyObject *consts)
}
Py_DECREF(cnt);
break;
case RETURN_VALUE:
INSTR_SET_OP1(inst, RETURN_CONST, oparg);
INSTR_SET_OP0(&bb->b_instr[i + 1], NOP);
break;
}
break;
}
@ -9723,9 +9730,7 @@ remove_unused_consts(basicblock *entryblock, PyObject *consts)
/* mark used consts */
for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
for (int i = 0; i < b->b_iused; i++) {
if (b->b_instr[i].i_opcode == LOAD_CONST ||
b->b_instr[i].i_opcode == KW_NAMES) {
if (HAS_CONST(b->b_instr[i].i_opcode)) {
int index = b->b_instr[i].i_oparg;
index_map[index] = index;
}
@ -9780,9 +9785,7 @@ remove_unused_consts(basicblock *entryblock, PyObject *consts)
for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
for (int i = 0; i < b->b_iused; i++) {
if (b->b_instr[i].i_opcode == LOAD_CONST ||
b->b_instr[i].i_opcode == KW_NAMES) {
if (HAS_CONST(b->b_instr[i].i_opcode)) {
int index = b->b_instr[i].i_oparg;
assert(reverse_index_map[index] >= 0);
assert(reverse_index_map[index] < n_used_consts);

View file

@ -742,6 +742,23 @@
goto resume_frame;
}
TARGET(RETURN_CONST) {
PyObject *retval = GETITEM(consts, oparg);
Py_INCREF(retval);
assert(EMPTY());
_PyFrame_SetStackPointer(frame, stack_pointer);
TRACE_FUNCTION_EXIT();
DTRACE_FUNCTION_EXIT();
_Py_LeaveRecursiveCallPy(tstate);
assert(frame != &entry_frame);
// GH-99729: We need to unlink the frame *before* clearing it:
_PyInterpreterFrame *dying = frame;
frame = cframe.current_frame = dying->previous;
_PyEvalFrameClearAndPop(tstate, dying);
_PyFrame_StackPush(frame, retval);
goto resume_frame;
}
TARGET(GET_AITER) {
PyObject *obj = PEEK(1);
PyObject *iter;

View file

@ -92,6 +92,8 @@ _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
return 1;
case RETURN_VALUE:
return 1;
case RETURN_CONST:
return 0;
case GET_AITER:
return 1;
case GET_ANEXT:
@ -438,6 +440,8 @@ _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
return 0;
case RETURN_VALUE:
return 0;
case RETURN_CONST:
return 0;
case GET_AITER:
return 1;
case GET_ANEXT:
@ -745,6 +749,7 @@ struct opcode_metadata {
[RAISE_VARARGS] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB },
[INTERPRETER_EXIT] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX },
[RETURN_VALUE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX },
[RETURN_CONST] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB },
[GET_AITER] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX },
[GET_ANEXT] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX },
[GET_AWAITABLE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB },

View file

@ -120,7 +120,7 @@ static void *opcode_targets[256] = {
&&TARGET_CONTAINS_OP,
&&TARGET_RERAISE,
&&TARGET_COPY,
&&TARGET_STORE_FAST__LOAD_FAST,
&&TARGET_RETURN_CONST,
&&TARGET_BINARY_OP,
&&TARGET_SEND,
&&TARGET_LOAD_FAST,
@ -142,7 +142,7 @@ static void *opcode_targets[256] = {
&&TARGET_JUMP_BACKWARD,
&&TARGET_COMPARE_AND_BRANCH,
&&TARGET_CALL_FUNCTION_EX,
&&TARGET_STORE_FAST__STORE_FAST,
&&TARGET_STORE_FAST__LOAD_FAST,
&&TARGET_EXTENDED_ARG,
&&TARGET_LIST_APPEND,
&&TARGET_SET_ADD,
@ -152,15 +152,15 @@ static void *opcode_targets[256] = {
&&TARGET_YIELD_VALUE,
&&TARGET_RESUME,
&&TARGET_MATCH_CLASS,
&&TARGET_STORE_FAST__STORE_FAST,
&&TARGET_STORE_SUBSCR_DICT,
&&TARGET_STORE_SUBSCR_LIST_INT,
&&TARGET_FORMAT_VALUE,
&&TARGET_BUILD_CONST_KEY_MAP,
&&TARGET_BUILD_STRING,
&&TARGET_STORE_SUBSCR_LIST_INT,
&&TARGET_UNPACK_SEQUENCE_LIST,
&&TARGET_UNPACK_SEQUENCE_TUPLE,
&&TARGET_UNPACK_SEQUENCE_TWO_TUPLE,
&&_unknown_opcode,
&&TARGET_LIST_EXTEND,
&&TARGET_SET_UPDATE,
&&TARGET_DICT_MERGE,