mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	bpo-44900: Add five superinstructions. (GH-27741)
* LOAD_FAST LOAD_FAST * STORE_FAST LOAD_FAST * LOAD_FAST LOAD_CONST * LOAD_CONST LOAD_FAST * STORE_FAST STORE_FAST
This commit is contained in:
		
							parent
							
								
									1a511dc92d
								
							
						
					
					
						commit
						4f51fa9e2d
					
				
					 6 changed files with 133 additions and 20 deletions
				
			
		
							
								
								
									
										5
									
								
								Include/opcode.h
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										5
									
								
								Include/opcode.h
									
										
									
										generated
									
									
									
								
							|  | @ -153,6 +153,11 @@ extern "C" { | |||
| #define STORE_ATTR_SPLIT_KEYS    45 | ||||
| #define STORE_ATTR_SLOT          46 | ||||
| #define STORE_ATTR_WITH_HINT     47 | ||||
| #define LOAD_FAST__LOAD_FAST     48 | ||||
| #define STORE_FAST__LOAD_FAST    58 | ||||
| #define LOAD_FAST__LOAD_CONST    80 | ||||
| #define LOAD_CONST__LOAD_FAST    81 | ||||
| #define STORE_FAST__STORE_FAST   87 | ||||
| #ifdef NEED_OPCODE_JUMP_TABLES | ||||
| static uint32_t _PyOpcode_RelativeJump[8] = { | ||||
|     0U, | ||||
|  |  | |||
|  | @ -237,8 +237,13 @@ def jabs_op(name, op): | |||
|     "STORE_ATTR_SPLIT_KEYS", | ||||
|     "STORE_ATTR_SLOT", | ||||
|     "STORE_ATTR_WITH_HINT", | ||||
|     # Super instructions | ||||
|     "LOAD_FAST__LOAD_FAST", | ||||
|     "STORE_FAST__LOAD_FAST", | ||||
|     "LOAD_FAST__LOAD_CONST", | ||||
|     "LOAD_CONST__LOAD_FAST", | ||||
|     "STORE_FAST__STORE_FAST", | ||||
| ] | ||||
| 
 | ||||
| _specialization_stats = [ | ||||
|     "specialization_success", | ||||
|     "specialization_failure", | ||||
|  |  | |||
|  | @ -0,0 +1,7 @@ | |||
| Add five superinstructions for PEP 659 quickening: | ||||
| 
 | ||||
| * LOAD_FAST LOAD_FAST | ||||
| * STORE_FAST LOAD_FAST | ||||
| * LOAD_FAST LOAD_CONST | ||||
| * LOAD_CONST LOAD_FAST | ||||
| * STORE_FAST STORE_FAST | ||||
|  | @ -1266,16 +1266,21 @@ eval_frame_handle_pending(PyThreadState *tstate) | |||
| #define PRE_DISPATCH_GOTO() do { LLTRACE_INSTR();  RECORD_DXPROFILE(); } while (0) | ||||
| #endif | ||||
| 
 | ||||
| #define NOTRACE_DISPATCH() \ | ||||
|     { \ | ||||
|         frame->f_lasti = INSTR_OFFSET(); \ | ||||
|         NEXTOPARG(); \ | ||||
|         PRE_DISPATCH_GOTO(); \ | ||||
|         DISPATCH_GOTO(); \ | ||||
|     } | ||||
| 
 | ||||
| /* Do interpreter dispatch accounting for tracing and instrumentation */ | ||||
| #define DISPATCH() \ | ||||
|     { \ | ||||
|         if (cframe.use_tracing OR_DTRACE_LINE) { \ | ||||
|             goto tracing_dispatch; \ | ||||
|         } \ | ||||
|         frame->f_lasti = INSTR_OFFSET(); \ | ||||
|         NEXTOPARG(); \ | ||||
|         PRE_DISPATCH_GOTO(); \ | ||||
|         DISPATCH_GOTO(); \ | ||||
|         NOTRACE_DISPATCH(); \ | ||||
|     } | ||||
| 
 | ||||
| #define CHECK_EVAL_BREAKER() \ | ||||
|  | @ -1682,11 +1687,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr | |||
|         TARGET(LOAD_FAST): { | ||||
|             PyObject *value = GETLOCAL(oparg); | ||||
|             if (value == NULL) { | ||||
|                 format_exc_check_arg(tstate, PyExc_UnboundLocalError, | ||||
|                                      UNBOUNDLOCAL_ERROR_MSG, | ||||
|                                      PyTuple_GetItem(co->co_localsplusnames, | ||||
|                                                      oparg)); | ||||
|                 goto error; | ||||
|                 goto unbound_local_error; | ||||
|             } | ||||
|             Py_INCREF(value); | ||||
|             PUSH(value); | ||||
|  | @ -1708,6 +1709,73 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr | |||
|             DISPATCH(); | ||||
|         } | ||||
| 
 | ||||
|         TARGET(LOAD_FAST__LOAD_FAST): { | ||||
|             PyObject *value = GETLOCAL(oparg); | ||||
|             if (value == NULL) { | ||||
|                 goto unbound_local_error; | ||||
|             } | ||||
|             NEXTOPARG(); | ||||
|             Py_INCREF(value); | ||||
|             PUSH(value); | ||||
|             value = GETLOCAL(oparg); | ||||
|             if (value == NULL) { | ||||
|                 goto unbound_local_error; | ||||
|             } | ||||
|             Py_INCREF(value); | ||||
|             PUSH(value); | ||||
|             NOTRACE_DISPATCH(); | ||||
|         } | ||||
| 
 | ||||
|         TARGET(LOAD_FAST__LOAD_CONST): { | ||||
|             PyObject *value = GETLOCAL(oparg); | ||||
|             if (value == NULL) { | ||||
|                 goto unbound_local_error; | ||||
|             } | ||||
|             NEXTOPARG(); | ||||
|             Py_INCREF(value); | ||||
|             PUSH(value); | ||||
|             value = GETITEM(consts, oparg); | ||||
|             Py_INCREF(value); | ||||
|             PUSH(value); | ||||
|             NOTRACE_DISPATCH(); | ||||
|         } | ||||
| 
 | ||||
|         TARGET(STORE_FAST__LOAD_FAST): { | ||||
|             PyObject *value = POP(); | ||||
|             SETLOCAL(oparg, value); | ||||
|             NEXTOPARG(); | ||||
|             value = GETLOCAL(oparg); | ||||
|             if (value == NULL) { | ||||
|                 goto unbound_local_error; | ||||
|             } | ||||
|             Py_INCREF(value); | ||||
|             PUSH(value); | ||||
|             NOTRACE_DISPATCH(); | ||||
|         } | ||||
| 
 | ||||
|         TARGET(STORE_FAST__STORE_FAST): { | ||||
|             PyObject *value = POP(); | ||||
|             SETLOCAL(oparg, value); | ||||
|             NEXTOPARG(); | ||||
|             value = POP(); | ||||
|             SETLOCAL(oparg, value); | ||||
|             NOTRACE_DISPATCH(); | ||||
|         } | ||||
| 
 | ||||
|         TARGET(LOAD_CONST__LOAD_FAST): { | ||||
|             PyObject *value = GETITEM(consts, oparg); | ||||
|             NEXTOPARG(); | ||||
|             Py_INCREF(value); | ||||
|             PUSH(value); | ||||
|             value = GETLOCAL(oparg); | ||||
|             if (value == NULL) { | ||||
|                 goto unbound_local_error; | ||||
|             } | ||||
|             Py_INCREF(value); | ||||
|             PUSH(value); | ||||
|             NOTRACE_DISPATCH(); | ||||
|         } | ||||
| 
 | ||||
|         TARGET(POP_TOP): { | ||||
|             PyObject *value = POP(); | ||||
|             Py_DECREF(value); | ||||
|  | @ -4592,6 +4660,15 @@ MISS_WITH_OPARG_COUNTER(BINARY_SUBSCR) | |||
|             goto error; | ||||
|         } | ||||
| 
 | ||||
| unbound_local_error: | ||||
|         { | ||||
|             format_exc_check_arg(tstate, PyExc_UnboundLocalError, | ||||
|                 UNBOUNDLOCAL_ERROR_MSG, | ||||
|                 PyTuple_GetItem(co->co_localsplusnames, oparg) | ||||
|             ); | ||||
|             goto error; | ||||
|         } | ||||
| 
 | ||||
| error: | ||||
|         /* Double-check exception status. */ | ||||
| #ifdef NDEBUG | ||||
|  |  | |||
							
								
								
									
										10
									
								
								Python/opcode_targets.h
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										10
									
								
								Python/opcode_targets.h
									
										
									
										generated
									
									
									
								
							|  | @ -47,7 +47,7 @@ static void *opcode_targets[256] = { | |||
|     &&TARGET_STORE_ATTR_SPLIT_KEYS, | ||||
|     &&TARGET_STORE_ATTR_SLOT, | ||||
|     &&TARGET_STORE_ATTR_WITH_HINT, | ||||
|     &&_unknown_opcode, | ||||
|     &&TARGET_LOAD_FAST__LOAD_FAST, | ||||
|     &&TARGET_WITH_EXCEPT_START, | ||||
|     &&TARGET_GET_AITER, | ||||
|     &&TARGET_GET_ANEXT, | ||||
|  | @ -57,7 +57,7 @@ static void *opcode_targets[256] = { | |||
|     &&TARGET_INPLACE_ADD, | ||||
|     &&TARGET_INPLACE_SUBTRACT, | ||||
|     &&TARGET_INPLACE_MULTIPLY, | ||||
|     &&_unknown_opcode, | ||||
|     &&TARGET_STORE_FAST__LOAD_FAST, | ||||
|     &&TARGET_INPLACE_MODULO, | ||||
|     &&TARGET_STORE_SUBSCR, | ||||
|     &&TARGET_DELETE_SUBSCR, | ||||
|  | @ -79,14 +79,14 @@ static void *opcode_targets[256] = { | |||
|     &&TARGET_INPLACE_AND, | ||||
|     &&TARGET_INPLACE_XOR, | ||||
|     &&TARGET_INPLACE_OR, | ||||
|     &&_unknown_opcode, | ||||
|     &&_unknown_opcode, | ||||
|     &&TARGET_LOAD_FAST__LOAD_CONST, | ||||
|     &&TARGET_LOAD_CONST__LOAD_FAST, | ||||
|     &&TARGET_LIST_TO_TUPLE, | ||||
|     &&TARGET_RETURN_VALUE, | ||||
|     &&TARGET_IMPORT_STAR, | ||||
|     &&TARGET_SETUP_ANNOTATIONS, | ||||
|     &&TARGET_YIELD_VALUE, | ||||
|     &&_unknown_opcode, | ||||
|     &&TARGET_STORE_FAST__STORE_FAST, | ||||
|     &&_unknown_opcode, | ||||
|     &&TARGET_POP_EXCEPT, | ||||
|     &&TARGET_STORE_NAME, | ||||
|  |  | |||
|  | @ -303,6 +303,7 @@ optimize(SpecializedCacheOrInstruction *quickened, int len) | |||
|     _Py_CODEUNIT *instructions = first_instruction(quickened); | ||||
|     int cache_offset = 0; | ||||
|     int previous_opcode = -1; | ||||
|     int previous_oparg = 0; | ||||
|     for(int i = 0; i < len; i++) { | ||||
|         int opcode = _Py_OPCODE(instructions[i]); | ||||
|         int oparg = _Py_OPARG(instructions[i]); | ||||
|  | @ -338,14 +339,32 @@ optimize(SpecializedCacheOrInstruction *quickened, int len) | |||
|                 case JUMP_ABSOLUTE: | ||||
|                     instructions[i] = _Py_MAKECODEUNIT(JUMP_ABSOLUTE_QUICK, oparg); | ||||
|                     break; | ||||
|                 /* Insert superinstructions here
 | ||||
|                  E.g. | ||||
|                 case LOAD_FAST: | ||||
|                     if (previous_opcode == LOAD_FAST) | ||||
|                         instructions[i-1] = _Py_MAKECODEUNIT(LOAD_FAST__LOAD_FAST, oparg); | ||||
|                  */ | ||||
|                     switch(previous_opcode) { | ||||
|                         case LOAD_FAST: | ||||
|                             instructions[i-1] = _Py_MAKECODEUNIT(LOAD_FAST__LOAD_FAST, previous_oparg); | ||||
|                             break; | ||||
|                         case STORE_FAST: | ||||
|                             instructions[i-1] = _Py_MAKECODEUNIT(STORE_FAST__LOAD_FAST, previous_oparg); | ||||
|                             break; | ||||
|                         case LOAD_CONST: | ||||
|                             instructions[i-1] = _Py_MAKECODEUNIT(LOAD_CONST__LOAD_FAST, previous_oparg); | ||||
|                             break; | ||||
|                     } | ||||
|                     break; | ||||
|                 case STORE_FAST: | ||||
|                     if (previous_opcode == STORE_FAST) { | ||||
|                         instructions[i-1] = _Py_MAKECODEUNIT(STORE_FAST__STORE_FAST, previous_oparg); | ||||
|                     } | ||||
|                     break; | ||||
|                 case LOAD_CONST: | ||||
|                     if (previous_opcode == LOAD_FAST) { | ||||
|                         instructions[i-1] = _Py_MAKECODEUNIT(LOAD_FAST__LOAD_CONST, previous_oparg); | ||||
|                     } | ||||
|                     break; | ||||
|             } | ||||
|             previous_opcode = opcode; | ||||
|             previous_oparg = oparg; | ||||
|         } | ||||
|     } | ||||
|     assert(cache_offset+1 == get_cache_count(quickened)); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Mark Shannon
						Mark Shannon