Skip to content

Commit a06e3c6

Browse files
committed
Improve dead code elimination
Enhanced dead store elimination to detect stores overwritten within a small window (3 instructions). The optimization: - Checks for intervening uses before marking as dead - Stops at control flow boundaries for safety - Marks dead stores for removal by DCE sweep This catches common patterns like consecutive assignments while remaining conservative to avoid incorrect elimination.
1 parent 81fa621 commit a06e3c6

File tree

1 file changed

+43
-17
lines changed

1 file changed

+43
-17
lines changed

src/ssa.c

Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
#define PHI_WORKLIST_SIZE 64
1919
#define DCE_WORKLIST_SIZE 2048
2020

21+
/* Dead store elimination window size */
22+
#define OVERWRITE_WINDOW 3
23+
2124
/* cfront does not accept structure as an argument, pass pointer */
2225
void bb_forward_traversal(bb_traversal_args_t *args)
2326
{
@@ -1836,24 +1839,47 @@ void optimize(void)
18361839
continue;
18371840
}
18381841

1839-
/* Dead store elimination - conservative */
1840-
if (insn->opcode == OP_store || insn->opcode == OP_write) {
1841-
/* Only eliminate if target is local and immediately
1842-
* overwritten
1843-
*/
1844-
if (insn->rd && !insn->rd->is_global && insn->next) {
1845-
insn_t *next_insn = insn->next;
1842+
/* Improved dead store elimination */
1843+
if (insn->opcode == OP_store || insn->opcode == OP_write ||
1844+
insn->opcode == OP_global_store) {
1845+
if (insn->rd && !insn->rd->is_global) {
1846+
/* Look for overwrites within a small window */
1847+
insn_t *check = insn->next;
1848+
int distance = 0;
1849+
bool found_overwrite = false;
1850+
1851+
while (check && distance < OVERWRITE_WINDOW) {
1852+
/* Stop at control flow changes */
1853+
if (check->opcode == OP_branch ||
1854+
check->opcode == OP_jump ||
1855+
check->opcode == OP_call ||
1856+
check->opcode == OP_return) {
1857+
break;
1858+
}
18461859

1847-
/* Check for immediate overwrite with no intervening
1848-
* instructions
1849-
*/
1850-
if ((next_insn->opcode == OP_store ||
1851-
next_insn->opcode == OP_write) &&
1852-
next_insn->rd == insn->rd) {
1853-
/* Eliminate only immediate overwrites */
1854-
insn->rd = NULL;
1855-
insn->rs1 = NULL;
1856-
insn->rs2 = NULL;
1860+
/* Check if there's a use of the stored location */
1861+
if ((check->opcode == OP_load ||
1862+
check->opcode == OP_read) &&
1863+
check->rs1 == insn->rd) {
1864+
break; /* Store is needed */
1865+
}
1866+
1867+
/* Found overwrite */
1868+
if ((check->opcode == OP_store ||
1869+
check->opcode == OP_write ||
1870+
check->opcode == OP_global_store) &&
1871+
check->rd == insn->rd) {
1872+
found_overwrite = true;
1873+
break;
1874+
}
1875+
1876+
check = check->next;
1877+
distance++;
1878+
}
1879+
1880+
if (found_overwrite) {
1881+
/* Mark for removal by DCE */
1882+
insn->useful = false;
18571883
}
18581884
}
18591885
}

0 commit comments

Comments
 (0)