-
-
Notifications
You must be signed in to change notification settings - Fork 32.6k
gh-87092: move CFG related code from compile.c to flowgraph.c #103021
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 14 commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
5eea154
gh-87092: create new opcode_utils.h file and move macros from compile…
iritkatriel b5244da
gh-87092: move CFG related code from compile.c to cfg.c
iritkatriel abb6f26
remove include
iritkatriel 91a8743
make globals const
iritkatriel abaeeac
update pcbuild
iritkatriel fb15754
Merge branch 'main' into cfg.c
iritkatriel 8f21775
move a few more functions from compile.c to cfg.c
iritkatriel a38cbcd
cfg.c --> cfg_opt.c
iritkatriel 0f78101
update pcbuild files
iritkatriel b273dd0
and makefile
iritkatriel 5909b64
fix include
iritkatriel 6f52884
cfg_opt --> flowgraph
iritkatriel beb28f6
Merge remote-tracking branch 'upstream/main' into cfg.c
iritkatriel b6baa7b
Merge branch 'main' into cfg.c
iritkatriel d1f0c66
remove duplicated macros. rename arr_ --> array
iritkatriel File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
#ifndef Py_INTERNAL_CFG_H | ||
#define Py_INTERNAL_CFG_H | ||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
#ifndef Py_BUILD_CORE | ||
# error "this header requires Py_BUILD_CORE define" | ||
#endif | ||
|
||
#include "pycore_opcode_utils.h" | ||
|
||
static const _PyCompilerSrcLocation NO_LOCATION = {-1, -1, -1, -1}; | ||
|
||
typedef struct { | ||
int i_opcode; | ||
int i_oparg; | ||
_PyCompilerSrcLocation i_loc; | ||
struct _PyCfgBasicblock_ *i_target; /* target block (if jump instruction) */ | ||
struct _PyCfgBasicblock_ *i_except; /* target block when exception is raised */ | ||
} _PyCfgInstruction; | ||
|
||
typedef struct { | ||
int id; | ||
} _PyCfgJumpTargetLabel; | ||
|
||
|
||
typedef struct { | ||
struct _PyCfgBasicblock_ *handlers[CO_MAXBLOCKS+1]; | ||
int depth; | ||
} _PyCfgExceptStack; | ||
|
||
typedef struct _PyCfgBasicblock_ { | ||
/* Each basicblock in a compilation unit is linked via b_list in the | ||
reverse order that the block are allocated. b_list points to the next | ||
block, not to be confused with b_next, which is next by control flow. */ | ||
struct _PyCfgBasicblock_ *b_list; | ||
/* The label of this block if it is a jump target, -1 otherwise */ | ||
_PyCfgJumpTargetLabel b_label; | ||
/* Exception stack at start of block, used by assembler to create the exception handling table */ | ||
_PyCfgExceptStack *b_exceptstack; | ||
/* pointer to an array of instructions, initially NULL */ | ||
_PyCfgInstruction *b_instr; | ||
/* If b_next is non-NULL, it is a pointer to the next | ||
block reached by normal control flow. */ | ||
struct _PyCfgBasicblock_ *b_next; | ||
/* number of instructions used */ | ||
int b_iused; | ||
/* length of instruction array (b_instr) */ | ||
int b_ialloc; | ||
/* Used by add_checks_for_loads_of_unknown_variables */ | ||
uint64_t b_unsafe_locals_mask; | ||
/* Number of predecessors that a block has. */ | ||
int b_predecessors; | ||
/* depth of stack upon entry of block, computed by stackdepth() */ | ||
int b_startdepth; | ||
/* instruction offset for block, computed by assemble_jump_offsets() */ | ||
int b_offset; | ||
/* Basic block is an exception handler that preserves lasti */ | ||
unsigned b_preserve_lasti : 1; | ||
/* Used by compiler passes to mark whether they have visited a basic block. */ | ||
unsigned b_visited : 1; | ||
/* b_except_handler is used by the cold-detection algorithm to mark exception targets */ | ||
unsigned b_except_handler : 1; | ||
/* b_cold is true if this block is not perf critical (like an exception handler) */ | ||
unsigned b_cold : 1; | ||
/* b_warm is used by the cold-detection algorithm to mark blocks which are definitely not cold */ | ||
unsigned b_warm : 1; | ||
} _PyCfgBasicblock; | ||
|
||
int _PyBasicblock_InsertInstruction(_PyCfgBasicblock *block, int pos, _PyCfgInstruction *instr); | ||
|
||
typedef struct cfg_builder_ { | ||
/* The entryblock, at which control flow begins. All blocks of the | ||
CFG are reachable through the b_next links */ | ||
_PyCfgBasicblock *g_entryblock; | ||
/* Pointer to the most recently allocated block. By following | ||
b_list links, you can reach all allocated blocks. */ | ||
_PyCfgBasicblock *g_block_list; | ||
/* pointer to the block currently being constructed */ | ||
_PyCfgBasicblock *g_curblock; | ||
/* label for the next instruction to be placed */ | ||
_PyCfgJumpTargetLabel g_current_label; | ||
} _PyCfgBuilder; | ||
|
||
int _PyCfgBuilder_UseLabel(_PyCfgBuilder *g, _PyCfgJumpTargetLabel lbl); | ||
int _PyCfgBuilder_Addop(_PyCfgBuilder *g, int opcode, int oparg, _PyCompilerSrcLocation loc); | ||
|
||
int _PyCfgBuilder_Init(_PyCfgBuilder *g); | ||
void _PyCfgBuilder_Fini(_PyCfgBuilder *g); | ||
|
||
_PyCfgInstruction* _PyCfg_BasicblockLastInstr(const _PyCfgBasicblock *b); | ||
int _PyCfg_OptimizeCodeUnit(_PyCfgBuilder *g, PyObject *consts, PyObject *const_cache, | ||
int code_flags, int nlocals, int nparams); | ||
int _PyCfg_Stackdepth(_PyCfgBasicblock *entryblock, int code_flags); | ||
void _PyCfg_ConvertExceptionHandlersToNops(_PyCfgBasicblock *entryblock); | ||
int _PyCfg_ResolveLineNumbers(_PyCfgBuilder *g, int firstlineno); | ||
int _PyCfg_ResolveJumps(_PyCfgBuilder *g); | ||
int _PyCfg_InstrSize(_PyCfgInstruction *instruction); | ||
|
||
|
||
static inline int | ||
basicblock_nofallthrough(const _PyCfgBasicblock *b) { | ||
_PyCfgInstruction *last = _PyCfg_BasicblockLastInstr(b); | ||
return (last && | ||
(IS_SCOPE_EXIT_OPCODE(last->i_opcode) || | ||
IS_UNCONDITIONAL_JUMP_OPCODE(last->i_opcode))); | ||
} | ||
|
||
#define BB_NO_FALLTHROUGH(B) (basicblock_nofallthrough(B)) | ||
#define BB_HAS_FALLTHROUGH(B) (!basicblock_nofallthrough(B)) | ||
|
||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
#endif /* !Py_INTERNAL_CFG_H */ |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
#ifndef Py_INTERNAL_OPCODE_UTILS_H | ||
#define Py_INTERNAL_OPCODE_UTILS_H | ||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
#ifndef Py_BUILD_CORE | ||
# error "this header requires Py_BUILD_CORE define" | ||
#endif | ||
|
||
#include "pycore_opcode.h" // _PyOpcode_RelativeJump | ||
|
||
|
||
#define MAX_REAL_OPCODE 254 | ||
|
||
#define IS_WITHIN_OPCODE_RANGE(opcode) \ | ||
(((opcode) >= 0 && (opcode) <= MAX_REAL_OPCODE) || \ | ||
IS_PSEUDO_OPCODE(opcode)) | ||
|
||
#define IS_JUMP_OPCODE(opcode) \ | ||
is_bit_set_in_table(_PyOpcode_Jump, opcode) | ||
|
||
#define IS_BLOCK_PUSH_OPCODE(opcode) \ | ||
((opcode) == SETUP_FINALLY || \ | ||
(opcode) == SETUP_WITH || \ | ||
(opcode) == SETUP_CLEANUP) | ||
|
||
#define HAS_TARGET(opcode) \ | ||
(IS_JUMP_OPCODE(opcode) || IS_BLOCK_PUSH_OPCODE(opcode)) | ||
|
||
/* opcodes that must be last in the basicblock */ | ||
#define IS_TERMINATOR_OPCODE(opcode) \ | ||
(IS_JUMP_OPCODE(opcode) || IS_SCOPE_EXIT_OPCODE(opcode)) | ||
|
||
/* opcodes which are not emitted in codegen stage, only by the assembler */ | ||
#define IS_ASSEMBLER_OPCODE(opcode) \ | ||
((opcode) == JUMP_FORWARD || \ | ||
(opcode) == JUMP_BACKWARD || \ | ||
(opcode) == JUMP_BACKWARD_NO_INTERRUPT) | ||
|
||
#define IS_BACKWARDS_JUMP_OPCODE(opcode) \ | ||
((opcode) == JUMP_BACKWARD || \ | ||
(opcode) == JUMP_BACKWARD_NO_INTERRUPT) | ||
|
||
#define IS_UNCONDITIONAL_JUMP_OPCODE(opcode) \ | ||
((opcode) == JUMP || \ | ||
(opcode) == JUMP_NO_INTERRUPT || \ | ||
(opcode) == JUMP_FORWARD || \ | ||
(opcode) == JUMP_BACKWARD || \ | ||
(opcode) == JUMP_BACKWARD_NO_INTERRUPT) | ||
|
||
#define IS_SCOPE_EXIT_OPCODE(opcode) \ | ||
((opcode) == RETURN_VALUE || \ | ||
(opcode) == RETURN_CONST || \ | ||
(opcode) == RAISE_VARARGS || \ | ||
(opcode) == RERAISE) | ||
|
||
#define IS_SUPERINSTRUCTION_OPCODE(opcode) \ | ||
((opcode) == LOAD_FAST__LOAD_FAST || \ | ||
(opcode) == LOAD_FAST__LOAD_CONST || \ | ||
(opcode) == LOAD_CONST__LOAD_FAST || \ | ||
(opcode) == STORE_FAST__LOAD_FAST || \ | ||
(opcode) == STORE_FAST__STORE_FAST) | ||
|
||
#define IS_SCOPE_EXIT_OPCODE(opcode) \ | ||
iritkatriel marked this conversation as resolved.
Show resolved
Hide resolved
|
||
((opcode) == RETURN_VALUE || \ | ||
(opcode) == RETURN_CONST || \ | ||
(opcode) == RAISE_VARARGS || \ | ||
(opcode) == RERAISE) | ||
|
||
#define IS_SUPERINSTRUCTION_OPCODE(opcode) \ | ||
iritkatriel marked this conversation as resolved.
Show resolved
Hide resolved
|
||
((opcode) == LOAD_FAST__LOAD_FAST || \ | ||
(opcode) == LOAD_FAST__LOAD_CONST || \ | ||
(opcode) == LOAD_CONST__LOAD_FAST || \ | ||
(opcode) == STORE_FAST__LOAD_FAST || \ | ||
(opcode) == STORE_FAST__STORE_FAST) | ||
|
||
|
||
#define LOG_BITS_PER_INT 5 | ||
#define MASK_LOW_LOG_BITS 31 | ||
|
||
static inline int | ||
is_bit_set_in_table(const uint32_t *table, int bitindex) { | ||
/* Is the relevant bit set in the relevant word? */ | ||
/* 512 bits fit into 9 32-bits words. | ||
* Word is indexed by (bitindex>>ln(size of int in bits)). | ||
* Bit within word is the low bits of bitindex. | ||
*/ | ||
if (bitindex >= 0 && bitindex < 512) { | ||
uint32_t word = table[bitindex >> LOG_BITS_PER_INT]; | ||
return (word >> (bitindex & MASK_LOW_LOG_BITS)) & 1; | ||
} | ||
else { | ||
return 0; | ||
} | ||
} | ||
|
||
#undef LOG_BITS_PER_INT | ||
#undef MASK_LOW_LOG_BITS | ||
|
||
#define IS_RELATIVE_JUMP(opcode) (is_bit_set_in_table(_PyOpcode_RelativeJump, opcode)) | ||
|
||
|
||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
#endif /* !Py_INTERNAL_OPCODE_UTILS_H */ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.