Skip to content

Commit 9b42b28

Browse files
committed
Enhance algebraic simplifications
Add comprehensive algebraic optimization patterns: - Self-operations: x-x=0, x^x=0, x&x=x, x|x=x - Comparisons: x==x=1, x!=x=0, x<x=0, x<=x=1 - Identity operations: x+0=x, x*1=x, x&-1=x - Constant folding: x*0=0, x&0=0, x|-1=-1 - Special cases: x%1=0, x*-1=-x, x<<0=x These patterns improve code generation by eliminating redundant operations and simplifying expressions at compile time.
1 parent 400ec54 commit 9b42b28

File tree

1 file changed

+131
-0
lines changed

1 file changed

+131
-0
lines changed

src/ssa.c

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1920,6 +1920,137 @@ void optimize(void)
19201920
}
19211921
}
19221922

1923+
/* Enhanced algebraic simplifications */
1924+
/* Self-operation optimizations */
1925+
if (insn->rs1 && insn->rs2 && insn->rs1 == insn->rs2) {
1926+
/* x - x = 0 */
1927+
if (insn->opcode == OP_sub && insn->rd) {
1928+
insn->opcode = OP_load_constant;
1929+
insn->rd->is_const = true;
1930+
insn->rd->init_val = 0;
1931+
insn->rs1 = NULL;
1932+
insn->rs2 = NULL;
1933+
}
1934+
/* x ^ x = 0 */
1935+
else if (insn->opcode == OP_bit_xor && insn->rd) {
1936+
insn->opcode = OP_load_constant;
1937+
insn->rd->is_const = true;
1938+
insn->rd->init_val = 0;
1939+
insn->rs1 = NULL;
1940+
insn->rs2 = NULL;
1941+
}
1942+
/* x & x = x */
1943+
else if (insn->opcode == OP_bit_and && insn->rd) {
1944+
insn->opcode = OP_assign;
1945+
insn->rs2 = NULL;
1946+
}
1947+
/* x | x = x */
1948+
else if (insn->opcode == OP_bit_or && insn->rd) {
1949+
insn->opcode = OP_assign;
1950+
insn->rs2 = NULL;
1951+
}
1952+
/* x == x = 1 */
1953+
else if (insn->opcode == OP_eq && insn->rd) {
1954+
insn->opcode = OP_load_constant;
1955+
insn->rd->is_const = true;
1956+
insn->rd->init_val = 1;
1957+
insn->rs1 = NULL;
1958+
insn->rs2 = NULL;
1959+
}
1960+
/* x != x = 0 */
1961+
else if (insn->opcode == OP_neq && insn->rd) {
1962+
insn->opcode = OP_load_constant;
1963+
insn->rd->is_const = true;
1964+
insn->rd->init_val = 0;
1965+
insn->rs1 = NULL;
1966+
insn->rs2 = NULL;
1967+
}
1968+
/* x < x = 0, x > x = 0 */
1969+
else if ((insn->opcode == OP_lt || insn->opcode == OP_gt) &&
1970+
insn->rd) {
1971+
insn->opcode = OP_load_constant;
1972+
insn->rd->is_const = true;
1973+
insn->rd->init_val = 0;
1974+
insn->rs1 = NULL;
1975+
insn->rs2 = NULL;
1976+
}
1977+
/* x <= x = 1, x >= x = 1 */
1978+
else if ((insn->opcode == OP_leq ||
1979+
insn->opcode == OP_geq) &&
1980+
insn->rd) {
1981+
insn->opcode = OP_load_constant;
1982+
insn->rd->is_const = true;
1983+
insn->rd->init_val = 1;
1984+
insn->rs1 = NULL;
1985+
insn->rs2 = NULL;
1986+
}
1987+
}
1988+
1989+
/* Identity and constant optimizations */
1990+
if (insn->rs2 && insn->rs2->is_const && insn->rd) {
1991+
int val = insn->rs2->init_val;
1992+
1993+
/* x + 0 = x, x - 0 = x, x | 0 = x, x ^ 0 = x */
1994+
if (val == 0) {
1995+
if (insn->opcode == OP_add || insn->opcode == OP_sub ||
1996+
insn->opcode == OP_bit_or ||
1997+
insn->opcode == OP_bit_xor) {
1998+
insn->opcode = OP_assign;
1999+
insn->rs2 = NULL;
2000+
}
2001+
/* x * 0 = 0, x & 0 = 0 */
2002+
else if (insn->opcode == OP_mul ||
2003+
insn->opcode == OP_bit_and) {
2004+
insn->opcode = OP_load_constant;
2005+
insn->rd->is_const = true;
2006+
insn->rd->init_val = 0;
2007+
insn->rs1 = NULL;
2008+
insn->rs2 = NULL;
2009+
}
2010+
/* x << 0 = x, x >> 0 = x */
2011+
else if (insn->opcode == OP_lshift ||
2012+
insn->opcode == OP_rshift) {
2013+
insn->opcode = OP_assign;
2014+
insn->rs2 = NULL;
2015+
}
2016+
}
2017+
/* x * 1 = x, x / 1 = x */
2018+
else if (val == 1) {
2019+
if (insn->opcode == OP_mul || insn->opcode == OP_div) {
2020+
insn->opcode = OP_assign;
2021+
insn->rs2 = NULL;
2022+
}
2023+
/* x % 1 = 0 */
2024+
else if (insn->opcode == OP_mod) {
2025+
insn->opcode = OP_load_constant;
2026+
insn->rd->is_const = true;
2027+
insn->rd->init_val = 0;
2028+
insn->rs1 = NULL;
2029+
insn->rs2 = NULL;
2030+
}
2031+
}
2032+
/* x & -1 = x (all bits set) */
2033+
else if (val == -1) {
2034+
if (insn->opcode == OP_bit_and) {
2035+
insn->opcode = OP_assign;
2036+
insn->rs2 = NULL;
2037+
}
2038+
/* x | -1 = -1 */
2039+
else if (insn->opcode == OP_bit_or) {
2040+
insn->opcode = OP_load_constant;
2041+
insn->rd->is_const = true;
2042+
insn->rd->init_val = -1;
2043+
insn->rs1 = NULL;
2044+
insn->rs2 = NULL;
2045+
}
2046+
/* x * -1 = -x */
2047+
else if (insn->opcode == OP_mul) {
2048+
insn->opcode = OP_negate;
2049+
insn->rs2 = NULL;
2050+
}
2051+
}
2052+
}
2053+
19232054
/* more optimizations */
19242055
}
19252056
}

0 commit comments

Comments
 (0)