mirror of
				https://github.com/python/cpython.git
				synced 2025-10-30 21:21:22 +00:00 
			
		
		
		
	GH-125837: Split LOAD_CONST into three. (GH-125972)
				
					
				
			* Add LOAD_CONST_IMMORTAL opcode * Add LOAD_SMALL_INT opcode * Remove RETURN_CONST opcode
This commit is contained in:
		
							parent
							
								
									67f5c5bd6f
								
							
						
					
					
						commit
						faa3272fb8
					
				
					 33 changed files with 706 additions and 538 deletions
				
			
		|  | @ -283,7 +283,7 @@ dump_instr(cfg_instr *i) | |||
| static inline int | ||||
| basicblock_returns(const basicblock *b) { | ||||
|     cfg_instr *last = basicblock_last_instr(b); | ||||
|     return last && (last->i_opcode == RETURN_VALUE || last->i_opcode == RETURN_CONST); | ||||
|     return last && last->i_opcode == RETURN_VALUE; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
|  | @ -515,22 +515,6 @@ no_redundant_jumps(cfg_builder *g) { | |||
|     } | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| static bool | ||||
| all_exits_have_lineno(basicblock *entryblock) { | ||||
|     for (basicblock *b = entryblock; b != NULL; b = b->b_next) { | ||||
|         for (int i = 0; i < b->b_iused; i++) { | ||||
|             cfg_instr *instr = &b->b_instr[i]; | ||||
|             if (instr->i_opcode == RETURN_VALUE) { | ||||
|                 if (instr->i_loc.lineno < 0) { | ||||
|                     assert(0); | ||||
|                     return false; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     return true; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| /***** CFG preprocessing (jump targets and exceptions) *****/ | ||||
|  | @ -1131,7 +1115,7 @@ remove_redundant_nops_and_pairs(basicblock *entryblock) | |||
|                 int opcode = instr->i_opcode; | ||||
|                 bool is_redundant_pair = false; | ||||
|                 if (opcode == POP_TOP) { | ||||
|                    if (prev_opcode == LOAD_CONST) { | ||||
|                    if (prev_opcode == LOAD_CONST || prev_opcode == LOAD_SMALL_INT) { | ||||
|                        is_redundant_pair = true; | ||||
|                    } | ||||
|                    else if (prev_opcode == COPY && prev_oparg == 1) { | ||||
|  | @ -1280,14 +1264,23 @@ jump_thread(basicblock *bb, cfg_instr *inst, cfg_instr *target, int opcode) | |||
|     return false; | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| loads_const(int opcode) | ||||
| { | ||||
|     return OPCODE_HAS_CONST(opcode) || opcode == LOAD_SMALL_INT; | ||||
| } | ||||
| 
 | ||||
| static PyObject* | ||||
| get_const_value(int opcode, int oparg, PyObject *co_consts) | ||||
| { | ||||
|     PyObject *constant = NULL; | ||||
|     assert(OPCODE_HAS_CONST(opcode)); | ||||
|     assert(loads_const(opcode)); | ||||
|     if (opcode == LOAD_CONST) { | ||||
|         constant = PyList_GET_ITEM(co_consts, oparg); | ||||
|     } | ||||
|     if (opcode == LOAD_SMALL_INT) { | ||||
|         return PyLong_FromLong(oparg); | ||||
|     } | ||||
| 
 | ||||
|     if (constant == NULL) { | ||||
|         PyErr_SetString(PyExc_SystemError, | ||||
|  | @ -1345,7 +1338,7 @@ fold_tuple_on_constants(PyObject *const_cache, | |||
|     assert(inst[n].i_oparg == n); | ||||
| 
 | ||||
|     for (int i = 0; i < n; i++) { | ||||
|         if (!OPCODE_HAS_CONST(inst[i].i_opcode)) { | ||||
|         if (!loads_const(inst[i].i_opcode)) { | ||||
|             return SUCCESS; | ||||
|         } | ||||
|     } | ||||
|  | @ -1583,7 +1576,7 @@ basicblock_optimize_load_const(PyObject *const_cache, basicblock *bb, PyObject * | |||
|             oparg = inst->i_oparg; | ||||
|         } | ||||
|         assert(!IS_ASSEMBLER_OPCODE(opcode)); | ||||
|         if (opcode != LOAD_CONST) { | ||||
|         if (opcode != LOAD_CONST && opcode != LOAD_SMALL_INT) { | ||||
|             continue; | ||||
|         } | ||||
|         int nextop = i+1 < bb->b_iused ? bb->b_instr[i+1].i_opcode : 0; | ||||
|  | @ -1662,12 +1655,6 @@ basicblock_optimize_load_const(PyObject *const_cache, basicblock *bb, PyObject * | |||
|                                               : POP_JUMP_IF_NONE; | ||||
|                 break; | ||||
|             } | ||||
|             case RETURN_VALUE: | ||||
|             { | ||||
|                 INSTR_SET_OP0(inst, NOP); | ||||
|                 INSTR_SET_OP1(&bb->b_instr[++i], RETURN_CONST, oparg); | ||||
|                 break; | ||||
|             } | ||||
|             case TO_BOOL: | ||||
|             { | ||||
|                 PyObject *cnt = get_const_value(opcode, oparg, consts); | ||||
|  | @ -2120,7 +2107,8 @@ remove_unused_consts(basicblock *entryblock, PyObject *consts) | |||
|     /* mark used consts */ | ||||
|     for (basicblock *b = entryblock; b != NULL; b = b->b_next) { | ||||
|         for (int i = 0; i < b->b_iused; i++) { | ||||
|             if (OPCODE_HAS_CONST(b->b_instr[i].i_opcode)) { | ||||
|             int opcode = b->b_instr[i].i_opcode; | ||||
|             if (OPCODE_HAS_CONST(opcode)) { | ||||
|                 int index = b->b_instr[i].i_oparg; | ||||
|                 index_map[index] = index; | ||||
|             } | ||||
|  | @ -2173,7 +2161,8 @@ remove_unused_consts(basicblock *entryblock, PyObject *consts) | |||
| 
 | ||||
|     for (basicblock *b = entryblock; b != NULL; b = b->b_next) { | ||||
|         for (int i = 0; i < b->b_iused; i++) { | ||||
|             if (OPCODE_HAS_CONST(b->b_instr[i].i_opcode)) { | ||||
|             int opcode = b->b_instr[i].i_opcode; | ||||
|             if (OPCODE_HAS_CONST(opcode)) { | ||||
|                 int index = b->b_instr[i].i_oparg; | ||||
|                 assert(reverse_index_map[index] >= 0); | ||||
|                 assert(reverse_index_map[index] < n_used_consts); | ||||
|  | @ -2594,8 +2583,9 @@ _PyCfg_OptimizeCodeUnit(cfg_builder *g, PyObject *consts, PyObject *const_cache, | |||
|     RETURN_IF_ERROR(insert_superinstructions(g)); | ||||
| 
 | ||||
|     RETURN_IF_ERROR(push_cold_blocks_to_end(g)); | ||||
|     assert(all_exits_have_lineno(g->g_entryblock)); | ||||
|     RETURN_IF_ERROR(resolve_line_numbers(g, firstlineno)); | ||||
|     // temporarily remove assert. See https://github.com/python/cpython/issues/125845
 | ||||
|     // assert(all_exits_have_lineno(g->g_entryblock));
 | ||||
|     return SUCCESS; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue