Skip to content

Commit 30e6cbd

Browse files
authored
GH-113860: Get rid of _PyUOpExecutorObject (GH-113954)
1 parent 29e2839 commit 30e6cbd

File tree

12 files changed

+35
-67
lines changed

12 files changed

+35
-67
lines changed

Include/cpython/optimizer.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,17 @@ typedef struct {
2929
_PyExecutorLinkListNode links;
3030
} _PyVMData;
3131

32+
typedef struct {
33+
uint16_t opcode;
34+
uint16_t oparg;
35+
uint32_t target;
36+
uint64_t operand; // A cache entry
37+
} _PyUOpInstruction;
38+
3239
typedef struct _PyExecutorObject {
3340
PyObject_VAR_HEAD
3441
_PyVMData vm_data; /* Used by the VM, but opaque to the optimizer */
35-
/* Data needed by the executor goes here, but is opaque to the VM */
42+
_PyUOpInstruction trace[1];
3643
} _PyExecutorObject;
3744

3845
typedef struct _PyOptimizerObject _PyOptimizerObject;

Include/internal/pycore_optimizer.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ extern "C" {
88
# error "this header requires Py_BUILD_CORE define"
99
#endif
1010

11-
#include "pycore_uops.h" // _PyUOpInstruction
12-
1311
int _Py_uop_analyze_and_optimize(PyCodeObject *code,
1412
_PyUOpInstruction *trace, int trace_len, int curr_stackentries);
1513

Include/internal/pycore_uops.h

Lines changed: 0 additions & 30 deletions
This file was deleted.

Makefile.pre.in

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1895,7 +1895,6 @@ PYTHON_HEADERS= \
18951895
$(srcdir)/Include/internal/pycore_unionobject.h \
18961896
$(srcdir)/Include/internal/pycore_unicodeobject.h \
18971897
$(srcdir)/Include/internal/pycore_unicodeobject_generated.h \
1898-
$(srcdir)/Include/internal/pycore_uops.h \
18991898
$(srcdir)/Include/internal/pycore_uop_metadata.h \
19001899
$(srcdir)/Include/internal/pycore_warnings.h \
19011900
$(srcdir)/Include/internal/pycore_weakref.h \

PCbuild/pythoncore.vcxproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,6 @@
295295
<ClInclude Include="..\Include\internal\pycore_unionobject.h" />
296296
<ClInclude Include="..\Include\internal\pycore_unicodeobject.h" />
297297
<ClInclude Include="..\Include\internal\pycore_unicodeobject_generated.h" />
298-
<ClInclude Include="..\Include\internal\pycore_uops.h" />
299298
<ClInclude Include="..\Include\internal\pycore_warnings.h" />
300299
<ClInclude Include="..\Include\internal\pycore_weakref.h" />
301300
<ClInclude Include="..\Include\interpreteridobject.h" />

PCbuild/pythoncore.vcxproj.filters

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -804,9 +804,6 @@
804804
<ClInclude Include="..\Include\internal\pycore_unionobject.h">
805805
<Filter>Include\internal</Filter>
806806
</ClInclude>
807-
<ClInclude Include="..\Include\internal\pycore_uops.h">
808-
<Filter>Include\internal</Filter>
809-
</ClInclude>
810807
<ClInclude Include="..\Include\internal\mimalloc\mimalloc.h">
811808
<Filter>Include\internal\mimalloc</Filter>
812809
</ClInclude>

Python/bytecodes.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ static size_t jump;
6868
static uint16_t invert, counter, index, hint;
6969
#define unused 0 // Used in a macro def, can't be static
7070
static uint32_t type_version;
71-
static _PyUOpExecutorObject *current_executor;
71+
static _PyExecutorObject *current_executor;
7272

7373
static PyObject *
7474
dummy_func(
@@ -2369,10 +2369,10 @@ dummy_func(
23692369
CHECK_EVAL_BREAKER();
23702370

23712371
PyCodeObject *code = _PyFrame_GetCode(frame);
2372-
_PyExecutorObject *executor = (_PyExecutorObject *)code->co_executors->executors[oparg&255];
2372+
_PyExecutorObject *executor = code->co_executors->executors[oparg & 255];
23732373
if (executor->vm_data.valid) {
23742374
Py_INCREF(executor);
2375-
current_executor = (_PyUOpExecutorObject *)executor;
2375+
current_executor = executor;
23762376
GOTO_TIER_TWO();
23772377
}
23782378
else {
@@ -4063,7 +4063,7 @@ dummy_func(
40634063

40644064
op(_CHECK_VALIDITY, (--)) {
40654065
TIER_TWO_ONLY
4066-
DEOPT_IF(!current_executor->base.vm_data.valid);
4066+
DEOPT_IF(!current_executor->vm_data.valid);
40674067
}
40684068

40694069
op(_LOAD_CONST_INLINE_BORROW, (ptr/4 -- value)) {

Python/ceval.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
#include "pycore_tuple.h" // _PyTuple_ITEMS()
2626
#include "pycore_typeobject.h" // _PySuper_Lookup()
2727
#include "pycore_uop_ids.h" // Uops
28-
#include "pycore_uops.h" // _PyUOpExecutorObject
2928
#include "pycore_pyerrors.h"
3029

3130
#include "pycore_dict.h"
@@ -739,7 +738,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
739738
}
740739

741740
/* State shared between Tier 1 and Tier 2 interpreter */
742-
_PyUOpExecutorObject *current_executor = NULL;
741+
_PyExecutorObject *current_executor = NULL;
743742

744743
/* Local "register" variables.
745744
* These are cached values from the frame and code object. */

Python/executor_cases.c.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/generated_cases.c.h

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

Python/optimizer.c

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
#include "pycore_optimizer.h" // _Py_uop_analyze_and_optimize()
88
#include "pycore_pystate.h" // _PyInterpreterState_GET()
99
#include "pycore_uop_ids.h"
10-
#include "pycore_uops.h"
1110
#include "cpython/optimizer.h"
1211
#include <stdbool.h>
1312
#include <stdint.h>
@@ -17,6 +16,8 @@
1716
#include "pycore_uop_metadata.h" // Uop tables
1817
#undef NEED_OPCODE_METADATA
1918

19+
#define UOP_MAX_TRACE_LENGTH 512
20+
2021
#define MAX_EXECUTORS_SIZE 256
2122

2223

@@ -224,8 +225,8 @@ static PyMethodDef executor_methods[] = {
224225
///////////////////// Experimental UOp Optimizer /////////////////////
225226

226227
static void
227-
uop_dealloc(_PyUOpExecutorObject *self) {
228-
_Py_ExecutorClear((_PyExecutorObject *)self);
228+
uop_dealloc(_PyExecutorObject *self) {
229+
_Py_ExecutorClear(self);
229230
PyObject_Free(self);
230231
}
231232

@@ -236,13 +237,13 @@ _PyUOpName(int index)
236237
}
237238

238239
static Py_ssize_t
239-
uop_len(_PyUOpExecutorObject *self)
240+
uop_len(_PyExecutorObject *self)
240241
{
241242
return Py_SIZE(self);
242243
}
243244

244245
static PyObject *
245-
uop_item(_PyUOpExecutorObject *self, Py_ssize_t index)
246+
uop_item(_PyExecutorObject *self, Py_ssize_t index)
246247
{
247248
Py_ssize_t len = uop_len(self);
248249
if (index < 0 || index >= len) {
@@ -280,7 +281,7 @@ PySequenceMethods uop_as_sequence = {
280281
PyTypeObject _PyUOpExecutor_Type = {
281282
PyVarObject_HEAD_INIT(&PyType_Type, 0)
282283
.tp_name = "uop_executor",
283-
.tp_basicsize = offsetof(_PyUOpExecutorObject, trace),
284+
.tp_basicsize = offsetof(_PyExecutorObject, trace),
284285
.tp_itemsize = sizeof(_PyUOpInstruction),
285286
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
286287
.tp_dealloc = (destructor)uop_dealloc,
@@ -423,8 +424,7 @@ translate_bytecode_to_trace(
423424

424425
if (opcode == ENTER_EXECUTOR) {
425426
assert(oparg < 256);
426-
_PyExecutorObject *executor =
427-
(_PyExecutorObject *)code->co_executors->executors[oparg];
427+
_PyExecutorObject *executor = code->co_executors->executors[oparg];
428428
opcode = executor->vm_data.opcode;
429429
DPRINTF(2, " * ENTER_EXECUTOR -> %s\n", _PyOpcode_OpName[opcode]);
430430
oparg = executor->vm_data.oparg;
@@ -704,7 +704,7 @@ compute_used(_PyUOpInstruction *buffer, uint32_t *used)
704704
{
705705
int count = 0;
706706
SET_BIT(used, 0);
707-
for (int i = 0; i < _Py_UOP_MAX_TRACE_LENGTH; i++) {
707+
for (int i = 0; i < UOP_MAX_TRACE_LENGTH; i++) {
708708
if (!BIT_IS_SET(used, i)) {
709709
continue;
710710
}
@@ -736,15 +736,15 @@ compute_used(_PyUOpInstruction *buffer, uint32_t *used)
736736
static _PyExecutorObject *
737737
make_executor_from_uops(_PyUOpInstruction *buffer, _PyBloomFilter *dependencies)
738738
{
739-
uint32_t used[(_Py_UOP_MAX_TRACE_LENGTH + 31)/32] = { 0 };
739+
uint32_t used[(UOP_MAX_TRACE_LENGTH + 31)/32] = { 0 };
740740
int length = compute_used(buffer, used);
741-
_PyUOpExecutorObject *executor = PyObject_NewVar(_PyUOpExecutorObject, &_PyUOpExecutor_Type, length);
741+
_PyExecutorObject *executor = PyObject_NewVar(_PyExecutorObject, &_PyUOpExecutor_Type, length);
742742
if (executor == NULL) {
743743
return NULL;
744744
}
745745
int dest = length - 1;
746746
/* Scan backwards, so that we see the destinations of jumps before the jumps themselves. */
747-
for (int i = _Py_UOP_MAX_TRACE_LENGTH-1; i >= 0; i--) {
747+
for (int i = UOP_MAX_TRACE_LENGTH-1; i >= 0; i--) {
748748
if (!BIT_IS_SET(used, i)) {
749749
continue;
750750
}
@@ -763,7 +763,7 @@ make_executor_from_uops(_PyUOpInstruction *buffer, _PyBloomFilter *dependencies)
763763
dest--;
764764
}
765765
assert(dest == -1);
766-
_Py_ExecutorInit((_PyExecutorObject *)executor, dependencies);
766+
_Py_ExecutorInit(executor, dependencies);
767767
#ifdef Py_DEBUG
768768
char *python_lltrace = Py_GETENV("PYTHON_LLTRACE");
769769
int lltrace = 0;
@@ -782,7 +782,7 @@ make_executor_from_uops(_PyUOpInstruction *buffer, _PyBloomFilter *dependencies)
782782
}
783783
}
784784
#endif
785-
return (_PyExecutorObject *)executor;
785+
return executor;
786786
}
787787

788788
static int
@@ -795,16 +795,16 @@ uop_optimize(
795795
{
796796
_PyBloomFilter dependencies;
797797
_Py_BloomFilter_Init(&dependencies);
798-
_PyUOpInstruction buffer[_Py_UOP_MAX_TRACE_LENGTH];
799-
int err = translate_bytecode_to_trace(code, instr, buffer, _Py_UOP_MAX_TRACE_LENGTH, &dependencies);
798+
_PyUOpInstruction buffer[UOP_MAX_TRACE_LENGTH];
799+
int err = translate_bytecode_to_trace(code, instr, buffer, UOP_MAX_TRACE_LENGTH, &dependencies);
800800
if (err <= 0) {
801801
// Error or nothing translated
802802
return err;
803803
}
804804
OPT_STAT_INC(traces_created);
805805
char *uop_optimize = Py_GETENV("PYTHONUOPSOPTIMIZE");
806806
if (uop_optimize == NULL || *uop_optimize > '0') {
807-
err = _Py_uop_analyze_and_optimize(code, buffer, _Py_UOP_MAX_TRACE_LENGTH, curr_stackentries);
807+
err = _Py_uop_analyze_and_optimize(code, buffer, UOP_MAX_TRACE_LENGTH, curr_stackentries);
808808
if (err < 0) {
809809
return -1;
810810
}
@@ -848,7 +848,7 @@ PyUnstable_Optimizer_NewUOpOptimizer(void)
848848
}
849849

850850
static void
851-
counter_dealloc(_PyUOpExecutorObject *self) {
851+
counter_dealloc(_PyExecutorObject *self) {
852852
PyObject *opt = (PyObject *)self->trace[0].operand;
853853
Py_DECREF(opt);
854854
uop_dealloc(self);
@@ -857,7 +857,7 @@ counter_dealloc(_PyUOpExecutorObject *self) {
857857
PyTypeObject _PyCounterExecutor_Type = {
858858
PyVarObject_HEAD_INIT(&PyType_Type, 0)
859859
.tp_name = "counting_executor",
860-
.tp_basicsize = offsetof(_PyUOpExecutorObject, trace),
860+
.tp_basicsize = offsetof(_PyExecutorObject, trace),
861861
.tp_itemsize = sizeof(_PyUOpInstruction),
862862
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
863863
.tp_dealloc = (destructor)counter_dealloc,

Python/optimizer_analysis.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
#include "pycore_opcode_utils.h"
66
#include "pycore_pystate.h" // _PyInterpreterState_GET()
77
#include "pycore_uop_metadata.h"
8-
#include "pycore_uops.h"
98
#include "pycore_long.h"
109
#include "cpython/optimizer.h"
1110
#include <stdbool.h>

0 commit comments

Comments
 (0)