Skip to content

Commit 6b6dd4d

Browse files
committed
Remove duplicate optimizer patterns
- Add x*-1=-x and -1*x=-x cases to eval_algebraic() function - Remove duplicate self-operation patterns (x-x, x^x, x&x, x|x) from SSA since peephole optimizer handles these more efficiently after register allocation - Keep SSA-specific patterns (x/x=1, x%x=0, comparisons) that peephole does not handle - Maintain proper separation: SSA handles constants, peephole handles registers
1 parent 6f602d5 commit 6b6dd4d

File tree

1 file changed

+36
-145
lines changed

1 file changed

+36
-145
lines changed

src/ssa.c

Lines changed: 36 additions & 145 deletions
Original file line numberDiff line numberDiff line change
@@ -1866,6 +1866,19 @@ bool eval_algebraic(insn_t *insn)
18661866
insn->rs2 = NULL;
18671867
return true;
18681868
}
1869+
/* x * -1 = -x */
1870+
if (insn->rs2 && insn->rs2->is_const && insn->rs2->init_val == -1) {
1871+
insn->opcode = OP_negate;
1872+
insn->rs2 = NULL;
1873+
return true;
1874+
}
1875+
/* -1 * x = -x */
1876+
if (insn->rs1 && insn->rs1->is_const && insn->rs1->init_val == -1) {
1877+
insn->opcode = OP_negate;
1878+
insn->rs1 = insn->rs2;
1879+
insn->rs2 = NULL;
1880+
return true;
1881+
}
18691882
/* Strength reduction: x * power-of-2 → x << shift */
18701883
if (insn->rs2 && insn->rs2->is_const) {
18711884
int val = insn->rs2->init_val;
@@ -2501,39 +2514,16 @@ void optimize(void)
25012514
}
25022515
}
25032516

2504-
/* Self-operation optimizations at SSA level */
2505-
/* These patterns must be handled at SSA level for correct
2506-
* self-hosting despite some duplication with peephole optimizer
2517+
/* SSA-specific self-operation optimizations */
2518+
/* Only handle patterns that peephole doesn't cover effectively:
2519+
* - Comparison operations (not in peephole)
2520+
* - Division/modulo (not in peephole)
2521+
* Note: Basic arithmetic (sub, xor, and, or) are handled by
2522+
* peephole after register allocation for better efficiency.
25072523
*/
25082524
if (insn->rs1 && insn->rs2 && insn->rs1 == insn->rs2) {
2509-
/* x - x = 0 */
2510-
if (insn->opcode == OP_sub && insn->rd) {
2511-
insn->opcode = OP_load_constant;
2512-
insn->rd->is_const = true;
2513-
insn->rd->init_val = 0;
2514-
insn->rs1 = NULL;
2515-
insn->rs2 = NULL;
2516-
}
2517-
/* x ^ x = 0 */
2518-
else if (insn->opcode == OP_bit_xor && insn->rd) {
2519-
insn->opcode = OP_load_constant;
2520-
insn->rd->is_const = true;
2521-
insn->rd->init_val = 0;
2522-
insn->rs1 = NULL;
2523-
insn->rs2 = NULL;
2524-
}
2525-
/* x & x = x */
2526-
else if (insn->opcode == OP_bit_and && insn->rd) {
2527-
insn->opcode = OP_assign;
2528-
insn->rs2 = NULL;
2529-
}
2530-
/* x | x = x */
2531-
else if (insn->opcode == OP_bit_or && insn->rd) {
2532-
insn->opcode = OP_assign;
2533-
insn->rs2 = NULL;
2534-
}
2535-
/* x / x = 1 (if x != 0) */
2536-
else if (insn->opcode == OP_div && insn->rd) {
2525+
/* x / x = 1 (assuming x != 0) */
2526+
if (insn->opcode == OP_div && insn->rd) {
25372527
insn->opcode = OP_load_constant;
25382528
insn->rd->is_const = true;
25392529
insn->rd->init_val = 1;
@@ -2548,35 +2538,34 @@ void optimize(void)
25482538
insn->rs1 = NULL;
25492539
insn->rs2 = NULL;
25502540
}
2551-
/* x == x = 1 */
2541+
/* Comparison self-operations */
25522542
else if (insn->opcode == OP_eq && insn->rd) {
2543+
/* x == x = 1 */
25532544
insn->opcode = OP_load_constant;
25542545
insn->rd->is_const = true;
25552546
insn->rd->init_val = 1;
25562547
insn->rs1 = NULL;
25572548
insn->rs2 = NULL;
2558-
}
2559-
/* x != x = 0 */
2560-
else if (insn->opcode == OP_neq && insn->rd) {
2549+
} else if (insn->opcode == OP_neq && insn->rd) {
2550+
/* x != x = 0 */
25612551
insn->opcode = OP_load_constant;
25622552
insn->rd->is_const = true;
25632553
insn->rd->init_val = 0;
25642554
insn->rs1 = NULL;
25652555
insn->rs2 = NULL;
2566-
}
2567-
/* x < x = 0, x > x = 0 */
2568-
else if ((insn->opcode == OP_lt || insn->opcode == OP_gt) &&
2569-
insn->rd) {
2556+
} else if ((insn->opcode == OP_lt ||
2557+
insn->opcode == OP_gt) &&
2558+
insn->rd) {
2559+
/* x < x = 0, x > x = 0 */
25702560
insn->opcode = OP_load_constant;
25712561
insn->rd->is_const = true;
25722562
insn->rd->init_val = 0;
25732563
insn->rs1 = NULL;
25742564
insn->rs2 = NULL;
2575-
}
2576-
/* x <= x = 1, x >= x = 1 */
2577-
else if ((insn->opcode == OP_leq ||
2578-
insn->opcode == OP_geq) &&
2579-
insn->rd) {
2565+
} else if ((insn->opcode == OP_leq ||
2566+
insn->opcode == OP_geq) &&
2567+
insn->rd) {
2568+
/* x <= x = 1, x >= x = 1 */
25802569
insn->opcode = OP_load_constant;
25812570
insn->rd->is_const = true;
25822571
insn->rd->init_val = 1;
@@ -2585,107 +2574,9 @@ void optimize(void)
25852574
}
25862575
}
25872576

2588-
/* Comprehensive algebraic simplifications with identity
2589-
* operations */
2590-
if (insn->rs2 && insn->rs2->is_const && insn->rd) {
2591-
int val = insn->rs2->init_val;
2592-
2593-
/* x + 0 = x, x - 0 = x, x | 0 = x, x ^ 0 = x */
2594-
if (val == 0) {
2595-
if (insn->opcode == OP_add || insn->opcode == OP_sub ||
2596-
insn->opcode == OP_bit_or ||
2597-
insn->opcode == OP_bit_xor) {
2598-
insn->opcode = OP_assign;
2599-
insn->rs2 = NULL;
2600-
}
2601-
/* x * 0 = 0, x & 0 = 0 */
2602-
else if (insn->opcode == OP_mul ||
2603-
insn->opcode == OP_bit_and) {
2604-
insn->opcode = OP_load_constant;
2605-
insn->rd->is_const = true;
2606-
insn->rd->init_val = 0;
2607-
insn->rs1 = NULL;
2608-
insn->rs2 = NULL;
2609-
}
2610-
/* x << 0 = x, x >> 0 = x */
2611-
else if (insn->opcode == OP_lshift ||
2612-
insn->opcode == OP_rshift) {
2613-
insn->opcode = OP_assign;
2614-
insn->rs2 = NULL;
2615-
}
2616-
}
2617-
/* x * 1 = x, x / 1 = x */
2618-
else if (val == 1) {
2619-
if (insn->opcode == OP_mul || insn->opcode == OP_div) {
2620-
insn->opcode = OP_assign;
2621-
insn->rs2 = NULL;
2622-
}
2623-
}
2624-
/* x & -1 = x (all bits set) */
2625-
else if (val == -1) {
2626-
if (insn->opcode == OP_bit_and) {
2627-
insn->opcode = OP_assign;
2628-
insn->rs2 = NULL;
2629-
}
2630-
/* x | -1 = -1 */
2631-
else if (insn->opcode == OP_bit_or) {
2632-
insn->opcode = OP_load_constant;
2633-
insn->rd->is_const = true;
2634-
insn->rd->init_val = -1;
2635-
insn->rs1 = NULL;
2636-
insn->rs2 = NULL;
2637-
}
2638-
}
2639-
/* x * -1 = -x */
2640-
else if (val == -1 && insn->opcode == OP_mul) {
2641-
insn->opcode = OP_negate;
2642-
insn->rs2 = NULL;
2643-
}
2644-
}
2645-
2646-
/* Simplifications with rs1 constant */
2647-
if (insn->rs1 && insn->rs1->is_const && insn->rd) {
2648-
int val = insn->rs1->init_val;
2649-
2650-
/* 0 + x = x, 0 | x = x, 0 ^ x = x */
2651-
if (val == 0) {
2652-
if (insn->opcode == OP_add ||
2653-
insn->opcode == OP_bit_or ||
2654-
insn->opcode == OP_bit_xor) {
2655-
insn->opcode = OP_assign;
2656-
insn->rs1 = insn->rs2;
2657-
insn->rs2 = NULL;
2658-
}
2659-
/* 0 * x = 0, 0 & x = 0, 0 / x = 0 */
2660-
else if (insn->opcode == OP_mul ||
2661-
insn->opcode == OP_bit_and ||
2662-
insn->opcode == OP_div) {
2663-
insn->opcode = OP_load_constant;
2664-
insn->rd->is_const = true;
2665-
insn->rd->init_val = 0;
2666-
insn->rs1 = NULL;
2667-
insn->rs2 = NULL;
2668-
}
2669-
/* 0 - x = -x */
2670-
else if (insn->opcode == OP_sub) {
2671-
insn->opcode = OP_negate;
2672-
insn->rs1 = insn->rs2;
2673-
insn->rs2 = NULL;
2674-
}
2675-
}
2676-
/* 1 * x = x */
2677-
else if (val == 1 && insn->opcode == OP_mul) {
2678-
insn->opcode = OP_assign;
2679-
insn->rs1 = insn->rs2;
2680-
insn->rs2 = NULL;
2681-
}
2682-
/* -1 & x = x */
2683-
else if (val == -1 && insn->opcode == OP_bit_and) {
2684-
insn->opcode = OP_assign;
2685-
insn->rs1 = insn->rs2;
2686-
insn->rs2 = NULL;
2687-
}
2688-
}
2577+
/* Apply algebraic simplifications using eval_algebraic */
2578+
if (eval_algebraic(insn))
2579+
continue;
26892580

26902581
/* Phi node optimization - eliminate trivial phi nodes */
26912582
if (insn->opcode == OP_phi && insn->phi_ops) {

0 commit comments

Comments
 (0)