Skip to content
Open
Show file tree
Hide file tree
Changes from 63 commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
795ef49
Basic trace recording
Fidget-Spinner Sep 18, 2025
40bf6c1
WIP generators
Fidget-Spinner Sep 19, 2025
13188a9
refactor to translate on the go
Fidget-Spinner Sep 19, 2025
e63de39
working python startup
Fidget-Spinner Sep 19, 2025
fba9d2d
fix a bug with specializzation
Fidget-Spinner Sep 19, 2025
7192671
Fully working bm_generators
Fidget-Spinner Sep 20, 2025
07542dd
fix jit build
Fidget-Spinner Sep 20, 2025
021fc44
Fix exception tracing
Fidget-Spinner Sep 20, 2025
f886c43
Fix jump tracing
Fidget-Spinner Sep 20, 2025
3066963
Fix handling of ENTER_EXECUTOR
Fidget-Spinner Sep 20, 2025
20b283b
Fix ENTER_EXECUTOR bug
Fidget-Spinner Sep 21, 2025
36554a5
Fix over-tracing bug
Fidget-Spinner Sep 21, 2025
92bba64
fix JIT + debug builds
Fidget-Spinner Sep 21, 2025
2e3ddc1
Fix double-initialization
Fidget-Spinner Sep 21, 2025
aada168
fix exception bug
Fidget-Spinner Sep 21, 2025
7b5c655
Fix dispatch_inlined
Fidget-Spinner Sep 22, 2025
3e9f782
Fix handling of EXTENDED_ARG
Fidget-Spinner Sep 22, 2025
9a66605
Fix chain depth bug
Fidget-Spinner Sep 22, 2025
108ab7f
remove printf
Fidget-Spinner Sep 22, 2025
fac8c74
fix problem with jumping labels
Fidget-Spinner Sep 23, 2025
fd3bb48
Point to previous executor when side-exiting
Fidget-Spinner Sep 23, 2025
96b7bb2
Fix progress needed and warmup
Fidget-Spinner Sep 23, 2025
396818b
Fix unsupported opcode bug, turn off optimizer again
Fidget-Spinner Sep 24, 2025
57f417e
fix branch tracing
Fidget-Spinner Sep 24, 2025
2c603cc
fix branch prediction for real
Fidget-Spinner Sep 24, 2025
02f1fb4
fix non-sstandard C
Fidget-Spinner Sep 24, 2025
dc414a3
Track from JUMP_BACKWARD rather than FOR_ITER
Fidget-Spinner Sep 24, 2025
0ffc2dd
Fix bug where code/func get freed halfway
Fidget-Spinner Sep 24, 2025
2032b9c
add back replaced, move jit tracing env var to
Fidget-Spinner Oct 9, 2025
299a068
Handle recursive tracing and CALL_ALLOC_AND_ENTER_INIT
Fidget-Spinner Oct 9, 2025
8e0fb21
Fix recursive tracing and dynamic exits
Fidget-Spinner Oct 9, 2025
95eee89
Fix handling of EXTENDED_ARG
Fidget-Spinner Oct 9, 2025
6936a38
Just punt on large opargs for now
Fidget-Spinner Oct 16, 2025
a274451
cleanup a little
Fidget-Spinner Oct 16, 2025
f55129e
fix recursive tracing
Fidget-Spinner Oct 16, 2025
71bd27b
comment out debugging
Fidget-Spinner Oct 17, 2025
e834c88
Delete out.txt
Fidget-Spinner Oct 17, 2025
cae8f10
patch the graphviz dump
Fidget-Spinner Oct 17, 2025
39bc819
fix bug with predicted stuff
Fidget-Spinner Oct 17, 2025
ff92937
Properly record the predicted ops
Fidget-Spinner Oct 17, 2025
2589eb0
Re-enable the optimizer
Fidget-Spinner Oct 17, 2025
a2e92a6
Delete hello.gvz
Fidget-Spinner Oct 17, 2025
cbb3ad2
turn off optimizer again (for now)
Fidget-Spinner Oct 17, 2025
9910b65
Turn off optimizer for real, trace through init
Fidget-Spinner Oct 17, 2025
5102ab6
fix a few tests and their exposed bugs
Fidget-Spinner Oct 17, 2025
c0c14b4
Restore the optimizer fully
Fidget-Spinner Oct 18, 2025
7d4f866
invalidate freed code/function objects used for global promotion
Fidget-Spinner Oct 18, 2025
1981f50
Fix tracing
Fidget-Spinner Oct 18, 2025
b879dab
fix tracing completely
Fidget-Spinner Oct 18, 2025
093578c
Separate the tracer out into its own file
Fidget-Spinner Oct 18, 2025
d114944
Cleanup, bugfixes to sys trace
Fidget-Spinner Oct 18, 2025
e50ff65
Whole test suite passing
Fidget-Spinner Oct 18, 2025
54f6cd6
Remove unused buffer
Fidget-Spinner Oct 18, 2025
e3f18e6
Cleanup warnings
Fidget-Spinner Oct 18, 2025
608772f
refactor a little
Fidget-Spinner Oct 18, 2025
1872715
Cleanup
Fidget-Spinner Oct 18, 2025
460fb39
📜🤖 Added by blurb_it.
blurb-it[bot] Oct 18, 2025
8d6f1db
Merge remote-tracking branch 'upstream/main' into tracing_jit
Fidget-Spinner Oct 18, 2025
a8762c2
Disable windows CI for now, simplify
Fidget-Spinner Oct 18, 2025
72c2242
restore non-jit builds
Fidget-Spinner Oct 18, 2025
d76dc85
make mypy happy
Fidget-Spinner Oct 18, 2025
87c0b72
fix linter and mypy?
Fidget-Spinner Oct 18, 2025
24cd7f9
more cleanup to fix CI
Fidget-Spinner Oct 18, 2025
8ae2e4c
Merge remote-tracking branch 'upstream/main' into tracing_jit
Fidget-Spinner Oct 18, 2025
f38ef69
Fix lltrace on jit debug builds
Fidget-Spinner Oct 18, 2025
960d647
Turn off tracing on dynamic exit
Fidget-Spinner Oct 19, 2025
1798ab1
Fix _CHECK_PERIODIC insertion
Fidget-Spinner Oct 19, 2025
681485f
Increase uop length to compensate
Fidget-Spinner Oct 19, 2025
9bb03a8
Handle EXTENDED_ARG
Fidget-Spinner Oct 19, 2025
4b26cde
Handle unstable branches
Fidget-Spinner Oct 19, 2025
d820e22
Don't JIT short traces except if they end in a loop
Fidget-Spinner Oct 19, 2025
00c81fa
revert last 2 changes
Fidget-Spinner Oct 20, 2025
ba64a5b
Support BINARY_OP_INPLACE_ADD_UNICODE
Fidget-Spinner Oct 20, 2025
b00252e
Trace through BINARY_OP_SUBSCR_GETITEM
Fidget-Spinner Oct 20, 2025
754b3b7
Close loops
Fidget-Spinner Oct 20, 2025
6045a67
Specialize on deopt when tracing
Fidget-Spinner Oct 20, 2025
ec2971f
make mypy happy
Fidget-Spinner Oct 20, 2025
d49e367
remedies against trace explosion
Fidget-Spinner Oct 20, 2025
55892a4
lint
Fidget-Spinner Oct 20, 2025
dd0e16f
Fix a bug with where the executors get inserted during EXTENDED_ARG
Fidget-Spinner Oct 20, 2025
d18c1a1
Revert remedies against trace explosion
Fidget-Spinner Oct 20, 2025
7d17741
First half of reviews
Fidget-Spinner Oct 21, 2025
8ebb6cb
Fix naming of things
Fidget-Spinner Oct 21, 2025
c23e591
restore optimizer code
Fidget-Spinner Oct 21, 2025
a62fe40
Clean up macros
Fidget-Spinner Oct 21, 2025
e4f1624
Clean up the cases generator
Fidget-Spinner Oct 21, 2025
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
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ Programs/test_frozenmain.h generated
Python/Python-ast.c generated
Python/executor_cases.c.h generated
Python/generated_cases.c.h generated
Python/generated_tracer_cases.c.h generated
Python/optimizer_cases.c.h generated
Python/opcode_targets.h generated
Python/stdlib_module_names.h generated
Expand Down
24 changes: 12 additions & 12 deletions .github/workflows/jit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ jobs:
fail-fast: false
matrix:
target:
- i686-pc-windows-msvc/msvc
- x86_64-pc-windows-msvc/msvc
- aarch64-pc-windows-msvc/msvc
# - i686-pc-windows-msvc/msvc
# - x86_64-pc-windows-msvc/msvc
# - aarch64-pc-windows-msvc/msvc
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it intentional to remove those targets?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. The description says this is not supported on Windows till it gets tail calling support.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please could you add a note above to say why it's commented-out? (And at line 73.) So we know not to just delete them later.

- x86_64-apple-darwin/clang
- aarch64-apple-darwin/clang
- x86_64-unknown-linux-gnu/gcc
Expand All @@ -70,15 +70,15 @@ jobs:
llvm:
- 19
include:
- target: i686-pc-windows-msvc/msvc
architecture: Win32
runner: windows-2022
- target: x86_64-pc-windows-msvc/msvc
architecture: x64
runner: windows-2022
- target: aarch64-pc-windows-msvc/msvc
architecture: ARM64
runner: windows-11-arm
# - target: i686-pc-windows-msvc/msvc
# architecture: Win32
# runner: windows-2022
# - target: x86_64-pc-windows-msvc/msvc
# architecture: x64
# runner: windows-2022
# - target: aarch64-pc-windows-msvc/msvc
# architecture: ARM64
# runner: windows-11-arm
- target: x86_64-apple-darwin/clang
architecture: x86_64
runner: macos-15-intel
Expand Down
17 changes: 16 additions & 1 deletion Include/internal/pycore_interp_structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -757,6 +757,21 @@ struct _Py_unique_id_pool {

typedef _Py_CODEUNIT *(*_PyJitEntryFuncPtr)(struct _PyExecutorObject *exec, _PyInterpreterFrame *frame, _PyStackRef *stack_pointer, PyThreadState *tstate);

typedef struct _PyJitState {
int jit_tracer_code_max_size;
int jit_tracer_code_curr_size;
_PyBloomFilter jit_tracer_dependencies;
bool jit_tracer_dependencies_still_valid;
_PyUOpInstruction *jit_tracer_code_buffer;
_Py_CODEUNIT *jit_tracer_initial_instr;
int jit_tracer_initial_stack_depth;
int jit_tracer_initial_chain_depth;
PyCodeObject *jit_tracer_initial_code; // Strong
PyFunctionObject *jit_tracer_initial_func; // Strong
struct _PyExitData *jit_tracer_previous_exit;
_PyInterpreterFrame *jit_tracer_current_frame;
} _PyJitState;

/* PyInterpreterState holds the global state for one of the runtime's
interpreters. Typically the initial (main) interpreter is the only one.

Expand Down Expand Up @@ -932,9 +947,9 @@ struct _is {
struct types_state types;
struct callable_cache callable_cache;
PyObject *common_consts[NUM_COMMON_CONSTANTS];
_PyJitState jit_state;
bool jit;
bool compiling;
struct _PyUOpInstruction *jit_uop_buffer;
struct _PyExecutorObject *executor_list_head;
struct _PyExecutorObject *executor_deletion_list_head;
struct _PyExecutorObject *cold_executor;
Expand Down
42 changes: 42 additions & 0 deletions Include/internal/pycore_opcode_metadata.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 25 additions & 11 deletions Include/internal/pycore_optimizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,6 @@ typedef struct _PyExecutorLinkListNode {
} _PyExecutorLinkListNode;


/* Bloom filter with m = 256
* https://en.wikipedia.org/wiki/Bloom_filter */
#define _Py_BLOOM_FILTER_WORDS 8

typedef struct {
uint32_t bits[_Py_BLOOM_FILTER_WORDS];
} _PyBloomFilter;

typedef struct {
uint8_t opcode;
uint8_t oparg;
Expand All @@ -45,6 +37,7 @@ typedef struct {
typedef struct _PyExitData {
uint32_t target;
uint16_t index;
char is_dynamic;
_Py_BackoffCounter temperature;
struct _PyExecutorObject *executor;
} _PyExitData;
Expand Down Expand Up @@ -95,7 +88,8 @@ PyAPI_FUNC(void) _Py_Executors_InvalidateCold(PyInterpreterState *interp);

#define TRACE_STACK_SIZE 5

int _Py_uop_analyze_and_optimize(_PyInterpreterFrame *frame,
int _Py_uop_analyze_and_optimize(
PyFunctionObject *initial_func,
_PyUOpInstruction *trace, int trace_len, int curr_stackentries,
_PyBloomFilter *dependencies);

Expand Down Expand Up @@ -336,7 +330,7 @@ extern int _Py_uop_frame_pop(JitOptContext *ctx);

PyAPI_FUNC(PyObject *) _Py_uop_symbols_test(PyObject *self, PyObject *ignored);

PyAPI_FUNC(int) _PyOptimizer_Optimize(_PyInterpreterFrame *frame, _Py_CODEUNIT *start, _PyExecutorObject **exec_ptr, int chain_depth);
PyAPI_FUNC(int) _PyOptimizer_Optimize(_PyInterpreterFrame *frame, PyThreadState *tstate);

static inline _PyExecutorObject *_PyExecutor_FromExit(_PyExitData *exit)
{
Expand All @@ -353,7 +347,8 @@ static inline int is_terminator(const _PyUOpInstruction *uop)
int opcode = uop->opcode;
return (
opcode == _EXIT_TRACE ||
opcode == _JUMP_TO_TOP
opcode == _JUMP_TO_TOP ||
opcode == _DYNAMIC_EXIT
);
}

Expand All @@ -364,6 +359,25 @@ PyAPI_FUNC(int) _PyDumpExecutors(FILE *out);
extern void _Py_ClearExecutorDeletionList(PyInterpreterState *interp);
#endif

int
_PyJIT_translate_single_bytecode_to_trace(
PyThreadState *tstate,
_PyInterpreterFrame *frame,
_Py_CODEUNIT *this_instr,
_Py_CODEUNIT *next_instr,
PyCodeObject *code,
PyFunctionObject *func,
int opcode,
int oparg,
int jump_taken);

void
_PyJIT_InitializeTracing(PyThreadState *tstate, _PyInterpreterFrame *frame, _Py_CODEUNIT *next_instr, int curr_stackdepth, int chain_depth, _PyExitData *exit);

void _PyJIT_FinalizeTracing(PyThreadState *tstate);

void _Py_JITTracer_InvalidateDependency(PyThreadState *old_tstate, void *obj);

#ifdef __cplusplus
}
#endif
Expand Down
10 changes: 9 additions & 1 deletion Include/internal/pycore_uop.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,18 @@ typedef struct _PyUOpInstruction{
#endif
} _PyUOpInstruction;

// This is the length of the trace we project initially.
// This is the length of the trace we translate initially.
#define UOP_MAX_TRACE_LENGTH 1200
#define UOP_BUFFER_SIZE (UOP_MAX_TRACE_LENGTH * sizeof(_PyUOpInstruction))

/* Bloom filter with m = 256
* https://en.wikipedia.org/wiki/Bloom_filter */
#define _Py_BLOOM_FILTER_WORDS 8

typedef struct {
uint32_t bits[_Py_BLOOM_FILTER_WORDS];
} _PyBloomFilter;

#ifdef __cplusplus
}
#endif
Expand Down
Loading
Loading