@@ -2238,7 +2238,7 @@ def test_pure_uop_body_copied_in(self):
22382238 """
22392239 input2 = """
22402240 op(OP, (foo -- res)) {
2241- REPLACE_OPCODE_IF_EVALUATES_PURE(foo);
2241+ REPLACE_OPCODE_IF_EVALUATES_PURE(foo, res );
22422242 res = sym_new_known(ctx, foo);
22432243 }
22442244 """
@@ -2278,7 +2278,7 @@ def test_pure_uop_body_copied_in_deopt(self):
22782278 """
22792279 input2 = """
22802280 op(OP, (foo -- res)) {
2281- REPLACE_OPCODE_IF_EVALUATES_PURE(foo);
2281+ REPLACE_OPCODE_IF_EVALUATES_PURE(foo, res );
22822282 res = foo;
22832283 }
22842284 """
@@ -2322,7 +2322,7 @@ def test_pure_uop_body_copied_in_error_if(self):
23222322 """
23232323 input2 = """
23242324 op(OP, (foo -- res)) {
2325- REPLACE_OPCODE_IF_EVALUATES_PURE(foo);
2325+ REPLACE_OPCODE_IF_EVALUATES_PURE(foo, res );
23262326 res = foo;
23272327 }
23282328 """
@@ -2368,7 +2368,7 @@ def test_replace_opcode_uop_body_copied_in_complex(self):
23682368 """
23692369 input2 = """
23702370 op(OP, (foo -- res)) {
2371- REPLACE_OPCODE_IF_EVALUATES_PURE(foo);
2371+ REPLACE_OPCODE_IF_EVALUATES_PURE(foo, res );
23722372 res = sym_new_known(ctx, foo);
23732373 }
23742374 """
@@ -2415,7 +2415,7 @@ def test_replace_opcode_escaping_uop_body_copied_in_complex(self):
24152415 """
24162416 input2 = """
24172417 op(OP, (foo -- res)) {
2418- REPLACE_OPCODE_IF_EVALUATES_PURE(foo);
2418+ REPLACE_OPCODE_IF_EVALUATES_PURE(foo, res );
24192419 res = sym_new_known(ctx, foo);
24202420 }
24212421 """
@@ -2449,6 +2449,172 @@ def test_replace_opcode_escaping_uop_body_copied_in_complex(self):
24492449 """
24502450 self .run_cases_test (input , input2 , output )
24512451
2452+ def test_replace_opcode_binop_one_output (self ):
2453+ input = """
2454+ pure op(OP, (left, right -- res)) {
2455+ res = foo(left, right);
2456+ }
2457+ """
2458+ input2 = """
2459+ op(OP, (left, right -- res)) {
2460+ res = sym_new_non_null(ctx, foo);
2461+ REPLACE_OPCODE_IF_EVALUATES_PURE(left, right, res);
2462+ }
2463+ """
2464+ output = """
2465+ case OP: {
2466+ JitOptRef right;
2467+ JitOptRef left;
2468+ JitOptRef res;
2469+ right = stack_pointer[-1];
2470+ left = stack_pointer[-2];
2471+ res = sym_new_non_null(ctx, foo);
2472+ if (
2473+ sym_is_safe_const(ctx, left) &&
2474+ sym_is_safe_const(ctx, right)
2475+ ) {
2476+ JitOptRef left_sym = left;
2477+ JitOptRef right_sym = right;
2478+ _PyStackRef left = sym_get_const_as_stackref(ctx, left_sym);
2479+ _PyStackRef right = sym_get_const_as_stackref(ctx, right_sym);
2480+ _PyStackRef res_stackref;
2481+ /* Start of uop copied from bytecodes for constant evaluation */
2482+ res_stackref = foo(left, right);
2483+ /* End of uop copied from bytecodes for constant evaluation */
2484+ res = sym_new_const_steal(ctx, PyStackRef_AsPyObjectSteal(res_stackref));
2485+ CHECK_STACK_BOUNDS(-1);
2486+ stack_pointer[-2] = res;
2487+ stack_pointer += -1;
2488+ ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
2489+ break;
2490+ }
2491+ CHECK_STACK_BOUNDS(-1);
2492+ stack_pointer[-2] = res;
2493+ stack_pointer += -1;
2494+ ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
2495+ break;
2496+ }
2497+ """
2498+ self .run_cases_test (input , input2 , output )
2499+
2500+ def test_replace_opcode_binop_one_output_insert (self ):
2501+ input = """
2502+ pure op(OP, (left, right -- res, l, r)) {
2503+ res = foo(left, right);
2504+ l = left;
2505+ r = right;
2506+ }
2507+ """
2508+ input2 = """
2509+ op(OP, (left, right -- res, l, r)) {
2510+ res = sym_new_non_null(ctx, foo);
2511+ l = left;
2512+ r = right;
2513+ REPLACE_OPCODE_IF_EVALUATES_PURE(left, right, res);
2514+ }
2515+ """
2516+ output = """
2517+ case OP: {
2518+ JitOptRef right;
2519+ JitOptRef left;
2520+ JitOptRef res;
2521+ JitOptRef l;
2522+ JitOptRef r;
2523+ right = stack_pointer[-1];
2524+ left = stack_pointer[-2];
2525+ res = sym_new_non_null(ctx, foo);
2526+ l = left;
2527+ r = right;
2528+ if (
2529+ sym_is_safe_const(ctx, left) &&
2530+ sym_is_safe_const(ctx, right)
2531+ ) {
2532+ JitOptRef left_sym = left;
2533+ JitOptRef right_sym = right;
2534+ _PyStackRef left = sym_get_const_as_stackref(ctx, left_sym);
2535+ _PyStackRef right = sym_get_const_as_stackref(ctx, right_sym);
2536+ _PyStackRef res_stackref;
2537+ _PyStackRef l_stackref;
2538+ _PyStackRef r_stackref;
2539+ /* Start of uop copied from bytecodes for constant evaluation */
2540+ res_stackref = foo(left, right);
2541+ l_stackref = left;
2542+ r_stackref = right;
2543+ /* End of uop copied from bytecodes for constant evaluation */
2544+ (void)l_stackref;
2545+ (void)r_stackref;
2546+ res = sym_new_const_steal(ctx, PyStackRef_AsPyObjectSteal(res_stackref));
2547+ CHECK_STACK_BOUNDS(1);
2548+ stack_pointer[-2] = res;
2549+ stack_pointer[-1] = l;
2550+ stack_pointer[0] = r;
2551+ stack_pointer += 1;
2552+ ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
2553+ break;
2554+ }
2555+ CHECK_STACK_BOUNDS(1);
2556+ stack_pointer[-2] = res;
2557+ stack_pointer[-1] = l;
2558+ stack_pointer[0] = r;
2559+ stack_pointer += 1;
2560+ ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
2561+ break;
2562+ }
2563+ """
2564+ self .run_cases_test (input , input2 , output )
2565+
2566+ def test_replace_opcode_unaryop_one_output_insert (self ):
2567+ input = """
2568+ pure op(OP, (left -- res, l)) {
2569+ res = foo(left);
2570+ l = left;
2571+ }
2572+ """
2573+ input2 = """
2574+ op(OP, (left -- res, l)) {
2575+ res = sym_new_non_null(ctx, foo);
2576+ l = left;
2577+ REPLACE_OPCODE_IF_EVALUATES_PURE(left, res);
2578+ }
2579+ """
2580+ output = """
2581+ case OP: {
2582+ JitOptRef left;
2583+ JitOptRef res;
2584+ JitOptRef l;
2585+ left = stack_pointer[-1];
2586+ res = sym_new_non_null(ctx, foo);
2587+ l = left;
2588+ if (
2589+ sym_is_safe_const(ctx, left)
2590+ ) {
2591+ JitOptRef left_sym = left;
2592+ _PyStackRef left = sym_get_const_as_stackref(ctx, left_sym);
2593+ _PyStackRef res_stackref;
2594+ _PyStackRef l_stackref;
2595+ /* Start of uop copied from bytecodes for constant evaluation */
2596+ res_stackref = foo(left);
2597+ l_stackref = left;
2598+ /* End of uop copied from bytecodes for constant evaluation */
2599+ (void)l_stackref;
2600+ res = sym_new_const_steal(ctx, PyStackRef_AsPyObjectSteal(res_stackref));
2601+ CHECK_STACK_BOUNDS(1);
2602+ stack_pointer[-1] = res;
2603+ stack_pointer[0] = l;
2604+ stack_pointer += 1;
2605+ ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
2606+ break;
2607+ }
2608+ CHECK_STACK_BOUNDS(1);
2609+ stack_pointer[-1] = res;
2610+ stack_pointer[0] = l;
2611+ stack_pointer += 1;
2612+ ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
2613+ break;
2614+ }
2615+ """
2616+ self .run_cases_test (input , input2 , output )
2617+
24522618 def test_replace_opocode_uop_reject_array_effects (self ):
24532619 input = """
24542620 pure op(OP, (foo[2] -- res)) {
@@ -2462,7 +2628,7 @@ def test_replace_opocode_uop_reject_array_effects(self):
24622628 """
24632629 input2 = """
24642630 op(OP, (foo[2] -- res)) {
2465- REPLACE_OPCODE_IF_EVALUATES_PURE(foo);
2631+ REPLACE_OPCODE_IF_EVALUATES_PURE(foo, res );
24662632 res = sym_new_unknown(ctx);
24672633 }
24682634 """
0 commit comments