Skip to content

Commit bafedfb

Browse files
authored
gh-106149: move CFG and basicblock definitions into flowgraph.c, use them as opaque types in compile.c (#107639)
1 parent 494e3d4 commit bafedfb

File tree

4 files changed

+482
-478
lines changed

4 files changed

+482
-478
lines changed

Include/internal/pycore_compile.h

+5
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ typedef struct {
5454
int s_next_free_label; /* next free label id */
5555
} _PyCompile_InstructionSequence;
5656

57+
int _PyCompile_InstructionSequence_UseLabel(_PyCompile_InstructionSequence *seq, int lbl);
58+
int _PyCompile_InstructionSequence_Addop(_PyCompile_InstructionSequence *seq,
59+
int opcode, int oparg,
60+
_PyCompilerSrcLocation loc);
61+
5762
typedef struct {
5863
PyObject *u_name;
5964
PyObject *u_qualname; /* dot-separated qualified name (lazy) */

Include/internal/pycore_flowgraph.h

+12-74
Original file line numberDiff line numberDiff line change
@@ -11,88 +11,26 @@ extern "C" {
1111
#include "pycore_opcode_utils.h"
1212
#include "pycore_compile.h"
1313

14-
15-
typedef struct {
16-
int i_opcode;
17-
int i_oparg;
18-
_PyCompilerSrcLocation i_loc;
19-
struct _PyCfgBasicblock_ *i_target; /* target block (if jump instruction) */
20-
struct _PyCfgBasicblock_ *i_except; /* target block when exception is raised */
21-
} _PyCfgInstruction;
22-
2314
typedef struct {
2415
int id;
2516
} _PyCfgJumpTargetLabel;
2617

18+
struct _PyCfgBuilder;
2719

28-
typedef struct {
29-
struct _PyCfgBasicblock_ *handlers[CO_MAXBLOCKS+1];
30-
int depth;
31-
} _PyCfgExceptStack;
32-
33-
typedef struct _PyCfgBasicblock_ {
34-
/* Each basicblock in a compilation unit is linked via b_list in the
35-
reverse order that the block are allocated. b_list points to the next
36-
block in this list, not to be confused with b_next, which is next by
37-
control flow. */
38-
struct _PyCfgBasicblock_ *b_list;
39-
/* The label of this block if it is a jump target, -1 otherwise */
40-
_PyCfgJumpTargetLabel b_label;
41-
/* Exception stack at start of block, used by assembler to create the exception handling table */
42-
_PyCfgExceptStack *b_exceptstack;
43-
/* pointer to an array of instructions, initially NULL */
44-
_PyCfgInstruction *b_instr;
45-
/* If b_next is non-NULL, it is a pointer to the next
46-
block reached by normal control flow. */
47-
struct _PyCfgBasicblock_ *b_next;
48-
/* number of instructions used */
49-
int b_iused;
50-
/* length of instruction array (b_instr) */
51-
int b_ialloc;
52-
/* Used by add_checks_for_loads_of_unknown_variables */
53-
uint64_t b_unsafe_locals_mask;
54-
/* Number of predecessors that a block has. */
55-
int b_predecessors;
56-
/* depth of stack upon entry of block, computed by stackdepth() */
57-
int b_startdepth;
58-
/* Basic block is an exception handler that preserves lasti */
59-
unsigned b_preserve_lasti : 1;
60-
/* Used by compiler passes to mark whether they have visited a basic block. */
61-
unsigned b_visited : 1;
62-
/* b_except_handler is used by the cold-detection algorithm to mark exception targets */
63-
unsigned b_except_handler : 1;
64-
/* b_cold is true if this block is not perf critical (like an exception handler) */
65-
unsigned b_cold : 1;
66-
/* b_warm is used by the cold-detection algorithm to mark blocks which are definitely not cold */
67-
unsigned b_warm : 1;
68-
} _PyCfgBasicblock;
20+
int _PyCfgBuilder_UseLabel(struct _PyCfgBuilder *g, _PyCfgJumpTargetLabel lbl);
21+
int _PyCfgBuilder_Addop(struct _PyCfgBuilder *g, int opcode, int oparg, _PyCompilerSrcLocation loc);
6922

70-
int _PyBasicblock_InsertInstruction(_PyCfgBasicblock *block, int pos, _PyCfgInstruction *instr);
23+
struct _PyCfgBuilder* _PyCfgBuilder_New(void);
24+
void _PyCfgBuilder_Free(struct _PyCfgBuilder *g);
25+
int _PyCfgBuilder_CheckSize(struct _PyCfgBuilder* g);
7126

72-
typedef struct cfg_builder_ {
73-
/* The entryblock, at which control flow begins. All blocks of the
74-
CFG are reachable through the b_next links */
75-
_PyCfgBasicblock *g_entryblock;
76-
/* Pointer to the most recently allocated block. By following
77-
b_list links, you can reach all allocated blocks. */
78-
_PyCfgBasicblock *g_block_list;
79-
/* pointer to the block currently being constructed */
80-
_PyCfgBasicblock *g_curblock;
81-
/* label for the next instruction to be placed */
82-
_PyCfgJumpTargetLabel g_current_label;
83-
} _PyCfgBuilder;
84-
85-
int _PyCfgBuilder_UseLabel(_PyCfgBuilder *g, _PyCfgJumpTargetLabel lbl);
86-
int _PyCfgBuilder_Addop(_PyCfgBuilder *g, int opcode, int oparg, _PyCompilerSrcLocation loc);
87-
88-
int _PyCfgBuilder_Init(_PyCfgBuilder *g);
89-
void _PyCfgBuilder_Fini(_PyCfgBuilder *g);
90-
91-
int _PyCfg_OptimizeCodeUnit(_PyCfgBuilder *g, PyObject *consts, PyObject *const_cache,
27+
int _PyCfg_OptimizeCodeUnit(struct _PyCfgBuilder *g, PyObject *consts, PyObject *const_cache,
9228
int nlocals, int nparams, int firstlineno);
93-
int _PyCfg_Stackdepth(_PyCfgBuilder *g);
94-
void _PyCfg_ConvertPseudoOps(_PyCfgBasicblock *entryblock);
95-
int _PyCfg_ResolveJumps(_PyCfgBuilder *g);
29+
30+
int _PyCfg_ToInstructionSequence(struct _PyCfgBuilder *g, _PyCompile_InstructionSequence *seq);
31+
int _PyCfg_OptimizedCfgToInstructionSequence(struct _PyCfgBuilder *g, _PyCompile_CodeUnitMetadata *umd,
32+
int code_flags, int *stackdepth, int *nlocalsplus,
33+
_PyCompile_InstructionSequence *seq);
9634

9735
PyCodeObject *
9836
_PyAssemble_MakeCodeObject(_PyCompile_CodeUnitMetadata *u, PyObject *const_cache,

0 commit comments

Comments
 (0)