Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Change optimizer API to provide more information
  • Loading branch information
markshannon committed Jan 18, 2024
commit 3941620c1e2311303169b89a0c2b658516d3d27a
2 changes: 1 addition & 1 deletion Include/cpython/optimizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ typedef struct _PyExecutorObject {
typedef struct _PyOptimizerObject _PyOptimizerObject;

/* Should return > 0 if a new executor is created. O if no executor is produced and < 0 if an error occurred. */
typedef int (*optimize_func)(_PyOptimizerObject* self, PyCodeObject *code, _Py_CODEUNIT *instr, _PyExecutorObject **, int curr_stackentries);
typedef int (*optimize_func)(_PyOptimizerObject* self, struct _PyInterpreterFrame *frame, _Py_CODEUNIT *instr, _PyExecutorObject **, int curr_stackentries);
Comment thread
markshannon marked this conversation as resolved.
Resolved

typedef struct _PyOptimizerObject {
PyObject_HEAD
Expand Down
2 changes: 1 addition & 1 deletion Include/internal/pycore_optimizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif

int _Py_uop_analyze_and_optimize(PyCodeObject *code,
int _Py_uop_analyze_and_optimize(_PyInterpreterFrame *frame,
_PyUOpInstruction *trace, int trace_len, int curr_stackentries);

extern PyTypeObject _PyCounterExecutor_Type;
Expand Down
16 changes: 9 additions & 7 deletions Python/optimizer.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ PyUnstable_Replace_Executor(PyCodeObject *code, _Py_CODEUNIT *instr, _PyExecutor
static int
error_optimize(
_PyOptimizerObject* self,
PyCodeObject *code,
_PyInterpreterFrame *frame,
_Py_CODEUNIT *instr,
_PyExecutorObject **exec,
int Py_UNUSED(stack_entries))
Expand Down Expand Up @@ -173,7 +173,7 @@ _PyOptimizer_Optimize(_PyInterpreterFrame *frame, _Py_CODEUNIT *start, PyObject
}
_PyOptimizerObject *opt = interp->optimizer;
_PyExecutorObject *executor = NULL;
int err = opt->optimize(opt, code, start, &executor, (int)(stack_pointer - _PyFrame_Stackbase(frame)));
int err = opt->optimize(opt, frame, start, &executor, (int)(stack_pointer - _PyFrame_Stackbase(frame)));
if (err <= 0) {
assert(executor == NULL);
return err;
Expand Down Expand Up @@ -376,13 +376,14 @@ BRANCH_TO_GUARD[4][2] = {
*/
static int
translate_bytecode_to_trace(
PyCodeObject *code,
_PyInterpreterFrame *frame,
_Py_CODEUNIT *instr,
_PyUOpInstruction *trace,
int buffer_size,
_PyBloomFilter *dependencies)
{
bool progress_needed = true;
PyCodeObject *code = (PyCodeObject *)frame->f_executable;
PyCodeObject *initial_code = code;
_Py_BloomFilter_Add(dependencies, initial_code);
_Py_CODEUNIT *initial_instr = instr;
Expand Down Expand Up @@ -795,23 +796,23 @@ make_executor_from_uops(_PyUOpInstruction *buffer, _PyBloomFilter *dependencies)
static int
uop_optimize(
_PyOptimizerObject *self,
PyCodeObject *code,
_PyInterpreterFrame *frame,
_Py_CODEUNIT *instr,
_PyExecutorObject **exec_ptr,
int curr_stackentries)
{
_PyBloomFilter dependencies;
_Py_BloomFilter_Init(&dependencies);
_PyUOpInstruction buffer[UOP_MAX_TRACE_LENGTH];
int err = translate_bytecode_to_trace(code, instr, buffer, UOP_MAX_TRACE_LENGTH, &dependencies);
int err = translate_bytecode_to_trace(frame, instr, buffer, UOP_MAX_TRACE_LENGTH, &dependencies);
if (err <= 0) {
// Error or nothing translated
return err;
}
OPT_STAT_INC(traces_created);
char *uop_optimize = Py_GETENV("PYTHONUOPSOPTIMIZE");
if (uop_optimize == NULL || *uop_optimize > '0') {
err = _Py_uop_analyze_and_optimize(code, buffer, UOP_MAX_TRACE_LENGTH, curr_stackentries);
err = _Py_uop_analyze_and_optimize(frame, buffer, UOP_MAX_TRACE_LENGTH, curr_stackentries);
if (err < 0) {
return -1;
}
Expand Down Expand Up @@ -874,12 +875,13 @@ PyTypeObject _PyCounterExecutor_Type = {
static int
counter_optimize(
_PyOptimizerObject* self,
PyCodeObject *code,
_PyInterpreterFrame *frame,
_Py_CODEUNIT *instr,
_PyExecutorObject **exec_ptr,
int Py_UNUSED(curr_stackentries)
)
{
PyCodeObject *code = (PyCodeObject *)frame->f_executable;
int oparg = instr->op.arg;
while (instr->op.code == EXTENDED_ARG) {
instr++;
Expand Down
7 changes: 4 additions & 3 deletions Python/optimizer_analysis.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@
#include "pycore_optimizer.h"

static void
peephole_opt(PyCodeObject *co, _PyUOpInstruction *buffer, int buffer_size)
peephole_opt(_PyInterpreterFrame *frame, _PyUOpInstruction *buffer, int buffer_size)
{
PyCodeObject *co = (PyCodeObject *)frame->f_executable;
for (int pc = 0; pc < buffer_size; pc++) {
int opcode = buffer[pc].opcode;
switch(opcode) {
Expand Down Expand Up @@ -86,13 +87,13 @@ remove_unneeded_uops(_PyUOpInstruction *buffer, int buffer_size)

int
_Py_uop_analyze_and_optimize(
PyCodeObject *co,
_PyInterpreterFrame *frame,
_PyUOpInstruction *buffer,
int buffer_size,
int curr_stacklen
)
{
peephole_opt(co, buffer, buffer_size);
peephole_opt(frame, buffer, buffer_size);
remove_unneeded_uops(buffer, buffer_size);
return 0;
}