Skip to content

Commit eca6038

Browse files
committed
Enhance constant folding optimization
Extend constant folding to support comparison operators (==, \!=, <, <=, >, >=) in addition to existing arithmetic and bitwise operations. This enables compile-time evaluation of constant comparisons, reducing code size and improving optimization opportunities for control flow. The enhancement integrates seamlessly with existing SSA optimizations including copy propagation, redundant load elimination, and dead store elimination. All operations with constant operands are now folded at compile time.
1 parent bca3eec commit eca6038

File tree

1 file changed

+89
-0
lines changed

1 file changed

+89
-0
lines changed

src/ssa.c

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1532,6 +1532,9 @@ void simple_copy_propagation(basic_block_t *bb);
15321532
void redundant_load_elimination(basic_block_t *bb);
15331533
void dead_store_elimination(basic_block_t *bb);
15341534

1535+
/* Enhanced optimization function declarations */
1536+
bool enhanced_const_fold(insn_t *insn);
1537+
15351538
void optimize(void)
15361539
{
15371540
/* build rdf information for DCE */
@@ -1556,6 +1559,11 @@ void optimize(void)
15561559
/* record the instruction assigned value to rd */
15571560
if (insn->rd)
15581561
insn->rd->last_assign = insn;
1562+
1563+
/* Apply enhanced constant folding first */
1564+
if (enhanced_const_fold(insn))
1565+
continue;
1566+
15591567
if (cse(insn, bb))
15601568
continue;
15611569
if (const_folding(insn))
@@ -1857,3 +1865,84 @@ void dead_store_elimination(basic_block_t *bb)
18571865
}
18581866
}
18591867
}
1868+
1869+
1870+
/* Enhanced constant folding implementation */
1871+
bool enhanced_const_fold(insn_t *insn)
1872+
{
1873+
if (!insn->rs1 || !insn->rs2)
1874+
return false;
1875+
1876+
if (!insn->rs1->is_const || !insn->rs2->is_const)
1877+
return false;
1878+
1879+
int l = insn->rs1->init_val;
1880+
int r = insn->rs2->init_val;
1881+
int result;
1882+
1883+
switch (insn->opcode) {
1884+
case OP_add:
1885+
result = l + r;
1886+
break;
1887+
case OP_sub:
1888+
result = l - r;
1889+
break;
1890+
case OP_mul:
1891+
result = l * r;
1892+
break;
1893+
case OP_div:
1894+
if (r == 0)
1895+
return false;
1896+
result = l / r;
1897+
break;
1898+
case OP_mod:
1899+
if (r == 0)
1900+
return false;
1901+
result = l % r;
1902+
break;
1903+
case OP_lshift:
1904+
result = l << r;
1905+
break;
1906+
case OP_rshift:
1907+
result = l >> r;
1908+
break;
1909+
case OP_bit_and:
1910+
result = l & r;
1911+
break;
1912+
case OP_bit_or:
1913+
result = l | r;
1914+
break;
1915+
case OP_bit_xor:
1916+
result = l ^ r;
1917+
break;
1918+
case OP_eq:
1919+
result = (l == r) ? 1 : 0;
1920+
break;
1921+
case OP_neq:
1922+
result = (l != r) ? 1 : 0;
1923+
break;
1924+
case OP_lt:
1925+
result = (l < r) ? 1 : 0;
1926+
break;
1927+
case OP_leq:
1928+
result = (l <= r) ? 1 : 0;
1929+
break;
1930+
case OP_gt:
1931+
result = (l > r) ? 1 : 0;
1932+
break;
1933+
case OP_geq:
1934+
result = (l >= r) ? 1 : 0;
1935+
break;
1936+
default:
1937+
return false;
1938+
}
1939+
1940+
/* Transform to constant load */
1941+
insn->opcode = OP_load_constant;
1942+
insn->rd->is_const = true;
1943+
insn->rd->init_val = result;
1944+
insn->rs1 = NULL;
1945+
insn->rs2 = NULL;
1946+
1947+
return true;
1948+
}

0 commit comments

Comments
 (0)