Skip to content

Commit a6533c1

Browse files
JuliaPooFidget-Spinnerbrandtbucher
authored
Feat: Merge Brandt's Copy and Patch compiler (python#52)
Co-authored-by: Ken Jin <[email protected]> Co-authored-by: Brandt Bucher <[email protected]>
1 parent 7210772 commit a6533c1

32 files changed

+1503
-128
lines changed

.github/workflows/jit.yml

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
name: JIT
2+
on: push
3+
jobs:
4+
jit:
5+
name: ${{ matrix.target }} (${{ matrix.debug && 'Debug' || 'Release' }}, LLVM ${{ matrix.llvm }})
6+
runs-on: ${{ matrix.runner }}
7+
strategy:
8+
fail-fast: false
9+
matrix:
10+
target:
11+
# - i686-pc-windows-msvc/msvc
12+
- x86_64-pc-windows-msvc/msvc
13+
# - x86_64-apple-darwin/clang
14+
# - x86_64-unknown-linux-gnu/gcc
15+
# - aarch64-apple-darwin/clang
16+
# - aarch64-unknown-linux-gnu/gcc
17+
# - aarch64-unknown-linux-gnu/clang
18+
# - powerpc64le-unknown-linux-gnu/gcc
19+
# - x86_64-unknown-linux-gnu/clang
20+
debug:
21+
- true
22+
# - false
23+
llvm:
24+
#- 14
25+
#- 15
26+
- 16
27+
include:
28+
# - target: i686-pc-windows-msvc/msvc
29+
# architecture: i686
30+
# runner: windows-latest
31+
# compiler: msvc
32+
# tier: 1
33+
# windows_platform: Win32
34+
- target: x86_64-pc-windows-msvc/msvc
35+
architecture: x86_64
36+
runner: windows-latest
37+
compiler: msvc
38+
tier: 1
39+
windows_platform: x64
40+
# - target: x86_64-apple-darwin/clang
41+
# architecture: x86_64
42+
# runner: macos-latest
43+
# compiler: clang
44+
# tier: 1
45+
# - target: x86_64-unknown-linux-gnu/gcc
46+
# architecture: x86_64
47+
# runner: ubuntu-latest
48+
# compiler: gcc
49+
# tier: 1
50+
# - target: aarch64-apple-darwin/clang
51+
# architecture: aarch64
52+
# runner: macos-latest
53+
# compiler: clang
54+
# tier: 2
55+
# - target: aarch64-unknown-linux-gnu/gcc
56+
# architecture: aarch64
57+
# runner: ubuntu-latest
58+
# compiler: gcc
59+
# tier: 2
60+
# - target: aarch64-unknown-linux-gnu/clang
61+
# architecture: aarch64
62+
# runner: ubuntu-latest
63+
# compiler: clang
64+
# tier: 2
65+
# - target: powerpc64le-unknown-linux-gnu/gcc
66+
# architecture: ppc64le
67+
# runner: ubuntu-latest
68+
# compiler: gcc
69+
# tier: 2
70+
# - target: x86_64-unknown-linux-gnu/clang
71+
# architecture: x86_64
72+
# runner: ubuntu-latest
73+
# compiler: clang
74+
# tier: 2
75+
env:
76+
CC: ${{ matrix.compiler }}
77+
PYTHON_LLVM_VERSION: ${{ matrix.llvm }}
78+
steps:
79+
- uses: actions/checkout@v3
80+
- uses: actions/setup-python@v4
81+
with:
82+
python-version: '3.10'
83+
# Only support Window x64 ~ Jules
84+
# - name: macOS
85+
# if: runner.os == 'macOS'
86+
# run: |
87+
# brew install llvm@${{ matrix.llvm }}
88+
# export SDKROOT="$(xcrun --show-sdk-path)"
89+
# ./configure ${{ matrix.debug && '--with-pydebug' || '--enable-optimizations --with-lto' }}
90+
# make
91+
# ./python.exe -m test -j0 -wW
92+
# - name: Native Linux
93+
# if: runner.os == 'Linux' && matrix.architecture == 'x86_64'
94+
# run: |
95+
# sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)" ./llvm.sh ${{ matrix.llvm }}
96+
# ${{ matrix.llvm == 14 && 'sudo apt install libclang-rt-14-dev' || '' }}
97+
# export PATH="$(llvm-config-${{ matrix.llvm }} --bindir):$PATH"
98+
# ./configure ${{ matrix.debug && '--with-pydebug' || '--enable-optimizations --with-lto' }}
99+
# make
100+
# ./python -m test -j0 -wW
101+
# - name: Emulated Linux
102+
# if: runner.os == 'Linux' && matrix.architecture != 'x86_64'
103+
# uses: uraimo/run-on-arch-action@v2
104+
# with:
105+
# arch: ${{ matrix.architecture }}
106+
# distro: ubuntu_latest
107+
# run: |
108+
# sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)" ./llvm.sh ${{ matrix.llvm }}
109+
# ${{ matrix.llvm == 14 && 'sudo apt install libclang-rt-14-dev' || '' }}
110+
# export PATH="$(llvm-config-${{ matrix.llvm }} --bindir):$PATH"
111+
# ./configure ${{ matrix.debug && '--with-pydebug' || '--enable-optimizations --with-lto' }}
112+
# make
113+
# ./python -m test -j0 -wW
114+
- name: Windows
115+
if: runner.os == 'Windows'
116+
run: |
117+
choco install llvm --allow-downgrade --version ${{ matrix.llvm }}
118+
./PCbuild/build ${{ matrix.debug && '-d' || '--pgo' }} -p ${{ matrix.windows_platform }}
119+
# ./PCbuild/rt${{ matrix.debug && ' -d' || '' }} -p ${{ matrix.windows_platform }} -q -j0 -wW
120+
- name: Tests
121+
run: .\python.bat tier2_test.py

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ Tools/msi/obj
140140
Tools/ssl/amd64
141141
Tools/ssl/win32
142142
Tools/freeze/test/outdir
143+
Python/jit_stencils.h
143144

144145
# The frozen modules are always generated by the build so we don't
145146
# keep them in the repo. Also see Tools/build/freeze_modules.py.

Include/internal/pycore_abstract.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ _PyIndex_Check(PyObject *obj)
1616
return (tp_as_number != NULL && tp_as_number->nb_index != NULL);
1717
}
1818

19-
PyObject *_PyNumber_PowerNoMod(PyObject *lhs, PyObject *rhs);
20-
PyObject *_PyNumber_InPlacePowerNoMod(PyObject *lhs, PyObject *rhs);
19+
PyAPI_FUNC(PyObject *)_PyNumber_PowerNoMod(PyObject *lhs, PyObject *rhs);
20+
PyAPI_FUNC(PyObject *)_PyNumber_InPlacePowerNoMod(PyObject *lhs, PyObject *rhs);
2121

2222
#ifdef __cplusplus
2323
}

Include/internal/pycore_ceval.h

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ struct _ceval_runtime_state;
1818

1919
#include "pycore_interp.h" // PyInterpreterState.eval_frame
2020
#include "pycore_pystate.h" // _PyThreadState_GET()
21+
#include "pycore_frame.h"
2122

2223

2324
extern void _Py_FinishPendingCalls(PyThreadState *tstate);
@@ -124,9 +125,18 @@ PyAPI_FUNC(int) _Py_CheckRecursiveCall(
124125
PyThreadState *tstate,
125126
const char *where);
126127

127-
int _Py_CheckRecursiveCallPy(
128+
PyAPI_FUNC(int) _Py_CheckRecursiveCallPy(
128129
PyThreadState *tstate);
129130

131+
static inline int _Py_EnterRecursivePy(PyThreadState *tstate) {
132+
return (tstate->py_recursion_remaining-- <= 0) &&
133+
_Py_CheckRecursiveCallPy(tstate);
134+
}
135+
136+
static inline void _Py_LeaveRecursiveCallPy(PyThreadState *tstate) {
137+
tstate->py_recursion_remaining++;
138+
}
139+
130140
static inline int _Py_EnterRecursiveCallTstate(PyThreadState *tstate,
131141
const char *where) {
132142
return (_Py_MakeRecCheck(tstate) && _Py_CheckRecursiveCall(tstate, where));
@@ -148,10 +158,14 @@ static inline void _Py_LeaveRecursiveCall(void) {
148158

149159
extern struct _PyInterpreterFrame* _PyEval_GetFrame(void);
150160

151-
extern PyObject* _Py_MakeCoro(PyFunctionObject *func);
161+
PyAPI_FUNC(PyObject *)_Py_MakeCoro(PyFunctionObject *func);
162+
163+
PyAPI_FUNC(int) _Py_HandlePending(PyThreadState *tstate);
152164

153-
extern int _Py_HandlePending(PyThreadState *tstate);
165+
PyAPI_FUNC(void) _PyEvalFrameClearAndPop(PyThreadState *tstate, _PyInterpreterFrame *frame);
166+
PyAPI_FUNC(_PyInterpreterFrame *)_PyEvalFramePushAndInit(PyThreadState *tstate, PyFunctionObject *func, PyObject *locals, PyObject* const* args, size_t argcount, PyObject *kwnames);
154167

168+
PyAPI_FUNC(PyObject *)trace_call_function(PyThreadState *tstate, PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwnames);
155169

156170

157171
#ifdef __cplusplus

Include/internal/pycore_code.h

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -238,26 +238,26 @@ extern int _PyLineTable_PreviousAddressRange(PyCodeAddressRange *range);
238238

239239
/* Specialization functions */
240240

241-
extern void _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr,
241+
PyAPI_FUNC(void) _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr,
242242
PyObject *name);
243-
extern void _Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr,
243+
PyAPI_FUNC(void) _Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr,
244244
PyObject *name);
245-
extern void _Py_Specialize_LoadGlobal(PyObject *globals, PyObject *builtins,
245+
PyAPI_FUNC(void) _Py_Specialize_LoadGlobal(PyObject *globals, PyObject *builtins,
246246
_Py_CODEUNIT *instr, PyObject *name);
247-
extern void _Py_Specialize_BinarySubscr(PyObject *sub, PyObject *container,
247+
PyAPI_FUNC(void) _Py_Specialize_BinarySubscr(PyObject *sub, PyObject *container,
248248
_Py_CODEUNIT *instr);
249-
extern void _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub,
249+
PyAPI_FUNC(void) _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub,
250250
_Py_CODEUNIT *instr);
251-
extern void _Py_Specialize_Call(PyObject *callable, _Py_CODEUNIT *instr,
251+
PyAPI_FUNC(void) _Py_Specialize_Call(PyObject *callable, _Py_CODEUNIT *instr,
252252
int nargs, PyObject *kwnames);
253-
extern void _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr,
253+
PyAPI_FUNC(void) _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr,
254254
int oparg, PyObject **locals);
255-
extern void _Py_Specialize_CompareOp(PyObject *lhs, PyObject *rhs,
255+
PyAPI_FUNC(void) _Py_Specialize_CompareOp(PyObject *lhs, PyObject *rhs,
256256
_Py_CODEUNIT *instr, int oparg);
257-
extern void _Py_Specialize_UnpackSequence(PyObject *seq, _Py_CODEUNIT *instr,
257+
PyAPI_FUNC(void) _Py_Specialize_UnpackSequence(PyObject *seq, _Py_CODEUNIT *instr,
258258
int oparg);
259-
extern void _Py_Specialize_ForIter(PyObject *iter, _Py_CODEUNIT *instr, int oparg, char is_bb);
260-
extern void _Py_Specialize_Send(PyObject *receiver, _Py_CODEUNIT *instr);
259+
PyAPI_FUNC(void) _Py_Specialize_ForIter(PyObject *iter, _Py_CODEUNIT *instr, int oparg, char is_bb);
260+
PyAPI_FUNC(void) _Py_Specialize_Send(PyObject *receiver, _Py_CODEUNIT *instr);
261261

262262
/* Finalizer function for static codeobjects used in deepfreeze.py */
263263
extern void _PyStaticCode_Fini(PyCodeObject *co);

Include/internal/pycore_dict.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ extern Py_ssize_t _PyDictKeys_StringLookup(PyDictKeysObject* dictkeys, PyObject
5252
extern PyObject *_PyDict_LoadGlobal(PyDictObject *, PyDictObject *, PyObject *);
5353

5454
/* Consumes references to key and value */
55-
extern int _PyDict_SetItem_Take2(PyDictObject *op, PyObject *key, PyObject *value);
55+
PyAPI_FUNC(int) _PyDict_SetItem_Take2(PyDictObject *op, PyObject *key, PyObject *value);
5656
extern int _PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr, PyObject *name, PyObject *value);
5757

5858
extern PyObject *_PyDict_Pop_KnownHash(PyObject *, PyObject *, Py_hash_t, PyObject *);
@@ -176,7 +176,7 @@ _PyDict_NotifyEvent(PyInterpreterState *interp,
176176
}
177177

178178
extern PyObject *_PyObject_MakeDictFromInstanceAttributes(PyObject *obj, PyDictValues *values);
179-
extern PyObject *_PyDict_FromItems(
179+
PyAPI_FUNC(PyObject *)_PyDict_FromItems(
180180
PyObject *const *keys, Py_ssize_t keys_offset,
181181
PyObject *const *values, Py_ssize_t values_offset,
182182
Py_ssize_t length);

Include/internal/pycore_floatobject.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ struct _Py_float_state {
5050
#endif
5151
};
5252

53-
void _PyFloat_ExactDealloc(PyObject *op);
53+
PyAPI_FUNC(void) _PyFloat_ExactDealloc(PyObject *op);
5454

5555

5656
PyAPI_FUNC(void) _PyFloat_DebugMallocStats(FILE* out);

Include/internal/pycore_frame.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ _PyFrame_NumSlotsForCodeObject(PyCodeObject *code)
114114
return res;
115115
}
116116

117-
void _PyFrame_Copy(_PyInterpreterFrame *src, _PyInterpreterFrame *dest);
117+
PyAPI_FUNC(void) _PyFrame_Copy(_PyInterpreterFrame *src, _PyInterpreterFrame *dest);
118118

119119
/* Consumes reference to func and locals.
120120
Does not initialize frame->previous, which happens
@@ -265,7 +265,7 @@ _PyThreadState_HasStackSpace(PyThreadState *tstate, int size)
265265
extern _PyInterpreterFrame *
266266
_PyThreadState_PushFrame(PyThreadState *tstate, size_t size);
267267

268-
void _PyThreadState_PopFrame(PyThreadState *tstate, _PyInterpreterFrame *frame);
268+
PyAPI_FUNC(void) _PyThreadState_PopFrame(PyThreadState *tstate, _PyInterpreterFrame *frame);
269269

270270
/* Pushes a frame without checking for space.
271271
* Must be guarded by _PyThreadState_HasStackSpace()

Include/internal/pycore_genobject.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ extern "C" {
99
#endif
1010

1111
extern PyObject *_PyGen_yf(PyGenObject *);
12-
extern PyObject *_PyCoro_GetAwaitableIter(PyObject *o);
12+
PyAPI_FUNC(PyObject *)_PyCoro_GetAwaitableIter(PyObject *o);
1313
extern PyObject *_PyAsyncGenValueWrapperNew(PyThreadState *state, PyObject *);
1414

1515
/* runtime lifecycle */

Include/internal/pycore_intrinsics.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@
2121
typedef PyObject *(*instrinsic_func1)(PyThreadState* tstate, PyObject *value);
2222
typedef PyObject *(*instrinsic_func2)(PyThreadState* tstate, PyObject *value1, PyObject *value2);
2323

24-
extern const instrinsic_func1 _PyIntrinsics_UnaryFunctions[];
25-
extern const instrinsic_func2 _PyIntrinsics_BinaryFunctions[];
24+
PyAPI_DATA(const instrinsic_func1) _PyIntrinsics_UnaryFunctions[];
25+
PyAPI_DATA(const instrinsic_func2) _PyIntrinsics_BinaryFunctions[];
2626

0 commit comments

Comments
 (0)