mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	gh-132732: Automatically constant evaluate pure operations (GH-132733)
This adds a "macro" to the optimizer DSL called "REPLACE_OPCODE_IF_EVALUATES_PURE", which allows automatically constant evaluating a bytecode body if certain inputs have no side effects upon evaluations (such as ints, strings, and floats). Co-authored-by: Tomas R. <tomas.roun8@gmail.com>
This commit is contained in:
		
							parent
							
								
									c45f4f3ebe
								
							
						
					
					
						commit
						695ab61351
					
				
					 10 changed files with 706 additions and 122 deletions
				
			
		|  | @ -181,6 +181,7 @@ dummy_func(void) { | |||
|     } | ||||
| 
 | ||||
|     op(_BINARY_OP, (lhs, rhs -- res)) { | ||||
|         REPLACE_OPCODE_IF_EVALUATES_PURE(lhs, rhs); | ||||
|         bool lhs_int = sym_matches_type(lhs, &PyLong_Type); | ||||
|         bool rhs_int = sym_matches_type(rhs, &PyLong_Type); | ||||
|         bool lhs_float = sym_matches_type(lhs, &PyFloat_Type); | ||||
|  | @ -235,35 +236,23 @@ dummy_func(void) { | |||
|     } | ||||
| 
 | ||||
|     op(_BINARY_OP_ADD_INT, (left, right -- res)) { | ||||
|         REPLACE_OPCODE_IF_EVALUATES_PURE(left, right); | ||||
|         res = sym_new_compact_int(ctx); | ||||
|     } | ||||
| 
 | ||||
|     op(_BINARY_OP_SUBTRACT_INT, (left, right -- res)) { | ||||
|         REPLACE_OPCODE_IF_EVALUATES_PURE(left, right); | ||||
|         res = sym_new_compact_int(ctx); | ||||
|     } | ||||
| 
 | ||||
|     op(_BINARY_OP_MULTIPLY_INT, (left, right -- res)) { | ||||
|         REPLACE_OPCODE_IF_EVALUATES_PURE(left, right); | ||||
|         res = sym_new_compact_int(ctx); | ||||
|     } | ||||
| 
 | ||||
|     op(_BINARY_OP_ADD_FLOAT, (left, right -- res)) { | ||||
|         if (sym_is_const(ctx, left) && sym_is_const(ctx, right)) { | ||||
|             assert(PyFloat_CheckExact(sym_get_const(ctx, left))); | ||||
|             assert(PyFloat_CheckExact(sym_get_const(ctx, right))); | ||||
|             PyObject *temp = PyFloat_FromDouble( | ||||
|                 PyFloat_AS_DOUBLE(sym_get_const(ctx, left)) + | ||||
|                 PyFloat_AS_DOUBLE(sym_get_const(ctx, right))); | ||||
|             if (temp == NULL) { | ||||
|                 goto error; | ||||
|             } | ||||
|             res = sym_new_const(ctx, temp); | ||||
|             Py_DECREF(temp); | ||||
|             // TODO gh-115506:
 | ||||
|             // replace opcode with constant propagated one and update tests!
 | ||||
|         } | ||||
|         else { | ||||
|             res = sym_new_type(ctx, &PyFloat_Type); | ||||
|         } | ||||
|         REPLACE_OPCODE_IF_EVALUATES_PURE(left, right); | ||||
|         res = sym_new_type(ctx, &PyFloat_Type); | ||||
|         // TODO (gh-134584): Refactor this to use another uop
 | ||||
|         if (PyJitRef_IsBorrowed(left) && PyJitRef_IsBorrowed(right)) { | ||||
|             REPLACE_OP(this_instr, op_without_decref_inputs[opcode], oparg, 0); | ||||
|  | @ -271,23 +260,8 @@ dummy_func(void) { | |||
|     } | ||||
| 
 | ||||
|     op(_BINARY_OP_SUBTRACT_FLOAT, (left, right -- res)) { | ||||
|         if (sym_is_const(ctx, left) && sym_is_const(ctx, right)) { | ||||
|             assert(PyFloat_CheckExact(sym_get_const(ctx, left))); | ||||
|             assert(PyFloat_CheckExact(sym_get_const(ctx, right))); | ||||
|             PyObject *temp = PyFloat_FromDouble( | ||||
|                 PyFloat_AS_DOUBLE(sym_get_const(ctx, left)) - | ||||
|                 PyFloat_AS_DOUBLE(sym_get_const(ctx, right))); | ||||
|             if (temp == NULL) { | ||||
|                 goto error; | ||||
|             } | ||||
|             res = sym_new_const(ctx, temp); | ||||
|             Py_DECREF(temp); | ||||
|             // TODO gh-115506:
 | ||||
|             // replace opcode with constant propagated one and update tests!
 | ||||
|         } | ||||
|         else { | ||||
|             res = sym_new_type(ctx, &PyFloat_Type); | ||||
|         } | ||||
|         REPLACE_OPCODE_IF_EVALUATES_PURE(left, right); | ||||
|         res = sym_new_type(ctx, &PyFloat_Type); | ||||
|         // TODO (gh-134584): Refactor this to use another uop
 | ||||
|         if (PyJitRef_IsBorrowed(left) && PyJitRef_IsBorrowed(right)) { | ||||
|             REPLACE_OP(this_instr, op_without_decref_inputs[opcode], oparg, 0); | ||||
|  | @ -295,23 +269,8 @@ dummy_func(void) { | |||
|     } | ||||
| 
 | ||||
|     op(_BINARY_OP_MULTIPLY_FLOAT, (left, right -- res)) { | ||||
|         if (sym_is_const(ctx, left) && sym_is_const(ctx, right)) { | ||||
|             assert(PyFloat_CheckExact(sym_get_const(ctx, left))); | ||||
|             assert(PyFloat_CheckExact(sym_get_const(ctx, right))); | ||||
|             PyObject *temp = PyFloat_FromDouble( | ||||
|                 PyFloat_AS_DOUBLE(sym_get_const(ctx, left)) * | ||||
|                 PyFloat_AS_DOUBLE(sym_get_const(ctx, right))); | ||||
|             if (temp == NULL) { | ||||
|                 goto error; | ||||
|             } | ||||
|             res = sym_new_const(ctx, temp); | ||||
|             Py_DECREF(temp); | ||||
|             // TODO gh-115506:
 | ||||
|             // replace opcode with constant propagated one and update tests!
 | ||||
|         } | ||||
|         else { | ||||
|             res = sym_new_type(ctx, &PyFloat_Type); | ||||
|         } | ||||
|         REPLACE_OPCODE_IF_EVALUATES_PURE(left, right); | ||||
|         res = sym_new_type(ctx, &PyFloat_Type); | ||||
|         // TODO (gh-134584): Refactor this to use another uop
 | ||||
|         if (PyJitRef_IsBorrowed(left) && PyJitRef_IsBorrowed(right)) { | ||||
|             REPLACE_OP(this_instr, op_without_decref_inputs[opcode], oparg, 0); | ||||
|  | @ -319,19 +278,8 @@ dummy_func(void) { | |||
|     } | ||||
| 
 | ||||
|     op(_BINARY_OP_ADD_UNICODE, (left, right -- res)) { | ||||
|         if (sym_is_const(ctx, left) && sym_is_const(ctx, right)) { | ||||
|             assert(PyUnicode_CheckExact(sym_get_const(ctx, left))); | ||||
|             assert(PyUnicode_CheckExact(sym_get_const(ctx, right))); | ||||
|             PyObject *temp = PyUnicode_Concat(sym_get_const(ctx, left), sym_get_const(ctx, right)); | ||||
|             if (temp == NULL) { | ||||
|                 goto error; | ||||
|             } | ||||
|             res = sym_new_const(ctx, temp); | ||||
|             Py_DECREF(temp); | ||||
|         } | ||||
|         else { | ||||
|             res = sym_new_type(ctx, &PyUnicode_Type); | ||||
|         } | ||||
|         REPLACE_OPCODE_IF_EVALUATES_PURE(left, right); | ||||
|         res = sym_new_type(ctx, &PyUnicode_Type); | ||||
|     } | ||||
| 
 | ||||
|     op(_BINARY_OP_INPLACE_ADD_UNICODE, (left, right -- )) { | ||||
|  | @ -443,6 +391,7 @@ dummy_func(void) { | |||
|     } | ||||
| 
 | ||||
|     op(_UNARY_NOT, (value -- res)) { | ||||
|         REPLACE_OPCODE_IF_EVALUATES_PURE(value); | ||||
|         sym_set_type(value, &PyBool_Type); | ||||
|         res = sym_new_truthiness(ctx, value, false); | ||||
|     } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Ken Jin
						Ken Jin