88 lines
		
	
	
	
		
			1.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			88 lines
		
	
	
	
		
			1.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include "mcg.h"
 | |
| 
 | |
| static ARRAYOF(struct ir) phis;
 | |
| static bool changed;
 | |
| 
 | |
| static void collect_phis(struct basicblock* bb)
 | |
| {
 | |
|     int i;
 | |
| 
 | |
|     for (i=0; i<bb->irs.count; i++)
 | |
|     {
 | |
|         struct ir* ir = bb->irs.item[i];
 | |
|         if (ir->opcode == IR_PHI)
 | |
|             array_append(&phis, ir);
 | |
|     }
 | |
| }
 | |
| 
 | |
| static bool ir_walker_cb(struct ir* ir, void* user)
 | |
| {
 | |
|     if (ir->left)
 | |
|         array_remove(&phis, ir->left);
 | |
|     if (ir->right)
 | |
|         array_remove(&phis, ir->right);
 | |
| 
 | |
|     return false;
 | |
| }
 | |
| 
 | |
| static void remove_referenced_phis(struct basicblock* bb)
 | |
| {
 | |
|     int i, j;
 | |
| 
 | |
|     for (i=0; i<bb->irs.count; i++)
 | |
|     {
 | |
|         struct ir* ir = bb->irs.item[i];
 | |
|         switch (ir->opcode)
 | |
|         {
 | |
|             case IR_PHI:
 | |
|                 for (j=0; j<ir->u.phivalue.count; j++)
 | |
|                     array_remove(&phis, ir->u.phivalue.item[j].right);
 | |
|                 break;
 | |
| 
 | |
|             default:
 | |
|                 ir_walk(ir, ir_walker_cb, NULL);
 | |
|                 break;
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| static void purge_unused_phis(struct basicblock* bb)
 | |
| {
 | |
|     int i;
 | |
|     
 | |
|     for (i=0; i<bb->irs.count; i++)
 | |
|     {
 | |
|         struct ir* ir = bb->irs.item[i];
 | |
|         if ((ir->opcode == IR_PHI) && (array_contains(&phis, ir)))
 | |
|         {
 | |
|             array_remove(&bb->irs, ir);
 | |
|             i--;
 | |
|             changed = true;
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| void pass_remove_dead_phis(void)
 | |
| {
 | |
|     int i;
 | |
|     
 | |
|     do
 | |
|     {
 | |
|         changed = false;
 | |
| 
 | |
|         phis.count = 0;
 | |
|         for (i=0; i<cfg.preorder.count; i++)
 | |
|             collect_phis(cfg.preorder.item[i]);
 | |
| 
 | |
|         for (i=0; i<cfg.preorder.count; i++)
 | |
|             remove_referenced_phis(cfg.preorder.item[i]);
 | |
| 
 | |
|         for (i=0; i<cfg.preorder.count; i++)
 | |
|             purge_unused_phis(cfg.preorder.item[i]);
 | |
|     }
 | |
|     while (changed);
 | |
| }
 | |
| 
 | |
| /* vim: set sw=4 ts=4 expandtab : */
 | |
| 
 | |
| 
 |