|
85 | 85 | (opcode) == SETUP_WITH || \
|
86 | 86 | (opcode) == SETUP_CLEANUP)
|
87 | 87 |
|
| 88 | +#define HAS_TARGET(opcode) \ |
| 89 | + (IS_JUMP_OPCODE(opcode) || IS_BLOCK_PUSH_OPCODE(opcode)) |
| 90 | + |
88 | 91 | /* opcodes that must be last in the basicblock */
|
89 | 92 | #define IS_TERMINATOR_OPCODE(opcode) \
|
90 | 93 | (IS_JUMP_OPCODE(opcode) || IS_SCOPE_EXIT_OPCODE(opcode))
|
@@ -159,14 +162,10 @@ static struct jump_target_label_ NO_LABEL = {-1};
|
159 | 162 | struct instr {
|
160 | 163 | int i_opcode;
|
161 | 164 | int i_oparg;
|
162 |
| - /* target block (if jump instruction) -- we temporarily have both the label |
163 |
| - and the block in the instr. The label is set by front end, and the block |
164 |
| - is calculated by backend. */ |
165 |
| - jump_target_label i_target_label; |
166 |
| - struct basicblock_ *i_target; |
167 |
| - /* target block when exception is raised, should not be set by front-end. */ |
168 |
| - struct basicblock_ *i_except; |
169 | 165 | struct location i_loc;
|
| 166 | + /* The following fields should not be set by the front-end: */ |
| 167 | + struct basicblock_ *i_target; /* target block (if jump instruction) */ |
| 168 | + struct basicblock_ *i_except; /* target block when exception is raised */ |
170 | 169 | };
|
171 | 170 |
|
172 | 171 | typedef struct exceptstack {
|
@@ -1299,8 +1298,12 @@ basicblock_addop(basicblock *b, int opcode, int oparg,
|
1299 | 1298 | }
|
1300 | 1299 | struct instr *i = &b->b_instr[off];
|
1301 | 1300 | i->i_opcode = opcode;
|
1302 |
| - i->i_oparg = oparg; |
1303 |
| - i->i_target_label = target; |
| 1301 | + if (HAS_TARGET(opcode)) { |
| 1302 | + i->i_oparg = target.id; |
| 1303 | + } |
| 1304 | + else { |
| 1305 | + i->i_oparg = oparg; |
| 1306 | + } |
1304 | 1307 | i->i_target = NULL;
|
1305 | 1308 | i->i_loc = loc;
|
1306 | 1309 |
|
@@ -7085,7 +7088,7 @@ stackdepth(basicblock *entryblock, int code_flags)
|
7085 | 7088 | maxdepth = new_depth;
|
7086 | 7089 | }
|
7087 | 7090 | assert(depth >= 0); /* invalid code or bug in stackdepth() */
|
7088 |
| - if (is_jump(instr) || is_block_push(instr)) { |
| 7091 | + if (HAS_TARGET(instr->i_opcode)) { |
7089 | 7092 | effect = stack_effect(instr->i_opcode, instr->i_oparg, 1);
|
7090 | 7093 | assert(effect != PY_INVALID_STACK_EFFECT);
|
7091 | 7094 | int target_depth = depth + effect;
|
@@ -7412,7 +7415,6 @@ push_cold_blocks_to_end(cfg_builder *g, int code_flags) {
|
7412 | 7415 | /* set target */
|
7413 | 7416 | struct instr *last = basicblock_last_instr(explicit_jump);
|
7414 | 7417 | last->i_target = explicit_jump->b_next;
|
7415 |
| - last->i_target_label = NO_LABEL; |
7416 | 7418 | }
|
7417 | 7419 | }
|
7418 | 7420 |
|
@@ -8218,12 +8220,9 @@ dump_instr(struct instr *i)
|
8218 | 8220 | if (HAS_ARG(i->i_opcode)) {
|
8219 | 8221 | sprintf(arg, "arg: %d ", i->i_oparg);
|
8220 | 8222 | }
|
8221 |
| - if (is_jump(i)) { |
| 8223 | + if (HAS_TARGET(i->i_opcode)) { |
8222 | 8224 | sprintf(arg, "target: %p ", i->i_target);
|
8223 | 8225 | }
|
8224 |
| - if (is_block_push(i)) { |
8225 |
| - sprintf(arg, "except_target: %p ", i->i_target); |
8226 |
| - } |
8227 | 8226 | fprintf(stderr, "line: %d, opcode: %d %s%s%s\n",
|
8228 | 8227 | i->i_loc.lineno, i->i_opcode, arg, jabs, jrel);
|
8229 | 8228 | }
|
@@ -8966,7 +8965,7 @@ optimize_basic_block(PyObject *const_cache, basicblock *bb, PyObject *consts)
|
8966 | 8965 | struct instr *inst = &bb->b_instr[i];
|
8967 | 8966 | int oparg = inst->i_oparg;
|
8968 | 8967 | int nextop = i+1 < bb->b_iused ? bb->b_instr[i+1].i_opcode : 0;
|
8969 |
| - if (is_jump(inst) || is_block_push(inst)) { |
| 8968 | + if (HAS_TARGET(inst->i_opcode)) { |
8970 | 8969 | /* Skip over empty basic blocks. */
|
8971 | 8970 | while (inst->i_target->b_iused == 0) {
|
8972 | 8971 | inst->i_target = inst->i_target->b_next;
|
@@ -9371,7 +9370,7 @@ eliminate_empty_basic_blocks(basicblock *entryblock) {
|
9371 | 9370 | }
|
9372 | 9371 | for (int i = 0; i < b->b_iused; i++) {
|
9373 | 9372 | struct instr *instr = &b->b_instr[i];
|
9374 |
| - if (is_jump(instr) || is_block_push(instr)) { |
| 9373 | + if (HAS_TARGET(instr->i_opcode)) { |
9375 | 9374 | basicblock *target = instr->i_target;
|
9376 | 9375 | while (target->b_iused == 0) {
|
9377 | 9376 | target = target->b_next;
|
@@ -9450,14 +9449,13 @@ calculate_jump_targets(basicblock *entryblock)
|
9450 | 9449 | for (int i = 0; i < b->b_iused; i++) {
|
9451 | 9450 | struct instr *instr = &b->b_instr[i];
|
9452 | 9451 | assert(instr->i_target == NULL);
|
9453 |
| - if (is_jump(instr) || is_block_push(instr)) { |
9454 |
| - int lbl = instr->i_target_label.id; |
| 9452 | + if (HAS_TARGET(instr->i_opcode)) { |
| 9453 | + int lbl = instr->i_oparg; |
9455 | 9454 | assert(lbl >= 0 && lbl <= max_label);
|
9456 | 9455 | instr->i_target = label2block[lbl];
|
9457 | 9456 | assert(instr->i_target != NULL);
|
9458 | 9457 | assert(instr->i_target->b_label == lbl);
|
9459 | 9458 | }
|
9460 |
| - instr->i_target_label = NO_LABEL; |
9461 | 9459 | }
|
9462 | 9460 | }
|
9463 | 9461 | PyMem_Free(label2block);
|
|
0 commit comments