[Python-checkins] gh-93008: refactor compiler functions that add instructions to take only a basicblock* (not the whole compiler) (GH-93009)
iritkatriel
webhook-mailer at python.org
Sun May 29 12:13:41 EDT 2022
https://github.com/python/cpython/commit/ace6607aa33da42972369ada2c565912e329bf5e
commit: ace6607aa33da42972369ada2c565912e329bf5e
branch: main
author: Irit Katriel <1055913+iritkatriel at users.noreply.github.com>
committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com>
date: 2022-05-29T17:13:29+01:00
summary:
gh-93008: refactor compiler functions that add instructions to take only a basicblock* (not the whole compiler) (GH-93009)
files:
M Python/compile.c
diff --git a/Python/compile.c b/Python/compile.c
index 541fa4c9a12b9..0920cebfe7c13 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -264,6 +264,15 @@ typedef struct basicblock_ {
unsigned b_return : 1;
} basicblock;
+
+static struct instr *
+basicblock_last_instr(basicblock *b) {
+ if (b->b_iused) {
+ return &b->b_instr[b->b_iused - 1];
+ }
+ return NULL;
+}
+
/* fblockinfo tracks the current frame block.
A frame block is used to handle loops, try/except, and try/finally.
@@ -331,9 +340,6 @@ struct compiler_unit {
int u_col_offset; /* the offset of the current stmt */
int u_end_lineno; /* the end line of the current stmt */
int u_end_col_offset; /* the end offset of the current stmt */
-
- /* true if we need to create an implicit basicblock before the next instr */
- int u_need_new_implicit_block;
};
/* This struct captures the global state of a compilation.
@@ -389,10 +395,11 @@ typedef struct {
Py_ssize_t on_top;
} pattern_context;
+static int basicblock_next_instr(basicblock *);
+
static int compiler_enter_scope(struct compiler *, identifier, int, void *, int);
static void compiler_free(struct compiler *);
static basicblock *compiler_new_block(struct compiler *);
-static int compiler_next_instr(basicblock *);
static int compiler_addop(struct compiler *, int);
static int compiler_addop_i(struct compiler *, int, Py_ssize_t);
static int compiler_addop_j(struct compiler *, int, basicblock *);
@@ -830,7 +837,6 @@ compiler_use_next_block(struct compiler *c, basicblock *block)
assert(block != NULL);
c->u->u_curblock->b_next = block;
c->u->u_curblock = block;
- c->u->u_need_new_implicit_block = 0;
return block;
}
@@ -846,7 +852,7 @@ compiler_copy_block(struct compiler *c, basicblock *block)
return NULL;
}
for (int i = 0; i < block->b_iused; i++) {
- int n = compiler_next_instr(result);
+ int n = basicblock_next_instr(result);
if (n < 0) {
return NULL;
}
@@ -863,7 +869,7 @@ compiler_copy_block(struct compiler *c, basicblock *block)
*/
static int
-compiler_next_instr(basicblock *b)
+basicblock_next_instr(basicblock *b)
{
assert(b != NULL);
if (b->b_instr == NULL) {
@@ -1206,7 +1212,8 @@ PyCompile_OpcodeStackEffect(int opcode, int oparg)
return stack_effect(opcode, oparg, -1);
}
-static int is_end_of_basic_block(struct instr *instr)
+static int
+is_end_of_basic_block(struct instr *instr)
{
int opcode = instr->i_opcode;
@@ -1219,7 +1226,8 @@ static int is_end_of_basic_block(struct instr *instr)
static int
compiler_use_new_implicit_block_if_needed(struct compiler *c)
{
- if (c->u->u_need_new_implicit_block) {
+ basicblock *b = c->u->u_curblock;
+ if (b->b_iused && is_end_of_basic_block(basicblock_last_instr(b))) {
basicblock *b = compiler_new_block(c);
if (b == NULL) {
return -1;
@@ -1229,32 +1237,19 @@ compiler_use_new_implicit_block_if_needed(struct compiler *c)
return 0;
}
-static void
-compiler_check_if_end_of_block(struct compiler *c, struct instr *instr)
-{
- if (is_end_of_basic_block(instr)) {
- c->u->u_need_new_implicit_block = 1;
- }
-}
-
/* Add an opcode with no argument.
Returns 0 on failure, 1 on success.
*/
static int
-compiler_addop_line(struct compiler *c, int opcode, int line,
- int end_line, int col_offset, int end_col_offset)
+basicblock_addop_line(basicblock *b, int opcode, int line,
+ int end_line, int col_offset, int end_col_offset)
{
assert(IS_WITHIN_OPCODE_RANGE(opcode));
assert(!IS_ASSEMBLER_OPCODE(opcode));
assert(!HAS_ARG(opcode) || IS_ARTIFICIAL(opcode));
- if (compiler_use_new_implicit_block_if_needed(c) < 0) {
- return -1;
- }
-
- basicblock *b = c->u->u_curblock;
- int off = compiler_next_instr(b);
+ int off = basicblock_next_instr(b);
if (off < 0) {
return 0;
}
@@ -1269,21 +1264,26 @@ compiler_addop_line(struct compiler *c, int opcode, int line,
i->i_col_offset = col_offset;
i->i_end_col_offset = end_col_offset;
- compiler_check_if_end_of_block(c, i);
return 1;
}
static int
compiler_addop(struct compiler *c, int opcode)
{
- return compiler_addop_line(c, opcode, c->u->u_lineno, c->u->u_end_lineno,
- c->u->u_col_offset, c->u->u_end_col_offset);
+ if (compiler_use_new_implicit_block_if_needed(c) < 0) {
+ return -1;
+ }
+ return basicblock_addop_line(c->u->u_curblock, opcode, c->u->u_lineno, c->u->u_end_lineno,
+ c->u->u_col_offset, c->u->u_end_col_offset);
}
static int
compiler_addop_noline(struct compiler *c, int opcode)
{
- return compiler_addop_line(c, opcode, -1, 0, 0, 0);
+ if (compiler_use_new_implicit_block_if_needed(c) < 0) {
+ return -1;
+ }
+ return basicblock_addop_line(c->u->u_curblock, opcode, -1, 0, 0, 0);
}
@@ -1477,9 +1477,9 @@ compiler_addop_name(struct compiler *c, int opcode, PyObject *dict,
*/
static int
-compiler_addop_i_line(struct compiler *c, int opcode, Py_ssize_t oparg,
- int lineno, int end_lineno,
- int col_offset, int end_col_offset)
+basicblock_addop_i_line(basicblock *b, int opcode, Py_ssize_t oparg,
+ int lineno, int end_lineno,
+ int col_offset, int end_col_offset)
{
/* oparg value is unsigned, but a signed C int is usually used to store
it in the C code (like Python/ceval.c).
@@ -1494,12 +1494,7 @@ compiler_addop_i_line(struct compiler *c, int opcode, Py_ssize_t oparg,
assert(HAS_ARG(opcode));
assert(0 <= oparg && oparg <= 2147483647);
- if (compiler_use_new_implicit_block_if_needed(c) < 0) {
- return -1;
- }
-
- basicblock *b = c->u->u_curblock;
- int off = compiler_next_instr(b);
+ int off = basicblock_next_instr(b);
if (off < 0) {
return 0;
}
@@ -1511,40 +1506,41 @@ compiler_addop_i_line(struct compiler *c, int opcode, Py_ssize_t oparg,
i->i_col_offset = col_offset;
i->i_end_col_offset = end_col_offset;
- compiler_check_if_end_of_block(c, i);
return 1;
}
static int
compiler_addop_i(struct compiler *c, int opcode, Py_ssize_t oparg)
{
- return compiler_addop_i_line(c, opcode, oparg,
- c->u->u_lineno, c->u->u_end_lineno,
- c->u->u_col_offset, c->u->u_end_col_offset);
+ if (compiler_use_new_implicit_block_if_needed(c) < 0) {
+ return -1;
+ }
+ return basicblock_addop_i_line(c->u->u_curblock, opcode, oparg,
+ c->u->u_lineno, c->u->u_end_lineno,
+ c->u->u_col_offset, c->u->u_end_col_offset);
}
static int
compiler_addop_i_noline(struct compiler *c, int opcode, Py_ssize_t oparg)
{
- return compiler_addop_i_line(c, opcode, oparg, -1, 0, 0, 0);
+ if (compiler_use_new_implicit_block_if_needed(c) < 0) {
+ return -1;
+ }
+ return basicblock_addop_i_line(c->u->u_curblock, opcode, oparg, -1, 0, 0, 0);
}
-static int add_jump_to_block(struct compiler *c, int opcode,
- int lineno, int end_lineno,
- int col_offset, int end_col_offset,
- basicblock *target)
+static int
+basicblock_add_jump(basicblock *b, int opcode,
+ int lineno, int end_lineno,
+ int col_offset, int end_col_offset,
+ basicblock *target)
{
assert(IS_WITHIN_OPCODE_RANGE(opcode));
assert(!IS_ASSEMBLER_OPCODE(opcode));
assert(HAS_ARG(opcode) || IS_VIRTUAL_OPCODE(opcode));
assert(target != NULL);
- if (compiler_use_new_implicit_block_if_needed(c) < 0) {
- return -1;
- }
-
- basicblock *b = c->u->u_curblock;
- int off = compiler_next_instr(b);
+ int off = basicblock_next_instr(b);
struct instr *i = &b->b_instr[off];
if (off < 0) {
return 0;
@@ -1556,22 +1552,27 @@ static int add_jump_to_block(struct compiler *c, int opcode,
i->i_col_offset = col_offset;
i->i_end_col_offset = end_col_offset;
- compiler_check_if_end_of_block(c, i);
return 1;
}
static int
compiler_addop_j(struct compiler *c, int opcode, basicblock *b)
{
- return add_jump_to_block(c, opcode, c->u->u_lineno,
- c->u->u_end_lineno, c->u->u_col_offset,
- c->u->u_end_col_offset, b);
+ if (compiler_use_new_implicit_block_if_needed(c) < 0) {
+ return -1;
+ }
+ return basicblock_add_jump(c->u->u_curblock, opcode, c->u->u_lineno,
+ c->u->u_end_lineno, c->u->u_col_offset,
+ c->u->u_end_col_offset, b);
}
static int
compiler_addop_j_noline(struct compiler *c, int opcode, basicblock *b)
{
- return add_jump_to_block(c, opcode, -1, 0, 0, 0, b);
+ if (compiler_use_new_implicit_block_if_needed(c) < 0) {
+ return -1;
+ }
+ return basicblock_add_jump(c->u->u_curblock, opcode, -1, 0, 0, 0, b);
}
#define ADDOP(C, OP) { \
@@ -8085,7 +8086,7 @@ build_cellfixedoffsets(struct compiler *c)
static inline int
insert_instruction(basicblock *block, int pos, struct instr *instr) {
- if (compiler_next_instr(block) < 0) {
+ if (basicblock_next_instr(block) < 0) {
return -1;
}
for (int i = block->b_iused-1; i > pos; i--) {
@@ -8971,7 +8972,7 @@ extend_block(basicblock *bb) {
basicblock *to_copy = last->i_target;
last->i_opcode = NOP;
for (int i = 0; i < to_copy->b_iused; i++) {
- int index = compiler_next_instr(bb);
+ int index = basicblock_next_instr(bb);
if (index < 0) {
return -1;
}
More information about the Python-checkins
mailing list