Skip to content

Commit 807f02f

Browse files
committed
Implement multi-instruction analysis and optimization
Add sophisticated cross-instruction optimizations: Store-to-Load Forwarding: - Forward stored values directly to subsequent loads - Eliminate unnecessary memory round-trips - Validate no intervening calls or branches Redundant Load Elimination: - Reuse values from previous loads to same location - Check for no intervening stores or calls - Convert redundant loads to simple assignments Strength Reduction: - Convert multiply by power-of-2 to left shift - Convert divide by power-of-2 to right shift - Convert modulo by power-of-2 to bitwise AND These patterns analyze instruction sequences to find optimization opportunities that single-instruction analysis would miss.
1 parent 474be1a commit 807f02f

File tree

1 file changed

+124
-0
lines changed

1 file changed

+124
-0
lines changed

src/ssa.c

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2051,6 +2051,130 @@ void optimize(void)
20512051
}
20522052
}
20532053

2054+
/* Multi-instruction analysis and optimization */
2055+
/* Store-to-load forwarding */
2056+
if (insn->opcode == OP_load && insn->rs1 && insn->rd) {
2057+
insn_t *search = insn->prev;
2058+
int search_limit = 10; /* Look back up to 10 instructions */
2059+
2060+
while (search && search_limit > 0) {
2061+
/* Found a recent store to the same location */
2062+
if ((search->opcode == OP_store ||
2063+
search->opcode == OP_write ||
2064+
search->opcode == OP_global_store) &&
2065+
search->rd == insn->rs1 && search->rs1) {
2066+
/* Check for intervening calls or branches */
2067+
bool safe_to_forward = true;
2068+
insn_t *check = search->next;
2069+
2070+
while (check && check != insn) {
2071+
if (check->opcode == OP_call ||
2072+
check->opcode == OP_indirect ||
2073+
check->opcode == OP_branch ||
2074+
check->opcode == OP_jump) {
2075+
safe_to_forward = false;
2076+
break;
2077+
}
2078+
check = check->next;
2079+
}
2080+
2081+
if (safe_to_forward) {
2082+
/* Forward the stored value */
2083+
insn->opcode = OP_assign;
2084+
insn->rs1 = search->rs1;
2085+
insn->rs2 = NULL;
2086+
break;
2087+
}
2088+
}
2089+
2090+
/* Stop at control flow changes */
2091+
if (search->opcode == OP_call ||
2092+
search->opcode == OP_branch ||
2093+
search->opcode == OP_jump ||
2094+
search->opcode == OP_indirect) {
2095+
break;
2096+
}
2097+
2098+
search = search->prev;
2099+
search_limit--;
2100+
}
2101+
}
2102+
2103+
/* Redundant load elimination */
2104+
if (insn->opcode == OP_load && insn->rs1 && insn->rd) {
2105+
insn_t *search = bb->insn_list.head;
2106+
2107+
while (search && search != insn) {
2108+
/* Found an earlier load from the same location */
2109+
if (search->opcode == OP_load &&
2110+
search->rs1 == insn->rs1 && search->rd) {
2111+
/* Check if location wasn't modified between loads
2112+
*/
2113+
bool safe_to_reuse = true;
2114+
insn_t *check = search->next;
2115+
2116+
while (check && check != insn) {
2117+
/* Check for stores to the same location */
2118+
if ((check->opcode == OP_store ||
2119+
check->opcode == OP_global_store ||
2120+
check->opcode == OP_write) &&
2121+
check->rd == insn->rs1) {
2122+
safe_to_reuse = false;
2123+
break;
2124+
}
2125+
/* Function calls might modify memory */
2126+
if (check->opcode == OP_call ||
2127+
check->opcode == OP_indirect) {
2128+
safe_to_reuse = false;
2129+
break;
2130+
}
2131+
check = check->next;
2132+
}
2133+
2134+
if (safe_to_reuse) {
2135+
/* Replace with assignment from previous load */
2136+
insn->opcode = OP_assign;
2137+
insn->rs1 = search->rd;
2138+
insn->rs2 = NULL;
2139+
break;
2140+
}
2141+
}
2142+
search = search->next;
2143+
}
2144+
}
2145+
2146+
/* Strength reduction for power-of-2 operations */
2147+
if (insn->rs2 && insn->rs2->is_const && insn->rd) {
2148+
int val = insn->rs2->init_val;
2149+
2150+
/* Check if value is power of 2 */
2151+
if (val > 0 && (val & (val - 1)) == 0) {
2152+
/* Count trailing zeros to get shift amount */
2153+
int shift = 0;
2154+
int temp = val;
2155+
while ((temp & 1) == 0) {
2156+
temp >>= 1;
2157+
shift++;
2158+
}
2159+
2160+
/* x * power_of_2 = x << shift */
2161+
if (insn->opcode == OP_mul) {
2162+
insn->opcode = OP_lshift;
2163+
insn->rs2->init_val = shift;
2164+
}
2165+
/* x / power_of_2 = x >> shift (unsigned) */
2166+
else if (insn->opcode == OP_div) {
2167+
insn->opcode = OP_rshift;
2168+
insn->rs2->init_val = shift;
2169+
}
2170+
/* x % power_of_2 = x & (power_of_2 - 1) */
2171+
else if (insn->opcode == OP_mod) {
2172+
insn->opcode = OP_bit_and;
2173+
insn->rs2->init_val = val - 1;
2174+
}
2175+
}
2176+
}
2177+
20542178
/* more optimizations */
20552179
}
20562180
}

0 commit comments

Comments
 (0)