24
24
25
25
typedef _PyCompilerSrcLocation location ;
26
26
typedef _PyCfgJumpTargetLabel jump_target_label ;
27
- typedef _PyCfgBasicblock basicblock ;
28
- typedef _PyCfgBuilder cfg_builder ;
29
27
30
28
typedef struct _PyCfgInstruction {
31
29
int i_opcode ;
32
30
int i_oparg ;
33
31
_PyCompilerSrcLocation i_loc ;
34
- struct _PyCfgBasicblock_ * i_target ; /* target block (if jump instruction) */
35
- struct _PyCfgBasicblock_ * i_except ; /* target block when exception is raised */
32
+ struct _PyCfgBasicblock * i_target ; /* target block (if jump instruction) */
33
+ struct _PyCfgBasicblock * i_except ; /* target block when exception is raised */
36
34
} cfg_instr ;
37
35
36
+ typedef struct _PyCfgBasicblock {
37
+ /* Each basicblock in a compilation unit is linked via b_list in the
38
+ reverse order that the block are allocated. b_list points to the next
39
+ block in this list, not to be confused with b_next, which is next by
40
+ control flow. */
41
+ struct _PyCfgBasicblock * b_list ;
42
+ /* The label of this block if it is a jump target, -1 otherwise */
43
+ _PyCfgJumpTargetLabel b_label ;
44
+ /* Exception stack at start of block, used by assembler to create the exception handling table */
45
+ struct PyCfgExceptStack * b_exceptstack ;
46
+ /* pointer to an array of instructions, initially NULL */
47
+ cfg_instr * b_instr ;
48
+ /* If b_next is non-NULL, it is a pointer to the next
49
+ block reached by normal control flow. */
50
+ struct _PyCfgBasicblock * b_next ;
51
+ /* number of instructions used */
52
+ int b_iused ;
53
+ /* length of instruction array (b_instr) */
54
+ int b_ialloc ;
55
+ /* Used by add_checks_for_loads_of_unknown_variables */
56
+ uint64_t b_unsafe_locals_mask ;
57
+ /* Number of predecessors that a block has. */
58
+ int b_predecessors ;
59
+ /* depth of stack upon entry of block, computed by stackdepth() */
60
+ int b_startdepth ;
61
+ /* Basic block is an exception handler that preserves lasti */
62
+ unsigned b_preserve_lasti : 1 ;
63
+ /* Used by compiler passes to mark whether they have visited a basic block. */
64
+ unsigned b_visited : 1 ;
65
+ /* b_except_handler is used by the cold-detection algorithm to mark exception targets */
66
+ unsigned b_except_handler : 1 ;
67
+ /* b_cold is true if this block is not perf critical (like an exception handler) */
68
+ unsigned b_cold : 1 ;
69
+ /* b_warm is used by the cold-detection algorithm to mark blocks which are definitely not cold */
70
+ unsigned b_warm : 1 ;
71
+ } basicblock ;
72
+
73
+
74
+ typedef struct _PyCfgBuilder {
75
+ /* The entryblock, at which control flow begins. All blocks of the
76
+ CFG are reachable through the b_next links */
77
+ struct _PyCfgBasicblock * g_entryblock ;
78
+ /* Pointer to the most recently allocated block. By following
79
+ b_list links, you can reach all allocated blocks. */
80
+ struct _PyCfgBasicblock * g_block_list ;
81
+ /* pointer to the block currently being constructed */
82
+ struct _PyCfgBasicblock * g_curblock ;
83
+ /* label for the next instruction to be placed */
84
+ _PyCfgJumpTargetLabel g_current_label ;
85
+ } cfg_builder ;
38
86
39
87
static const jump_target_label NO_LABEL = {-1 };
40
88
@@ -60,7 +108,7 @@ is_jump(cfg_instr *i)
60
108
#define INSTR_SET_OP1 (I , OP , ARG ) \
61
109
do { \
62
110
assert(OPCODE_HAS_ARG(OP)); \
63
- struct _PyCfgInstruction *_instr__ptr_ = (I); \
111
+ cfg_instr *_instr__ptr_ = (I); \
64
112
_instr__ptr_->i_opcode = (OP); \
65
113
_instr__ptr_->i_oparg = (ARG); \
66
114
} while (0);
@@ -69,7 +117,7 @@ is_jump(cfg_instr *i)
69
117
#define INSTR_SET_OP0 (I , OP ) \
70
118
do { \
71
119
assert(!OPCODE_HAS_ARG(OP)); \
72
- struct _PyCfgInstruction *_instr__ptr_ = (I); \
120
+ cfg_instr *_instr__ptr_ = (I); \
73
121
_instr__ptr_->i_opcode = (OP); \
74
122
_instr__ptr_->i_oparg = 0; \
75
123
} while (0);
@@ -158,8 +206,8 @@ basicblock_last_instr(const basicblock *b) {
158
206
}
159
207
160
208
static inline int
161
- basicblock_nofallthrough (const _PyCfgBasicblock * b ) {
162
- struct _PyCfgInstruction * last = basicblock_last_instr (b );
209
+ basicblock_nofallthrough (const basicblock * b ) {
210
+ cfg_instr * last = basicblock_last_instr (b );
163
211
return (last &&
164
212
(IS_SCOPE_EXIT_OPCODE (last -> i_opcode ) ||
165
213
IS_UNCONDITIONAL_JUMP_OPCODE (last -> i_opcode )));
@@ -494,7 +542,7 @@ normalize_jumps_in_block(cfg_builder *g, basicblock *b) {
494
542
495
543
496
544
static int
497
- normalize_jumps (_PyCfgBuilder * g )
545
+ normalize_jumps (cfg_builder * g )
498
546
{
499
547
basicblock * entryblock = g -> g_entryblock ;
500
548
for (basicblock * b = entryblock ; b != NULL ; b = b -> b_next ) {
@@ -565,7 +613,7 @@ translate_jump_labels_to_targets(basicblock *entryblock)
565
613
}
566
614
567
615
int
568
- _PyCfg_JumpLabelsToTargets (_PyCfgBuilder * g )
616
+ _PyCfg_JumpLabelsToTargets (cfg_builder * g )
569
617
{
570
618
return translate_jump_labels_to_targets (g -> g_entryblock );
571
619
}
@@ -590,7 +638,7 @@ mark_except_handlers(basicblock *entryblock) {
590
638
591
639
592
640
struct _PyCfgExceptStack {
593
- struct _PyCfgBasicblock_ * handlers [CO_MAXBLOCKS + 1 ];
641
+ basicblock * handlers [CO_MAXBLOCKS + 1 ];
594
642
int depth ;
595
643
};
596
644
@@ -2561,7 +2609,7 @@ _PyCfg_ToInstructionSequence(cfg_builder *g, _PyCompile_InstructionSequence *seq
2561
2609
2562
2610
2563
2611
int
2564
- _PyCfg_OptimizedCfgToInstructionSequence (_PyCfgBuilder * g ,
2612
+ _PyCfg_OptimizedCfgToInstructionSequence (cfg_builder * g ,
2565
2613
_PyCompile_CodeUnitMetadata * umd , int code_flags ,
2566
2614
int * stackdepth , int * nlocalsplus ,
2567
2615
_PyCompile_InstructionSequence * seq )
0 commit comments