(needed for CHAINFP and FPTOAB). Wire up lfrs to calls via a phi when necessary, to allow call-bra-lfr chains.
		
			
				
	
	
		
			75 lines
		
	
	
	
		
			1.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			75 lines
		
	
	
	
		
			1.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include "mcg.h"
 | |
| 
 | |
| static bool finished;
 | |
| 
 | |
| static void preload_blocks(void)
 | |
| {
 | |
|     /* Any variable referenced in a phi *must* be a liveout of one of our
 | |
|      * predecessors. */
 | |
| 
 | |
|     int i, j;
 | |
|     for (i=0; i<cfg.preorder.count; i++)
 | |
|     {
 | |
|         struct basicblock* bb = cfg.preorder.item[i];
 | |
| 
 | |
|         for (j=0; j<bb->phis.count; j++)
 | |
|         {
 | |
|             struct vreg* vreg = bb->phis.item[j].left;
 | |
|             struct phi* phi = bb->phis.item[j].right;
 | |
| 
 | |
|             assert(array_contains(&bb->prevs, phi->prev));
 | |
|             array_appendu(&phi->prev->liveouts, phi->ir->result);
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| static void propagate_liveness(struct basicblock* bb)
 | |
| {
 | |
| 	static ARRAYOF(struct vreg) current;
 | |
| 	int i;
 | |
| 
 | |
| 	current.count = 0;
 | |
| 	array_appendall(¤t, &bb->liveouts);
 | |
| 
 | |
| 	for (i=bb->hops.count-1; i>=0; i--)
 | |
| 	{
 | |
| 		struct hop* hop = bb->hops.item[i];
 | |
| 
 | |
| 		array_removeall(¤t, &hop->outs);
 | |
| 		finished &= array_appendallu(&hop->throughs, ¤t);
 | |
| 		array_appendallu(¤t, &hop->ins);
 | |
| 	}
 | |
| 
 | |
|     for (i=0; i<bb->phis.count; i++)
 | |
|         array_remove(¤t, bb->phis.item[i].left);
 | |
| 
 | |
| 	finished &= array_appendallu(&bb->liveins, ¤t);
 | |
| 
 | |
| 	for (i=0; i<bb->prevs.count; i++)
 | |
| 	{
 | |
| 		struct basicblock* prev = bb->prevs.item[i];
 | |
| 		finished &= array_appendallu(&prev->liveouts, ¤t);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| void pass_live_vreg_analysis(void)
 | |
| {
 | |
| 	int i;
 | |
| 
 | |
|     preload_blocks();
 | |
| 
 | |
| 	do
 | |
| 	{
 | |
| 		finished = true;
 | |
| 
 | |
| 		tracef('L', "L: beginning liveness pass\n");
 | |
| 		for (i=0; i<dominance.postorder.count; i++)
 | |
| 			propagate_liveness(dominance.postorder.item[i]);
 | |
| 	}
 | |
| 	while (!finished);
 | |
| 
 | |
|     //assert(cfg.entry->liveins.count == 0);
 | |
| }
 | |
| 
 | |
| /* vim: set sw=4 ts=4 expandtab : */
 | |
| 
 |