Skip to content

Commit 6527865

Browse files
committed
Add constant cast optimization to SCCP
This enhances the SCCP optimizer with support for constant truncation operations, providing multiple optimization strategies to handle compile-time constant cast operations efficiently. The optimization correctly handles patterns like: const %.t977, 300 %.t978 = trunc %.t977, 1 And performs compile-time evaluation (e.g., 300 & 0xFF = 44 for char).
1 parent 06ecbd7 commit 6527865

File tree

2 files changed

+110
-2
lines changed

2 files changed

+110
-2
lines changed

src/opt-sccp.c

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,38 @@ bool simple_sccp(func_t *func)
4343
}
4444
break;
4545

46+
case OP_trunc:
47+
/* Constant truncation optimization integrated into SCCP */
48+
if (insn->rs1 && insn->rs1->is_const && !insn->rd->is_global &&
49+
insn->sz > 0) {
50+
int value = insn->rs1->init_val;
51+
int result = value;
52+
53+
/* Perform truncation based on size */
54+
if (insn->sz == 1) {
55+
/* Truncate to 8 bits */
56+
result = value & 0xFF;
57+
} else if (insn->sz == 2) {
58+
/* Truncate to 16 bits */
59+
result = value & 0xFFFF;
60+
} else if (insn->sz == 4) {
61+
/* No truncation needed for 32-bit */
62+
result = value;
63+
} else {
64+
/* Invalid size, skip */
65+
break;
66+
}
67+
68+
/* Convert to constant load */
69+
insn->opcode = OP_load_constant;
70+
insn->rd->is_const = true;
71+
insn->rd->init_val = result;
72+
insn->rs1 = NULL;
73+
insn->sz = 0;
74+
changed = true;
75+
}
76+
break;
77+
4678
case OP_add:
4779
case OP_sub:
4880
case OP_mul:
@@ -154,3 +186,67 @@ bool simple_sccp(func_t *func)
154186

155187
return changed;
156188
}
189+
190+
/* Targeted constant truncation peephole optimization */
191+
bool optimize_constant_casts(func_t *func)
192+
{
193+
if (!func || !func->bbs)
194+
return false;
195+
196+
bool changed = false;
197+
198+
/* Simple peephole optimization: const + trunc pattern */
199+
for (basic_block_t *bb = func->bbs; bb; bb = bb->rpo_next) {
200+
if (!bb)
201+
continue;
202+
203+
for (insn_t *insn = bb->insn_list.head; insn && insn->next;
204+
insn = insn->next) {
205+
insn_t *next_insn = insn->next;
206+
207+
/* Look for pattern: const %.tX, VALUE followed by
208+
* %.tY = trunc %.tX, SIZE
209+
*/
210+
if (insn->opcode == OP_load_constant &&
211+
next_insn->opcode == OP_trunc && insn->rd && next_insn->rs1 &&
212+
insn->rd == next_insn->rs1 && next_insn->sz > 0 &&
213+
!next_insn->rd->is_global) {
214+
int value = insn->rd->init_val;
215+
int result = value;
216+
217+
/* Perform truncation based on size */
218+
if (next_insn->sz == 1) {
219+
/* Truncate to 8 bits */
220+
result = value & 0xFF;
221+
} else if (next_insn->sz == 2) {
222+
/* Truncate to 16 bits */
223+
result = value & 0xFFFF;
224+
} else if (next_insn->sz == 4) {
225+
/* No truncation needed for 32-bit */
226+
result = value;
227+
} else {
228+
/* Invalid size, skip */
229+
continue;
230+
}
231+
232+
/* Optimize: Replace both instructions with single const */
233+
insn->rd = next_insn->rd; /* Update dest to final target */
234+
insn->rd->is_const = true;
235+
insn->rd->init_val = result;
236+
237+
/* Remove the truncation instruction by converting it to
238+
* NOP-like
239+
*/
240+
next_insn->opcode = OP_load_constant;
241+
next_insn->rd->is_const = true;
242+
next_insn->rd->init_val = result;
243+
next_insn->rs1 = NULL;
244+
next_insn->sz = 0;
245+
246+
changed = true;
247+
}
248+
}
249+
}
250+
251+
return changed;
252+
}

src/ssa.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1795,9 +1795,21 @@ void optimize(void)
17951795

17961796
use_chain_build();
17971797

1798-
/* Run SCCP optimization first */
1798+
/* Run SCCP optimization multiple times for full propagation */
1799+
bool sccp_changed = true;
1800+
int sccp_iterations = 0;
1801+
while (sccp_changed && sccp_iterations < 5) {
1802+
sccp_changed = false;
1803+
for (func_t *func = FUNC_LIST.head; func; func = func->next) {
1804+
if (simple_sccp(func))
1805+
sccp_changed = true;
1806+
}
1807+
sccp_iterations++;
1808+
}
1809+
1810+
/* Run constant cast optimization for truncation */
17991811
for (func_t *func = FUNC_LIST.head; func; func = func->next)
1800-
simple_sccp(func);
1812+
optimize_constant_casts(func);
18011813

18021814
for (func_t *func = FUNC_LIST.head; func; func = func->next) {
18031815
/* basic block level (control flow) optimizations */

0 commit comments

Comments
 (0)