Skip to content

Commit 4c71c12

Browse files
committed
Get rid of LOAD_FAST__LOAD_ATTR_INSTANCE_VALUE
1 parent 097fdaf commit 4c71c12

File tree

5 files changed

+4
-89
lines changed

5 files changed

+4
-89
lines changed

Include/opcode.h

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/opcode.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,6 @@ def jabs_op(name, op, entries=0):
301301
"LOAD_FAST__LOAD_CONST",
302302
"LOAD_CONST__LOAD_FAST",
303303
"STORE_FAST__STORE_FAST",
304-
"LOAD_FAST__LOAD_ATTR_INSTANCE_VALUE",
305304
]
306305
_specialization_stats = [
307306
"success",

Python/ceval.c

Lines changed: 3 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -3458,33 +3458,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
34583458
}
34593459
}
34603460

3461-
TARGET(LOAD_FAST__LOAD_ATTR_INSTANCE_VALUE) {
3462-
assert(cframe.use_tracing == 0);
3463-
PyObject *owner = GETLOCAL(oparg); // borrowed
3464-
if (owner == NULL) {
3465-
goto unbound_local_error;
3466-
}
3467-
// GET_CACHE(), but for the following opcode
3468-
assert(_Py_OPCODE(*next_instr) == LOAD_ATTR_INSTANCE_VALUE);
3469-
_PyAttrCache *cache = (_PyAttrCache *)(next_instr + 1);
3470-
uint32_t type_version = read_u32(cache->version);
3471-
assert(type_version != 0);
3472-
PyTypeObject *tp = Py_TYPE(owner);
3473-
// These DEOPT_IF miss branches do PUSH(Py_NewRef(owner)).
3474-
DEOPT_IF(tp->tp_version_tag != type_version,
3475-
LOAD_FAST__LOAD_ATTR_INSTANCE_VALUE);
3476-
assert(tp->tp_dictoffset < 0);
3477-
assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT);
3478-
PyDictValues *values = *_PyObject_ValuesPointer(owner);
3479-
DEOPT_IF(values == NULL, LOAD_FAST__LOAD_ATTR_INSTANCE_VALUE);
3480-
PyObject *res = values->values[cache->index];
3481-
DEOPT_IF(res == NULL, LOAD_FAST__LOAD_ATTR_INSTANCE_VALUE);
3482-
STAT_INC(LOAD_ATTR, hit);
3483-
PUSH(Py_NewRef(res));
3484-
JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR + 1);
3485-
NOTRACE_DISPATCH();
3486-
}
3487-
34883461
TARGET(LOAD_ATTR_INSTANCE_VALUE) {
34893462
assert(cframe.use_tracing == 0);
34903463
PyObject *owner = TOP();
@@ -3493,14 +3466,13 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
34933466
_PyAttrCache *cache = (_PyAttrCache *)next_instr;
34943467
uint32_t type_version = read_u32(cache->version);
34953468
assert(type_version != 0);
3496-
DEOPT_IF(tp->tp_version_tag != type_version,
3497-
LOAD_ATTR_INSTANCE_VALUE);
3469+
DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR);
34983470
assert(tp->tp_dictoffset < 0);
34993471
assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT);
35003472
PyDictValues *values = *_PyObject_ValuesPointer(owner);
3501-
DEOPT_IF(values == NULL, LOAD_ATTR_INSTANCE_VALUE);
3473+
DEOPT_IF(values == NULL, LOAD_ATTR);
35023474
res = values->values[cache->index];
3503-
DEOPT_IF(res == NULL, LOAD_ATTR_INSTANCE_VALUE);
3475+
DEOPT_IF(res == NULL, LOAD_ATTR);
35043476
STAT_INC(LOAD_ATTR, hit);
35053477
Py_INCREF(res);
35063478
SET_TOP(res);
@@ -5640,51 +5612,6 @@ MISS_WITH_INLINE_CACHE(BINARY_SUBSCR)
56405612
MISS_WITH_INLINE_CACHE(UNPACK_SEQUENCE)
56415613
MISS_WITH_OPARG_COUNTER(STORE_SUBSCR)
56425614

5643-
LOAD_ATTR_INSTANCE_VALUE_miss:
5644-
{
5645-
// Special-cased so that if LOAD_ATTR_INSTANCE_VALUE
5646-
// gets replaced, then any preceeding
5647-
// LOAD_FAST__LOAD_ATTR_INSTANCE_VALUE gets replaced as well
5648-
STAT_INC(LOAD_ATTR_INSTANCE_VALUE, miss);
5649-
STAT_INC(LOAD_ATTR, miss);
5650-
_PyAttrCache *cache = (_PyAttrCache *)next_instr;
5651-
cache->counter--;
5652-
if (cache->counter == 0) {
5653-
next_instr[-1] = _Py_MAKECODEUNIT(LOAD_ATTR_ADAPTIVE, oparg);
5654-
if (_Py_OPCODE(next_instr[-2]) == LOAD_FAST__LOAD_ATTR_INSTANCE_VALUE) {
5655-
next_instr[-2] = _Py_MAKECODEUNIT(LOAD_FAST, _Py_OPARG(next_instr[-2]));
5656-
if (_Py_OPCODE(next_instr[-3]) == LOAD_FAST) {
5657-
next_instr[-3] = _Py_MAKECODEUNIT(LOAD_FAST__LOAD_FAST, _Py_OPARG(next_instr[-3]));
5658-
}
5659-
}
5660-
STAT_INC(LOAD_ATTR, deopt);
5661-
cache->counter = ADAPTIVE_CACHE_BACKOFF;
5662-
}
5663-
JUMP_TO_INSTRUCTION(LOAD_ATTR);
5664-
}
5665-
5666-
LOAD_FAST__LOAD_ATTR_INSTANCE_VALUE_miss:
5667-
{
5668-
// This is special-cased because we have a superinstruction
5669-
// that includes a specialized instruction.
5670-
// If the specialized portion misses, carry out
5671-
// the first instruction, then perform a miss
5672-
// for the second instruction as usual.
5673-
5674-
// Do LOAD_FAST
5675-
{
5676-
PyObject *value = GETLOCAL(oparg);
5677-
assert(value != NULL); // Already checked if unbound
5678-
Py_INCREF(value);
5679-
PUSH(value);
5680-
NEXTOPARG();
5681-
next_instr++;
5682-
}
5683-
5684-
// Now we are in the correct state for LOAD_ATTR
5685-
goto LOAD_ATTR_INSTANCE_VALUE_miss;
5686-
}
5687-
56885615
binary_subscr_dict_error:
56895616
{
56905617
PyObject *sub = POP();

Python/opcode_targets.h

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/specialize.c

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -891,16 +891,6 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name)
891891
return -1;
892892
}
893893
if (err) {
894-
if (_Py_OPCODE(instr[0]) == LOAD_ATTR_INSTANCE_VALUE) {
895-
// Note: instr[-1] exists because there's something on the stack,
896-
// and instr[-2] exists because there's at least a RESUME as well.
897-
if (_Py_OPCODE(instr[-1]) == LOAD_FAST) {
898-
instr[-1] = _Py_MAKECODEUNIT(LOAD_FAST__LOAD_ATTR_INSTANCE_VALUE, _Py_OPARG(instr[-1]));
899-
if (_Py_OPCODE(instr[-2]) == LOAD_FAST__LOAD_FAST) {
900-
instr[-2] = _Py_MAKECODEUNIT(LOAD_FAST, _Py_OPARG(instr[-2]));
901-
}
902-
}
903-
}
904894
goto success;
905895
}
906896
fail:

0 commit comments

Comments
 (0)