Skip to content

Commit 1753776

Browse files
committed
Add comparison optimization patterns to peephole
This implements self-comparison optimizations: - x != x → 0 (always false) - x == x → 1 (always true) - x < x → 0 (always false) - x > x → 0 (always false) - x <= x → 1 (always true) - x >= x → 1 (always true) These register-based patterns appear after register allocation when different variables are assigned to the same register. Complements SSA's SCCP constant comparison folding.
1 parent 3c24984 commit 1753776

File tree

1 file changed

+76
-0
lines changed

1 file changed

+76
-0
lines changed

src/peephole.c

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,82 @@ bool strength_reduction(ph2_ir_t *ph2_ir)
677677
return false;
678678
}
679679

680+
/* Comparison optimization: Simplify comparison patterns
681+
* Focus on register-based patterns that SSA's SCCP misses
682+
* Returns true if optimization was applied
683+
*/
684+
bool comparison_optimization(ph2_ir_t *ph2_ir)
685+
{
686+
if (!ph2_ir)
687+
return false;
688+
689+
/* NOTE: SSA's SCCP handles constant comparisons, so we focus on
690+
* register-based self-comparisons after register allocation
691+
*/
692+
693+
/* Pattern 1: Self-comparison always false for !=
694+
* x != x → 0 (for register operands)
695+
*/
696+
if (ph2_ir->op == OP_neq && ph2_ir->src0 == ph2_ir->src1) {
697+
ph2_ir->op = OP_load_constant;
698+
ph2_ir->src0 = 0; /* always false */
699+
ph2_ir->src1 = 0;
700+
return true;
701+
}
702+
703+
/* Pattern 2: Self-comparison always true for ==
704+
* x == x → 1 (for register operands)
705+
*/
706+
if (ph2_ir->op == OP_eq && ph2_ir->src0 == ph2_ir->src1) {
707+
ph2_ir->op = OP_load_constant;
708+
ph2_ir->src0 = 1; /* always true */
709+
ph2_ir->src1 = 0;
710+
return true;
711+
}
712+
713+
/* Pattern 3: Self-comparison for less-than
714+
* x < x → 0 (always false)
715+
*/
716+
if (ph2_ir->op == OP_lt && ph2_ir->src0 == ph2_ir->src1) {
717+
ph2_ir->op = OP_load_constant;
718+
ph2_ir->src0 = 0; /* always false */
719+
ph2_ir->src1 = 0;
720+
return true;
721+
}
722+
723+
/* Pattern 4: Self-comparison for greater-than
724+
* x > x → 0 (always false)
725+
*/
726+
if (ph2_ir->op == OP_gt && ph2_ir->src0 == ph2_ir->src1) {
727+
ph2_ir->op = OP_load_constant;
728+
ph2_ir->src0 = 0; /* always false */
729+
ph2_ir->src1 = 0;
730+
return true;
731+
}
732+
733+
/* Pattern 5: Self-comparison for less-equal
734+
* x <= x → 1 (always true)
735+
*/
736+
if (ph2_ir->op == OP_leq && ph2_ir->src0 == ph2_ir->src1) {
737+
ph2_ir->op = OP_load_constant;
738+
ph2_ir->src0 = 1; /* always true */
739+
ph2_ir->src1 = 0;
740+
return true;
741+
}
742+
743+
/* Pattern 6: Self-comparison for greater-equal
744+
* x >= x → 1 (always true)
745+
*/
746+
if (ph2_ir->op == OP_geq && ph2_ir->src0 == ph2_ir->src1) {
747+
ph2_ir->op = OP_load_constant;
748+
ph2_ir->src0 = 1; /* always true */
749+
ph2_ir->src1 = 0;
750+
return true;
751+
}
752+
753+
return false;
754+
}
755+
680756
/* Main peephole optimization driver.
681757
* It iterates through all functions, basic blocks, and IR instructions to apply
682758
* local optimizations on adjacent instruction pairs.

0 commit comments

Comments
 (0)