mirror of
https://github.com/python/cpython
synced 2026-09-29 11:15:30 +03:00
GH-113710: Add a "globals to constants" pass (GH-114592)
Converts specializations of `LOAD_GLOBAL` into constants during tier 2 optimization.
This commit is contained in:
parent
2091fb2a85
commit
0e71a295e9
16 changed files with 375 additions and 55 deletions
|
|
@ -17,6 +17,9 @@ typedef struct {
|
|||
/* Dictionary version: globally unique, value change each time
|
||||
the dictionary is modified */
|
||||
#ifdef Py_BUILD_CORE
|
||||
/* Bits 0-7 are for dict watchers.
|
||||
* Bits 8-11 are for the watched mutation counter (used by tier2 optimization)
|
||||
* The remaining bits (12-63) are the actual version tag. */
|
||||
uint64_t ma_version_tag;
|
||||
#else
|
||||
Py_DEPRECATED(3.12) uint64_t ma_version_tag;
|
||||
|
|
|
|||
|
|
@ -47,7 +47,10 @@ 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 **exec_ptr,
|
||||
int curr_stackentries);
|
||||
|
||||
typedef struct _PyOptimizerObject {
|
||||
PyObject_HEAD
|
||||
|
|
@ -94,6 +97,9 @@ PyAPI_FUNC(PyObject *)PyUnstable_Optimizer_NewUOpOptimizer(void);
|
|||
/* Minimum of 16 additional executions before retry */
|
||||
#define MINIMUM_TIER2_BACKOFF 4
|
||||
|
||||
#define _Py_MAX_ALLOWED_BUILTINS_MODIFICATIONS 3
|
||||
#define _Py_MAX_ALLOWED_GLOBALS_MODIFICATIONS 6
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -207,8 +207,8 @@ static inline PyDictUnicodeEntry* DK_UNICODE_ENTRIES(PyDictKeysObject *dk) {
|
|||
|
||||
#define DK_IS_UNICODE(dk) ((dk)->dk_kind != DICT_KEYS_GENERAL)
|
||||
|
||||
#define DICT_VERSION_INCREMENT (1 << DICT_MAX_WATCHERS)
|
||||
#define DICT_VERSION_MASK (DICT_VERSION_INCREMENT - 1)
|
||||
#define DICT_VERSION_INCREMENT (1 << (DICT_MAX_WATCHERS + DICT_WATCHED_MUTATION_BITS))
|
||||
#define DICT_WATCHER_MASK ((1 << DICT_MAX_WATCHERS) - 1)
|
||||
|
||||
#ifdef Py_GIL_DISABLED
|
||||
#define DICT_NEXT_VERSION(INTERP) \
|
||||
|
|
@ -234,7 +234,7 @@ _PyDict_NotifyEvent(PyInterpreterState *interp,
|
|||
PyObject *value)
|
||||
{
|
||||
assert(Py_REFCNT((PyObject*)mp) > 0);
|
||||
int watcher_bits = mp->ma_version_tag & DICT_VERSION_MASK;
|
||||
int watcher_bits = mp->ma_version_tag & DICT_WATCHER_MASK;
|
||||
if (watcher_bits) {
|
||||
_PyDict_SendEvent(watcher_bits, event, mp, key, value);
|
||||
return DICT_NEXT_VERSION(interp) | watcher_bits;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#define DICT_MAX_WATCHERS 8
|
||||
#define DICT_WATCHED_MUTATION_BITS 4
|
||||
|
||||
struct _Py_dict_state {
|
||||
/*Global counter used to set ma_version_tag field of dictionary.
|
||||
|
|
|
|||
|
|
@ -72,7 +72,6 @@ typedef struct _rare_events {
|
|||
uint8_t set_eval_frame_func;
|
||||
/* Modifying the builtins, __builtins__.__dict__[var] = ... */
|
||||
uint8_t builtin_dict;
|
||||
int builtins_dict_watcher_id;
|
||||
/* Modifying a function, e.g. func.__defaults__ = ..., etc. */
|
||||
uint8_t func_modification;
|
||||
} _rare_events;
|
||||
|
|
@ -243,6 +242,7 @@ struct _is {
|
|||
uint16_t optimizer_backedge_threshold;
|
||||
uint32_t next_func_version;
|
||||
_rare_events rare_events;
|
||||
PyDict_WatchCallback builtins_dict_watcher;
|
||||
|
||||
_Py_GlobalMonitors monitors;
|
||||
bool sys_profile_initialized;
|
||||
|
|
|
|||
|
|
@ -8,8 +8,9 @@ extern "C" {
|
|||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
int _Py_uop_analyze_and_optimize(PyCodeObject *code,
|
||||
_PyUOpInstruction *trace, int trace_len, int curr_stackentries);
|
||||
int _Py_uop_analyze_and_optimize(_PyInterpreterFrame *frame,
|
||||
_PyUOpInstruction *trace, int trace_len, int curr_stackentries,
|
||||
_PyBloomFilter *dependencies);
|
||||
|
||||
extern PyTypeObject _PyCounterExecutor_Type;
|
||||
extern PyTypeObject _PyCounterOptimizer_Type;
|
||||
|
|
|
|||
8
Include/internal/pycore_uop_ids.h
generated
8
Include/internal/pycore_uop_ids.h
generated
|
|
@ -232,8 +232,12 @@ extern "C" {
|
|||
#define _CHECK_VALIDITY 379
|
||||
#define _LOAD_CONST_INLINE 380
|
||||
#define _LOAD_CONST_INLINE_BORROW 381
|
||||
#define _INTERNAL_INCREMENT_OPT_COUNTER 382
|
||||
#define MAX_UOP_ID 382
|
||||
#define _LOAD_CONST_INLINE_WITH_NULL 382
|
||||
#define _LOAD_CONST_INLINE_BORROW_WITH_NULL 383
|
||||
#define _CHECK_GLOBALS 384
|
||||
#define _CHECK_BUILTINS 385
|
||||
#define _INTERNAL_INCREMENT_OPT_COUNTER 386
|
||||
#define MAX_UOP_ID 386
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -204,6 +204,10 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
|
|||
[_CHECK_VALIDITY] = HAS_DEOPT_FLAG,
|
||||
[_LOAD_CONST_INLINE] = 0,
|
||||
[_LOAD_CONST_INLINE_BORROW] = 0,
|
||||
[_LOAD_CONST_INLINE_WITH_NULL] = 0,
|
||||
[_LOAD_CONST_INLINE_BORROW_WITH_NULL] = 0,
|
||||
[_CHECK_GLOBALS] = HAS_DEOPT_FLAG,
|
||||
[_CHECK_BUILTINS] = HAS_DEOPT_FLAG,
|
||||
[_INTERNAL_INCREMENT_OPT_COUNTER] = 0,
|
||||
};
|
||||
|
||||
|
|
@ -250,10 +254,12 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = {
|
|||
[_CHECK_ATTR_METHOD_LAZY_DICT] = "_CHECK_ATTR_METHOD_LAZY_DICT",
|
||||
[_CHECK_ATTR_MODULE] = "_CHECK_ATTR_MODULE",
|
||||
[_CHECK_ATTR_WITH_HINT] = "_CHECK_ATTR_WITH_HINT",
|
||||
[_CHECK_BUILTINS] = "_CHECK_BUILTINS",
|
||||
[_CHECK_CALL_BOUND_METHOD_EXACT_ARGS] = "_CHECK_CALL_BOUND_METHOD_EXACT_ARGS",
|
||||
[_CHECK_EG_MATCH] = "_CHECK_EG_MATCH",
|
||||
[_CHECK_EXC_MATCH] = "_CHECK_EXC_MATCH",
|
||||
[_CHECK_FUNCTION_EXACT_ARGS] = "_CHECK_FUNCTION_EXACT_ARGS",
|
||||
[_CHECK_GLOBALS] = "_CHECK_GLOBALS",
|
||||
[_CHECK_MANAGED_OBJECT_HAS_VALUES] = "_CHECK_MANAGED_OBJECT_HAS_VALUES",
|
||||
[_CHECK_PEP_523] = "_CHECK_PEP_523",
|
||||
[_CHECK_STACK_SPACE] = "_CHECK_STACK_SPACE",
|
||||
|
|
@ -332,6 +338,8 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = {
|
|||
[_LOAD_CONST] = "_LOAD_CONST",
|
||||
[_LOAD_CONST_INLINE] = "_LOAD_CONST_INLINE",
|
||||
[_LOAD_CONST_INLINE_BORROW] = "_LOAD_CONST_INLINE_BORROW",
|
||||
[_LOAD_CONST_INLINE_BORROW_WITH_NULL] = "_LOAD_CONST_INLINE_BORROW_WITH_NULL",
|
||||
[_LOAD_CONST_INLINE_WITH_NULL] = "_LOAD_CONST_INLINE_WITH_NULL",
|
||||
[_LOAD_DEREF] = "_LOAD_DEREF",
|
||||
[_LOAD_FAST] = "_LOAD_FAST",
|
||||
[_LOAD_FAST_AND_CLEAR] = "_LOAD_FAST_AND_CLEAR",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue