Skip to content

Commit 3001f90

Browse files
committed
basicblock is local to flowgraph and cfg_builder is opaque
1 parent 3994c3a commit 3001f90

File tree

3 files changed

+70
-74
lines changed

3 files changed

+70
-74
lines changed

Include/internal/pycore_flowgraph.h

Lines changed: 9 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -11,76 +11,24 @@ extern "C" {
1111
#include "pycore_opcode_utils.h"
1212
#include "pycore_compile.h"
1313

14-
1514
typedef struct {
1615
int id;
1716
} _PyCfgJumpTargetLabel;
1817

19-
struct _PyCfgExceptStack;
20-
21-
typedef struct _PyCfgBasicblock_ {
22-
/* Each basicblock in a compilation unit is linked via b_list in the
23-
reverse order that the block are allocated. b_list points to the next
24-
block in this list, not to be confused with b_next, which is next by
25-
control flow. */
26-
struct _PyCfgBasicblock_ *b_list;
27-
/* The label of this block if it is a jump target, -1 otherwise */
28-
_PyCfgJumpTargetLabel b_label;
29-
/* Exception stack at start of block, used by assembler to create the exception handling table */
30-
struct PyCfgExceptStack *b_exceptstack;
31-
/* pointer to an array of instructions, initially NULL */
32-
struct _PyCfgInstruction *b_instr;
33-
/* If b_next is non-NULL, it is a pointer to the next
34-
block reached by normal control flow. */
35-
struct _PyCfgBasicblock_ *b_next;
36-
/* number of instructions used */
37-
int b_iused;
38-
/* length of instruction array (b_instr) */
39-
int b_ialloc;
40-
/* Used by add_checks_for_loads_of_unknown_variables */
41-
uint64_t b_unsafe_locals_mask;
42-
/* Number of predecessors that a block has. */
43-
int b_predecessors;
44-
/* depth of stack upon entry of block, computed by stackdepth() */
45-
int b_startdepth;
46-
/* Basic block is an exception handler that preserves lasti */
47-
unsigned b_preserve_lasti : 1;
48-
/* Used by compiler passes to mark whether they have visited a basic block. */
49-
unsigned b_visited : 1;
50-
/* b_except_handler is used by the cold-detection algorithm to mark exception targets */
51-
unsigned b_except_handler : 1;
52-
/* b_cold is true if this block is not perf critical (like an exception handler) */
53-
unsigned b_cold : 1;
54-
/* b_warm is used by the cold-detection algorithm to mark blocks which are definitely not cold */
55-
unsigned b_warm : 1;
56-
} _PyCfgBasicblock;
57-
58-
59-
typedef struct cfg_builder_ {
60-
/* The entryblock, at which control flow begins. All blocks of the
61-
CFG are reachable through the b_next links */
62-
_PyCfgBasicblock *g_entryblock;
63-
/* Pointer to the most recently allocated block. By following
64-
b_list links, you can reach all allocated blocks. */
65-
_PyCfgBasicblock *g_block_list;
66-
/* pointer to the block currently being constructed */
67-
_PyCfgBasicblock *g_curblock;
68-
/* label for the next instruction to be placed */
69-
_PyCfgJumpTargetLabel g_current_label;
70-
} _PyCfgBuilder;
18+
struct _PyCfgBuilder;
7119

72-
int _PyCfgBuilder_UseLabel(_PyCfgBuilder *g, _PyCfgJumpTargetLabel lbl);
73-
int _PyCfgBuilder_Addop(_PyCfgBuilder *g, int opcode, int oparg, _PyCompilerSrcLocation loc);
20+
int _PyCfgBuilder_UseLabel(struct _PyCfgBuilder *g, _PyCfgJumpTargetLabel lbl);
21+
int _PyCfgBuilder_Addop(struct _PyCfgBuilder *g, int opcode, int oparg, _PyCompilerSrcLocation loc);
7422

75-
_PyCfgBuilder* _PyCfgBuilder_New(void);
76-
void _PyCfgBuilder_Free(_PyCfgBuilder *g);
77-
int _PyCfgBuilder_CheckSize(_PyCfgBuilder* g);
23+
struct _PyCfgBuilder* _PyCfgBuilder_New(void);
24+
void _PyCfgBuilder_Free(struct _PyCfgBuilder *g);
25+
int _PyCfgBuilder_CheckSize(struct _PyCfgBuilder* g);
7826

79-
int _PyCfg_OptimizeCodeUnit(_PyCfgBuilder *g, PyObject *consts, PyObject *const_cache,
27+
int _PyCfg_OptimizeCodeUnit(struct _PyCfgBuilder *g, PyObject *consts, PyObject *const_cache,
8028
int nlocals, int nparams, int firstlineno);
8129

82-
int _PyCfg_ToInstructionSequence(_PyCfgBuilder *g, _PyCompile_InstructionSequence *seq);
83-
int _PyCfg_OptimizedCfgToInstructionSequence(_PyCfgBuilder *g, _PyCompile_CodeUnitMetadata *umd,
30+
int _PyCfg_ToInstructionSequence(struct _PyCfgBuilder *g, _PyCompile_InstructionSequence *seq);
31+
int _PyCfg_OptimizedCfgToInstructionSequence(struct _PyCfgBuilder *g, _PyCompile_CodeUnitMetadata *umd,
8432
int code_flags, int *stackdepth, int *nlocalsplus,
8533
_PyCompile_InstructionSequence *seq);
8634

Python/compile.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@
7070
&& ((C)->u->u_ste->ste_type == ModuleBlock))
7171

7272
typedef _PyCompilerSrcLocation location;
73-
typedef _PyCfgBuilder cfg_builder;
73+
typedef struct _PyCfgBuilder cfg_builder;
7474

7575
#define LOCATION(LNO, END_LNO, COL, END_COL) \
7676
((const _PyCompilerSrcLocation){(LNO), (END_LNO), (COL), (END_COL)})

Python/flowgraph.c

Lines changed: 60 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,65 @@
2424

2525
typedef _PyCompilerSrcLocation location;
2626
typedef _PyCfgJumpTargetLabel jump_target_label;
27-
typedef _PyCfgBasicblock basicblock;
28-
typedef _PyCfgBuilder cfg_builder;
2927

3028
typedef struct _PyCfgInstruction {
3129
int i_opcode;
3230
int i_oparg;
3331
_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 */
3634
} cfg_instr;
3735

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;
3886

3987
static const jump_target_label NO_LABEL = {-1};
4088

@@ -60,7 +108,7 @@ is_jump(cfg_instr *i)
60108
#define INSTR_SET_OP1(I, OP, ARG) \
61109
do { \
62110
assert(OPCODE_HAS_ARG(OP)); \
63-
struct _PyCfgInstruction *_instr__ptr_ = (I); \
111+
cfg_instr *_instr__ptr_ = (I); \
64112
_instr__ptr_->i_opcode = (OP); \
65113
_instr__ptr_->i_oparg = (ARG); \
66114
} while (0);
@@ -69,7 +117,7 @@ is_jump(cfg_instr *i)
69117
#define INSTR_SET_OP0(I, OP) \
70118
do { \
71119
assert(!OPCODE_HAS_ARG(OP)); \
72-
struct _PyCfgInstruction *_instr__ptr_ = (I); \
120+
cfg_instr *_instr__ptr_ = (I); \
73121
_instr__ptr_->i_opcode = (OP); \
74122
_instr__ptr_->i_oparg = 0; \
75123
} while (0);
@@ -158,8 +206,8 @@ basicblock_last_instr(const basicblock *b) {
158206
}
159207

160208
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);
163211
return (last &&
164212
(IS_SCOPE_EXIT_OPCODE(last->i_opcode) ||
165213
IS_UNCONDITIONAL_JUMP_OPCODE(last->i_opcode)));
@@ -494,7 +542,7 @@ normalize_jumps_in_block(cfg_builder *g, basicblock *b) {
494542

495543

496544
static int
497-
normalize_jumps(_PyCfgBuilder *g)
545+
normalize_jumps(cfg_builder *g)
498546
{
499547
basicblock *entryblock = g->g_entryblock;
500548
for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
@@ -565,7 +613,7 @@ translate_jump_labels_to_targets(basicblock *entryblock)
565613
}
566614

567615
int
568-
_PyCfg_JumpLabelsToTargets(_PyCfgBuilder *g)
616+
_PyCfg_JumpLabelsToTargets(cfg_builder *g)
569617
{
570618
return translate_jump_labels_to_targets(g->g_entryblock);
571619
}
@@ -590,7 +638,7 @@ mark_except_handlers(basicblock *entryblock) {
590638

591639

592640
struct _PyCfgExceptStack {
593-
struct _PyCfgBasicblock_ *handlers[CO_MAXBLOCKS+1];
641+
basicblock *handlers[CO_MAXBLOCKS+1];
594642
int depth;
595643
};
596644

@@ -2561,7 +2609,7 @@ _PyCfg_ToInstructionSequence(cfg_builder *g, _PyCompile_InstructionSequence *seq
25612609

25622610

25632611
int
2564-
_PyCfg_OptimizedCfgToInstructionSequence(_PyCfgBuilder *g,
2612+
_PyCfg_OptimizedCfgToInstructionSequence(cfg_builder *g,
25652613
_PyCompile_CodeUnitMetadata *umd, int code_flags,
25662614
int *stackdepth, int *nlocalsplus,
25672615
_PyCompile_InstructionSequence *seq)

0 commit comments

Comments
 (0)