Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork33.7k
GH-93678: reduce boilerplate and code repetition in the compiler#93682
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Merged
Uh oh!
There was an error while loading.Please reload this page.
Merged
Changes from3 commits
Commits
Show all changes
18 commits Select commitHold shift + click to select a range
996be64 move line/noline to arg and remove _noline version of functions
iritkatrielaf31e92 add struct location to reduce boilerplate
iritkatrielf8a0767 merge basicblock_addop, basicblock_addop_i and basicblock_add_jump in…
iritkatriel430b4b9 add news
iritkatriel66d5609 assume that oparg is < (1<<30)
iritkatriel7670a7c Merge remote-tracking branch 'upstream/main' into codegen-reduce-repe…
iritkatriel7d74572 use the new location struct for the compiler unit's location
iritkatriel016ebbc use the new location struct for the instruction location
iritkatriel5e06cad basicblock_addop takes location by reference
iritkatrielc23e2cf LOCATION needs to return a const
iritkatrielfc74555 define static no_location in function scope
iritkatriel9220fc1 are we const now?
iritkatriel9b5dc34 trivial stuff
iritkatriel5330060 Merge remote-tracking branch 'upstream/main' into codegen-reduce-repe…
iritkatriel414e26a remove two unused fields from struct assembler
iritkatriel26dc190 define NO_LOCATION as a static const in global scope
iritkatriel98d24f2 Merge remote-tracking branch 'upstream/main' into codegen-reduce-repe…
iritkatriel7851ccd Merge remote-tracking branch 'upstream/main' into codegen-reduce-repe…
iritkatrielFile filter
Filter by extension
Conversations
Failed to load comments.
Loading
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Jump to file
Failed to load files.
Loading
Uh oh!
There was an error while loading.Please reload this page.
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -105,6 +105,11 @@ | ||
| (IS_VIRTUAL_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) | ||
| /* opcodes which are not emitted in codegen stage, only by the assembler */ | ||
| #define IS_ASSEMBLER_OPCODE(opcode) \ | ||
| ((opcode) == JUMP_FORWARD || \ | ||
| @@ -191,7 +196,7 @@ static inline int | ||
| is_block_push(struct instr *instr) | ||
| { | ||
| int opcode = instr->i_opcode; | ||
| returnIS_BLOCK_PUSH_OPCODE(opcode); | ||
| } | ||
| static inline int | ||
| @@ -432,10 +437,9 @@ 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_addop(struct compiler *, int, bool); | ||
| static int compiler_addop_i(struct compiler *, int, Py_ssize_t, bool); | ||
| static int compiler_addop_j(struct compiler *, int, basicblock *, bool); | ||
| static int compiler_error(struct compiler *, const char *, ...); | ||
| static int compiler_warn(struct compiler *, const char *, ...); | ||
| static int compiler_nameop(struct compiler *, identifier, expr_context_ty); | ||
| @@ -967,6 +971,25 @@ basicblock_next_instr(basicblock *b) | ||
| (new).i_end_lineno = (old).i_end_lineno; \ | ||
| (new).i_end_col_offset = (old).i_end_col_offset; | ||
| struct location { | ||
| int lineno; | ||
| int end_lineno; | ||
| int col_offset; | ||
| int end_col_offset; | ||
| }; | ||
| #define NO_LOCATION ((struct location){-1, 0, 0, 0}) | ||
| /* current compiler unit's location */ | ||
| #define CU_LOCATION(CU) \ | ||
| ((struct location){ \ | ||
| (CU)->u_lineno, \ | ||
| (CU)->u_end_lineno, \ | ||
| (CU)->u_col_offset, \ | ||
| (CU)->u_end_col_offset, \ | ||
| }) | ||
| /* Return the stack effect of opcode with argument oparg. | ||
| Some opcodes have different stack effect when jump to the target and | ||
| @@ -1269,48 +1292,46 @@ compiler_use_new_implicit_block_if_needed(struct compiler *c) | ||
| */ | ||
| static int | ||
| basicblock_addop(basicblock *b, int opcode, intoparg, | ||
| basicblock *target, struct location loc) | ||
| { | ||
| assert(IS_WITHIN_OPCODE_RANGE(opcode)); | ||
| assert(!IS_ASSEMBLER_OPCODE(opcode)); | ||
| assert(HAS_ARG(opcode) || oparg == 0); | ||
| assert(0 <= oparg && oparg <= 2147483647); | ||
iritkatriel marked this conversation as resolved. OutdatedShow resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| assert((target == NULL) || | ||
| IS_JUMP_OPCODE(opcode) || | ||
| IS_BLOCK_PUSH_OPCODE(opcode)); | ||
| assert(oparg == 0 || target == NULL); | ||
| int off = basicblock_next_instr(b); | ||
| if (off < 0) { | ||
| return 0; | ||
| } | ||
| struct instr *i = &b->b_instr[off]; | ||
| i->i_opcode = opcode; | ||
| i->i_oparg = oparg; | ||
| i->i_target = target; | ||
| i->i_lineno = loc.lineno; | ||
| i->i_end_lineno = loc.end_lineno; | ||
| i->i_col_offset = loc.col_offset; | ||
| i->i_end_col_offset = loc.end_col_offset; | ||
| return 1; | ||
| } | ||
| static int | ||
| compiler_addop(struct compiler *c, int opcode, bool line) | ||
| { | ||
| assert(!HAS_ARG(opcode) || IS_ARTIFICIAL(opcode)); | ||
| if (compiler_use_new_implicit_block_if_needed(c) < 0) { | ||
| return -1; | ||
| } | ||
| struct location loc = line ? CU_LOCATION(c->u) : NO_LOCATION; | ||
| return basicblock_addop(c->u->u_curblock, opcode, 0, NULL, loc); | ||
| } | ||
| static Py_ssize_t | ||
| compiler_add_o(PyObject *dict, PyObject *o) | ||
| { | ||
| @@ -1467,7 +1488,7 @@ compiler_addop_load_const(struct compiler *c, PyObject *o) | ||
| Py_ssize_t arg = compiler_add_const(c, o); | ||
| if (arg < 0) | ||
| return 0; | ||
| return compiler_addop_i(c, LOAD_CONST, arg, true); | ||
| } | ||
| static int | ||
| @@ -1477,7 +1498,7 @@ compiler_addop_o(struct compiler *c, int opcode, PyObject *dict, | ||
| Py_ssize_t arg = compiler_add_o(dict, o); | ||
| if (arg < 0) | ||
| return 0; | ||
| return compiler_addop_i(c, opcode, arg, true); | ||
| } | ||
| static int | ||
| @@ -1493,18 +1514,18 @@ compiler_addop_name(struct compiler *c, int opcode, PyObject *dict, | ||
| Py_DECREF(mangled); | ||
| if (arg < 0) | ||
| return 0; | ||
| return compiler_addop_i(c, opcode, arg, true); | ||
| } | ||
| /* Add an opcode with an integer argument. | ||
| Returns 0 on failure, 1 on success. | ||
| */ | ||
| static int | ||
| compiler_addop_i(struct compiler *c, int opcode, Py_ssize_t oparg, bool line) | ||
| { | ||
| if (compiler_use_new_implicit_block_if_needed(c) < 0) { | ||
| return -1; | ||
| } | ||
| /* oparg value is unsigned, but a signed C int is usually used to store | ||
| it in the C code (like Python/ceval.c). | ||
| @@ -1513,104 +1534,36 @@ basicblock_addop_i_line(basicblock *b, int opcode, Py_ssize_t oparg, | ||
| The argument of a concrete bytecode instruction is limited to 8-bit. | ||
| EXTENDED_ARG is used for 16, 24, and 32-bit arguments. */ | ||
| int oparg_ = Py_SAFE_DOWNCAST(oparg, Py_ssize_t, int); | ||
| struct location loc = line ? CU_LOCATION(c->u) : NO_LOCATION; | ||
| return basicblock_addop(c->u->u_curblock, opcode, oparg_, NULL, loc); | ||
| } | ||
| static int | ||
| compiler_addop_j(struct compiler *c, int opcode,basicblock *target, bool line) | ||
| { | ||
| if (compiler_use_new_implicit_block_if_needed(c) < 0) { | ||
| return -1; | ||
| } | ||
| struct location loc = line ? CU_LOCATION(c->u) : NO_LOCATION; | ||
| assert(target != NULL); | ||
| assert(IS_JUMP_OPCODE(opcode) || IS_BLOCK_PUSH_OPCODE(opcode)); | ||
| return basicblock_addop(c->u->u_curblock, opcode, 0, target, loc); | ||
| } | ||
| #define ADDOP(C, OP) { \ | ||
| if (!compiler_addop((C), (OP), true)) \ | ||
| return 0; \ | ||
| } | ||
| #define ADDOP_NOLINE(C, OP) { \ | ||
| if (!compiler_addop((C), (OP), false)) \ | ||
| return 0; \ | ||
| } | ||
| #define ADDOP_IN_SCOPE(C, OP) { \ | ||
| if (!compiler_addop((C), (OP), true)) { \ | ||
| compiler_exit_scope(c); \ | ||
| return 0; \ | ||
| } \ | ||
| @@ -1649,25 +1602,25 @@ compiler_addop_j_noline(struct compiler *c, int opcode, basicblock *b) | ||
| } | ||
| #define ADDOP_I(C, OP, O) { \ | ||
| if (!compiler_addop_i((C), (OP), (O), true)) \ | ||
| return 0; \ | ||
| } | ||
| #define ADDOP_I_NOLINE(C, OP, O) { \ | ||
| if (!compiler_addop_i((C), (OP), (O), false)) \ | ||
| return 0; \ | ||
| } | ||
| #define ADDOP_JUMP(C, OP, O) { \ | ||
| if (!compiler_addop_j((C), (OP), (O), true)) \ | ||
| return 0; \ | ||
| } | ||
| /* Add a jump with no line number. | ||
| * Used for artificial jumps that have no corresponding | ||
| * token in the source code. */ | ||
| #define ADDOP_JUMP_NOLINE(C, OP, O) { \ | ||
| if (!compiler_addop_j((C), (OP), (O), false)) \ | ||
| return 0; \ | ||
| } | ||
| @@ -4320,7 +4273,7 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx) | ||
| if (op == LOAD_GLOBAL) { | ||
| arg <<= 1; | ||
| } | ||
| return compiler_addop_i(c, op, arg, true); | ||
| } | ||
| static int | ||
| @@ -6299,7 +6252,7 @@ emit_and_reset_fail_pop(struct compiler *c, pattern_context *pc) | ||
| } | ||
| while (--pc->fail_pop_size) { | ||
| compiler_use_next_block(c, pc->fail_pop[pc->fail_pop_size]); | ||
| if (!compiler_addop(c, POP_TOP, true)) { | ||
| pc->fail_pop_size = 0; | ||
| PyObject_Free(pc->fail_pop); | ||
| pc->fail_pop = NULL; | ||
| @@ -6733,7 +6686,7 @@ compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc) | ||
| pc->fail_pop = NULL; | ||
| pc->fail_pop_size = 0; | ||
| pc->on_top = 0; | ||
| if (!compiler_addop_i(c, COPY, 1, true) || !compiler_pattern(c, alt, pc)) { | ||
| goto error; | ||
| } | ||
| // Success! | ||
| @@ -6796,7 +6749,7 @@ compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc) | ||
| } | ||
| } | ||
| assert(control); | ||
| if (!compiler_addop_j(c, JUMP, end, true) || | ||
| !emit_and_reset_fail_pop(c, pc)) | ||
| { | ||
| goto error; | ||
| @@ -6808,7 +6761,7 @@ compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc) | ||
| // Need to NULL this for the PyObject_Free call in the error block. | ||
| old_pc.fail_pop = NULL; | ||
| // No match. Pop the remaining copy of the subject and fail: | ||
| if (!compiler_addop(c, POP_TOP, true) || !jump_to_fail_pop(c, pc, JUMP)) { | ||
| goto error; | ||
| } | ||
| compiler_use_next_block(c, end); | ||
| @@ -7471,7 +7424,7 @@ push_cold_blocks_to_end(struct compiler *c, basicblock *entry, int code_flags) { | ||
| if (explicit_jump == NULL) { | ||
| return -1; | ||
| } | ||
| basicblock_addop(explicit_jump, JUMP, 0, b->b_next, NO_LOCATION); | ||
| explicit_jump->b_cold = 1; | ||
| explicit_jump->b_next = b->b_next; | ||
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.