|
18 | 18 | #define PHI_WORKLIST_SIZE 64
|
19 | 19 | #define DCE_WORKLIST_SIZE 2048
|
20 | 20 |
|
| 21 | +/* Dead store elimination window size */ |
| 22 | +#define OVERWRITE_WINDOW 3 |
| 23 | + |
21 | 24 | /* cfront does not accept structure as an argument, pass pointer */
|
22 | 25 | void bb_forward_traversal(bb_traversal_args_t *args)
|
23 | 26 | {
|
@@ -1836,24 +1839,47 @@ void optimize(void)
|
1836 | 1839 | continue;
|
1837 | 1840 | }
|
1838 | 1841 |
|
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 | + } |
1846 | 1859 |
|
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; |
1857 | 1883 | }
|
1858 | 1884 | }
|
1859 | 1885 | }
|
|
0 commit comments