Skip to content

Commit 3248658

Browse files
Hulon's and mine changes
Co-Authored-By: Hulon Jenkins <[email protected]>
1 parent 82d1259 commit 3248658

File tree

7 files changed

+59
-16
lines changed

7 files changed

+59
-16
lines changed

Include/pyport.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,24 @@ extern "C" {
385385
# define Py_NO_INLINE
386386
#endif
387387

388+
// Any function annotated with this MUST not modify global state.
389+
// It can only modify state referenced by its parameters.
390+
// This is useful for optimizations on certain compilers.
391+
// Please see https://learn.microsoft.com/en-us/cpp/cpp/noalias
392+
#if defined(__GNUC__) || defined(__clang__) || defined(__INTEL_COMPILER)
393+
# define Py_NOALIAS
394+
#elif defined(_MSC_VER)
395+
# define Py_NOALIAS __declspec(noalias)
396+
#else
397+
# define Py_NOALIAS
398+
#endif
399+
400+
// A no-op at compile time. Hints to the programmer
401+
// That any local variable defined within this block MUST
402+
// not escape from the current definition.
403+
# define Py_BEGIN_LOCALS_MUST_NOT_ESCAPE() {
404+
# define Py_END_LOCALS_MUST_NOT_ESCAPE() }
405+
388406
#include "exports.h"
389407

390408
#ifdef Py_LIMITED_API

PCbuild/pythoncore.vcxproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@
108108
<PreprocessorDefinitions Condition="'$(UseJIT)' == 'true'">_Py_JIT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
109109
<PreprocessorDefinitions Condition="'$(UseTIER2)' != '' and '$(UseTIER2)' != '0'">_Py_TIER2=$(UseTIER2);%(PreprocessorDefinitions)</PreprocessorDefinitions>
110110
<PreprocessorDefinitions Condition="'$(UseTailCallInterp)' == 'true'">Py_TAIL_CALL_INTERP=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
111+
<AdditionalOptions Condition="'$(UseTailCallInterp)' == 'true'">/std:clatest %(AdditionalOptions)</AdditionalOptions>
111112
<PreprocessorDefinitions Condition="'$(WITH_COMPUTED_GOTOS)' != ''">HAVE_COMPUTED_GOTOS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
112113
<PreprocessorDefinitions Condition="'$(DisableRemoteDebug)' != 'true'">Py_REMOTE_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
113114
</ClCompile>

Python/bytecodes.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2226,8 +2226,11 @@ dummy_func(
22262226
}
22272227
// we make no attempt to optimize here; specializations should
22282228
// handle any case whose performance we care about
2229-
PyObject *stack[] = {class, self};
2230-
PyObject *super = PyObject_Vectorcall(global_super, stack, oparg & 2, NULL);
2229+
PyObject *super;
2230+
Py_BEGIN_LOCALS_MUST_NOT_ESCAPE();
2231+
PyObject *restrict stack[] = {class, self};
2232+
super = PyObject_Vectorcall(global_super, stack, oparg & 2, NULL);
2233+
Py_END_LOCALS_MUST_NOT_ESCAPE();
22312234
if (opcode == INSTRUMENTED_LOAD_SUPER_ATTR) {
22322235
PyObject *arg = oparg & 2 ? class : &_PyInstrumentation_MISSING;
22332236
if (super == NULL) {
@@ -3509,10 +3512,13 @@ dummy_func(
35093512
}
35103513
assert(PyStackRef_IsTaggedInt(lasti));
35113514
(void)lasti; // Shut up compiler warning if asserts are off
3512-
PyObject *stack[5] = {NULL, PyStackRef_AsPyObjectBorrow(exit_self), exc, val_o, tb};
3515+
PyObject* res_o;
3516+
Py_BEGIN_LOCALS_MUST_NOT_ESCAPE();
3517+
PyObject *restrict stack[5] = {NULL, PyStackRef_AsPyObjectBorrow(exit_self), exc, val_o, tb};
35133518
int has_self = !PyStackRef_IsNull(exit_self);
3514-
PyObject *res_o = PyObject_Vectorcall(exit_func_o, stack + 2 - has_self,
3519+
res_o = PyObject_Vectorcall(exit_func_o, stack + 2 - has_self,
35153520
(3 + has_self) | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
3521+
Py_END_LOCALS_MUST_NOT_ESCAPE();
35163522
Py_XDECREF(original_tb);
35173523
ERROR_IF(res_o == NULL);
35183524
res = PyStackRef_FromPyObjectSteal(res_o);

Python/ceval_macros.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,9 @@
8585
# else
8686
# define Py_MUSTTAIL [[clang::musttail]]
8787
# define Py_PRESERVE_NONE_CC __attribute__((preserve_none))
88-
Py_PRESERVE_NONE_CC typedef PyObject* (*py_tail_call_funcptr)(TAIL_CALL_PARAMS);
8988
# endif
90-
# define TARGET(op) Py_PRESERVE_NONE_CC PyObject *_TAIL_CALL_##op(TAIL_CALL_PARAMS)
89+
typedef PyObject *(Py_PRESERVE_NONE_CC *py_tail_call_funcptr)(TAIL_CALL_PARAMS);
90+
# define TARGET(op) Py_NO_INLINE PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_##op(TAIL_CALL_PARAMS)
9191
# define DISPATCH_GOTO() \
9292
do { \
9393
Py_MUSTTAIL return (INSTRUCTION_TABLE[opcode])(TAIL_CALL_ARGS); \

Python/executor_cases.c.h

Lines changed: 8 additions & 3 deletions
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: 18 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Tools/cases_generator/analyzer.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,8 @@ def has_error_without_pop(op: parser.CodeDef) -> bool:
692692
"PyStackRef_Wrap",
693693
"PyStackRef_Unwrap",
694694
"_PyLong_CheckExactAndCompact",
695+
"Py_BEGIN_LOCALS_MUST_NOT_ESCAPE",
696+
"Py_END_LOCALS_MUST_NOT_ESCAPE",
695697
)
696698

697699

0 commit comments

Comments
 (0)