Skip to content

Commit db3c389

Browse files
committed
Add redundant move elimination patterns
This commit implements redundant move elimination to optimize away unnecessary move operations that are immediately overwritten, targetting common inefficiencies in compiler-generated code. Added 5 optimization patterns: - Consecutive assignments to same destination: {mov rd,rs1; mov rd,rs2} → {mov rd,rs2} - Load immediately overwritten: {load rd,offset; mov rd,rs} → {mov rd,rs} - Constant load immediately overwritten: {li rd,imm; mov rd,rs} → {mov rd,rs} - Consecutive loads to same register: {load rd,off1; load rd,off2} → {load rd,off2} - Consecutive constant loads: {li rd,imm1; li rd,imm2} → {li rd,imm2}
1 parent 1611d23 commit db3c389

File tree

1 file changed

+85
-1
lines changed

1 file changed

+85
-1
lines changed

src/peephole.c

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,84 @@ bool insn_fusion(ph2_ir_t *ph2_ir)
242242
return false;
243243
}
244244

245+
/* Redundant move elimination
246+
* Eliminates unnecessary move operations that are overwritten or redundant
247+
*/
248+
bool redundant_move_elim(ph2_ir_t *ph2_ir)
249+
{
250+
ph2_ir_t *next = ph2_ir->next;
251+
if (!next)
252+
return false;
253+
254+
/* Pattern 1: Consecutive assignments to same destination
255+
* {mov rd, rs1; mov rd, rs2} → {mov rd, rs2}
256+
* The first move is completely overwritten by the second
257+
*/
258+
if (ph2_ir->op == OP_assign && next->op == OP_assign &&
259+
ph2_ir->dest == next->dest) {
260+
/* Replace first move with second, skip second */
261+
ph2_ir->src0 = next->src0;
262+
ph2_ir->next = next->next;
263+
return true;
264+
}
265+
266+
/* Pattern 2: Redundant load immediately overwritten
267+
* {load rd, offset; mov rd, rs} → {mov rd, rs}
268+
* Loading a value that's immediately replaced is wasteful
269+
*/
270+
if ((ph2_ir->op == OP_load || ph2_ir->op == OP_global_load) &&
271+
next->op == OP_assign && ph2_ir->dest == next->dest) {
272+
/* Replace load with move */
273+
ph2_ir->op = OP_assign;
274+
ph2_ir->src0 = next->src0;
275+
ph2_ir->src1 = 0; /* Clear unused field */
276+
ph2_ir->next = next->next;
277+
return true;
278+
}
279+
280+
/* Pattern 3: Load constant immediately overwritten
281+
* {li rd, imm; mov rd, rs} → {mov rd, rs}
282+
* Loading a constant that's immediately replaced
283+
*/
284+
if (ph2_ir->op == OP_load_constant && next->op == OP_assign &&
285+
ph2_ir->dest == next->dest) {
286+
/* Replace constant load with move */
287+
ph2_ir->op = OP_assign;
288+
ph2_ir->src0 = next->src0;
289+
ph2_ir->next = next->next;
290+
return true;
291+
}
292+
293+
/* Pattern 4: Consecutive loads to same register
294+
* {load rd, offset1; load rd, offset2} → {load rd, offset2}
295+
* First load is pointless if immediately overwritten
296+
*/
297+
if ((ph2_ir->op == OP_load || ph2_ir->op == OP_global_load) &&
298+
(next->op == OP_load || next->op == OP_global_load) &&
299+
ph2_ir->dest == next->dest) {
300+
/* Keep only the second load */
301+
ph2_ir->op = next->op;
302+
ph2_ir->src0 = next->src0;
303+
ph2_ir->src1 = next->src1;
304+
ph2_ir->next = next->next;
305+
return true;
306+
}
307+
308+
/* Pattern 5: Consecutive constant loads (already handled in main loop
309+
* but included here for completeness)
310+
* {li rd, imm1; li rd, imm2} → {li rd, imm2}
311+
*/
312+
if (ph2_ir->op == OP_load_constant && next->op == OP_load_constant &&
313+
ph2_ir->dest == next->dest) {
314+
/* Keep only the second constant */
315+
ph2_ir->src0 = next->src0;
316+
ph2_ir->next = next->next;
317+
return true;
318+
}
319+
320+
return false;
321+
}
322+
245323
/* Main peephole optimization driver.
246324
* It iterates through all functions, basic blocks, and IR instructions to apply
247325
* local optimizations on adjacent instruction pairs.
@@ -265,7 +343,13 @@ void peephole(void)
265343
continue;
266344
}
267345

268-
insn_fusion(ir);
346+
/* Try instruction fusion first */
347+
if (insn_fusion(ir))
348+
continue;
349+
350+
/* Apply redundant move elimination */
351+
if (redundant_move_elim(ir))
352+
continue;
269353
}
270354
}
271355
}

0 commit comments

Comments
 (0)