@@ -320,13 +320,129 @@ bool redundant_move_elim(ph2_ir_t *ph2_ir)
320320 return false;
321321}
322322
323+ /* Simple dead instruction elimination within basic blocks.
324+ * Removes instructions whose results are never used (dead stores).
325+ * Works in conjunction with existing SSA-based DCE.
326+ */
327+ bool eliminate_dead_instructions (func_t * func )
328+ {
329+ if (!func || !func -> bbs )
330+ return false;
331+
332+ bool changed = false;
333+
334+ for (basic_block_t * bb = func -> bbs ; bb ; bb = bb -> rpo_next ) {
335+ ph2_ir_t * ir = bb -> ph2_ir_list .head ;
336+ while (ir && ir -> next ) {
337+ ph2_ir_t * next = ir -> next ;
338+
339+ /* Check if next instruction immediately overwrites this one's
340+ * result */
341+ if (ir -> op == OP_load_constant && next -> op == OP_load_constant &&
342+ ir -> dest == next -> dest ) {
343+ /* Consecutive constant loads to same register - first is dead
344+ */
345+ ir -> next = next -> next ;
346+ if (next == bb -> ph2_ir_list .tail ) {
347+ bb -> ph2_ir_list .tail = ir ;
348+ }
349+ changed = true;
350+ continue ;
351+ }
352+
353+ /* Check for dead arithmetic results */
354+ if ((ir -> op == OP_add || ir -> op == OP_sub || ir -> op == OP_mul ) &&
355+ next -> op == OP_assign && ir -> dest == next -> dest ) {
356+ /* Arithmetic result immediately overwritten by assignment */
357+ ir -> next = next -> next ;
358+ if (next == bb -> ph2_ir_list .tail ) {
359+ bb -> ph2_ir_list .tail = ir ;
360+ }
361+ changed = true;
362+ continue ;
363+ }
364+
365+ ir = ir -> next ;
366+ }
367+ }
368+
369+ return changed ;
370+ }
371+
372+ /* Simple constant folding for branches after SCCP.
373+ * Converts branches with obvious constant conditions to jumps.
374+ * Very conservative to maintain bootstrap stability.
375+ */
376+ bool fold_constant_branches (func_t * func )
377+ {
378+ if (!func || !func -> bbs )
379+ return false;
380+
381+ bool changed = false;
382+
383+ for (basic_block_t * bb = func -> bbs ; bb ; bb = bb -> rpo_next ) {
384+ if (!bb -> ph2_ir_list .tail )
385+ continue ;
386+
387+ ph2_ir_t * last = bb -> ph2_ir_list .tail ;
388+
389+ /* Only handle branches */
390+ if (last -> op != OP_branch || last -> src0 < 0 )
391+ continue ;
392+
393+ /* Look for immediately preceding constant load to the same register */
394+ ph2_ir_t * prev = bb -> ph2_ir_list .head ;
395+ ph2_ir_t * found = NULL ;
396+
397+ /* Find the most recent constant load to the branch condition register
398+ */
399+ while (prev && prev != last ) {
400+ if (prev -> op == OP_load_constant && prev -> dest == last -> src0 ) {
401+ found = prev ;
402+ /* Keep looking - want the most recent load */
403+ }
404+ /* Stop if we see any other write to this register */
405+ else if (prev -> dest == last -> src0 ) {
406+ found = NULL ; /* Register was modified, can't fold */
407+ }
408+ prev = prev -> next ;
409+ }
410+
411+ if (found ) {
412+ /* Found constant condition - convert branch to jump */
413+ int const_val = found -> src0 ;
414+
415+ /* Just change the opcode, don't modify CFG edges directly */
416+ last -> op = OP_jump ;
417+
418+ if (const_val != 0 ) {
419+ /* Always take then branch */
420+ last -> next_bb = bb -> then_ ;
421+ } else {
422+ /* Always take else branch */
423+ last -> next_bb = bb -> else_ ;
424+ }
425+
426+ /* Don't modify src0 or CFG edges - let later passes handle it */
427+ changed = true;
428+ }
429+ }
430+
431+ return changed ;
432+ }
433+
323434/* Main peephole optimization driver.
324435 * It iterates through all functions, basic blocks, and IR instructions to apply
325436 * local optimizations on adjacent instruction pairs.
326437 */
327438void peephole (void )
328439{
329440 for (func_t * func = FUNC_LIST .head ; func ; func = func -> next ) {
441+ /* Phase 1: Dead code elimination working with SCCP results */
442+ eliminate_dead_instructions (func );
443+ fold_constant_branches (func );
444+
445+ /* Phase 2: Local peephole optimizations */
330446 for (basic_block_t * bb = func -> bbs ; bb ; bb = bb -> rpo_next ) {
331447 for (ph2_ir_t * ir = bb -> ph2_ir_list .head ; ir ; ir = ir -> next ) {
332448 ph2_ir_t * next = ir -> next ;
0 commit comments