@@ -43,6 +43,38 @@ bool simple_sccp(func_t *func)
43
43
}
44
44
break ;
45
45
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
+
46
78
case OP_add :
47
79
case OP_sub :
48
80
case OP_mul :
@@ -154,3 +186,67 @@ bool simple_sccp(func_t *func)
154
186
155
187
return changed ;
156
188
}
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
+ }
0 commit comments