Precisely one stack hreg gets allocated for each vreg/congruence group for
eviction; this prevents us from having to worry about moving values from stack slot to stack slot, which is hard.
This commit is contained in:
		
							parent
							
								
									b7a1c96986
								
							
						
					
					
						commit
						d2c14ca44f
					
				
					 6 changed files with 32 additions and 9 deletions
				
			
		|  | @ -127,7 +127,7 @@ struct hop* platform_epilogue(void) | |||
| 	return hop; | ||||
| } | ||||
| 
 | ||||
| struct hop* platform_move(struct basicblock* bb, struct hreg* src, struct hreg* dest) | ||||
| struct hop* platform_move(struct basicblock* bb, struct vreg* vreg, struct hreg* src, struct hreg* dest) | ||||
| { | ||||
|     struct hop* hop = new_hop(bb, NULL); | ||||
| 
 | ||||
|  | @ -280,6 +280,8 @@ struct hop* platform_move(struct basicblock* bb, struct hreg* src, struct hreg* | |||
|                     goto nomove; | ||||
|             } | ||||
|         } | ||||
|         else if (src->is_stacked && dest->is_stacked) | ||||
|             fatal("tried to move stacked object %%%d of type 0x%x from %s to %s", vreg->id, type, src->id, dest->id); | ||||
|         else | ||||
|             goto nomove; | ||||
|     } | ||||
|  | @ -294,6 +296,7 @@ struct hop* platform_swap(struct basicblock* bb, struct hreg* src, struct hreg* | |||
| { | ||||
|     struct hop* hop = new_hop(bb, NULL); | ||||
| 
 | ||||
| 	tracef('R', "R: swap of %s to %s\n", src->id, dest->id); | ||||
|     assert(!src->is_stacked); | ||||
|     assert(!dest->is_stacked); | ||||
|     assert((src->attrs & TYPE_ATTRS) == (dest->attrs & TYPE_ATTRS)); | ||||
|  |  | |||
|  | @ -128,7 +128,7 @@ struct hop* platform_epilogue(void) | |||
| 	return hop; | ||||
| } | ||||
| 
 | ||||
| struct hop* platform_move(struct basicblock* bb, struct hreg* src, struct hreg* dest) | ||||
| struct hop* platform_move(struct basicblock* bb, struct vreg* vreg, struct hreg* src, struct hreg* dest) | ||||
| { | ||||
|     struct hop* hop = new_hop(bb, NULL); | ||||
| 
 | ||||
|  |  | |||
|  | @ -123,7 +123,7 @@ extern void pass_wire_up_return_values(void); | |||
| extern void platform_calculate_offsets(void); | ||||
| extern struct hop* platform_prologue(void); | ||||
| extern struct hop* platform_epilogue(void); | ||||
| extern struct hop* platform_move(struct basicblock* bb, struct hreg* src, struct hreg* dest); | ||||
| extern struct hop* platform_move(struct basicblock* bb, struct vreg* vreg, struct hreg* src, struct hreg* dest); | ||||
| extern struct hop* platform_swap(struct basicblock* bb, struct hreg* src, struct hreg* dest); | ||||
| extern const char* platform_label(const char* label); | ||||
| 
 | ||||
|  |  | |||
|  | @ -10,7 +10,8 @@ static void make_phimap(void) | |||
| 	for (i=0; i<cfg.preorder.count; i++) | ||||
| 	{ | ||||
| 		struct basicblock* bb = cfg.preorder.item[i]; | ||||
| 		 | ||||
| 
 | ||||
| 		/* Registers imported through a phi can come from multiple locations. */ | ||||
| 		for (j=0; j<bb->phis.count; j++) | ||||
| 		{ | ||||
| 			struct vreg* vreg = bb->phis.item[j].left; | ||||
|  |  | |||
|  | @ -386,16 +386,28 @@ static void find_new_home_for_evicted_register(struct vreg* vreg, struct hreg* s | |||
|     for (i=0; i<hregs.count; i++) | ||||
|     { | ||||
|         hreg = hregs.item[i]; | ||||
|         if ((hreg->attrs & srctype) && | ||||
|         if (!hreg->is_stacked && (hreg->attrs & srctype) && | ||||
|             allocatable_through(hreg, vreg)) | ||||
|         { | ||||
|             goto found; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /* No more registers --- allocate a stack slot. */ | ||||
|     /* No more registers --- allocate a stack slot. Ensure that we use the same stack
 | ||||
|      * slot for this vreg throughout the function. */ | ||||
| 
 | ||||
|     hreg = new_stacked_hreg(srctype); | ||||
| 	hreg = vreg->evicted; | ||||
| 	if (!hreg) | ||||
| 	{ | ||||
| 		if (vreg->congruence) | ||||
| 			hreg = vreg->evicted = vreg->congruence->evicted; | ||||
| 		if (!hreg) | ||||
| 		{ | ||||
| 			hreg = vreg->evicted = new_stacked_hreg(srctype); | ||||
| 			if (vreg->congruence) | ||||
| 				vreg->congruence->evicted = hreg; | ||||
| 		} | ||||
| 	} | ||||
|     array_append(&hregs, hreg); | ||||
| 
 | ||||
| found: | ||||
|  | @ -617,7 +629,8 @@ static int insert_moves(struct basicblock* bb, int index, | |||
|         { | ||||
|             /* Copy. */ | ||||
| 
 | ||||
|             hop = platform_move(bb, src, dest); | ||||
| 			struct vreg* vreg = pmap_findleft(srcregs, src); | ||||
|             hop = platform_move(bb, vreg, src, dest); | ||||
|             pmap_remove(&copies, src, dest); | ||||
|         } | ||||
|         else | ||||
|  | @ -710,13 +723,17 @@ static void insert_phi_copies(void) | |||
| 
 | ||||
|             for (k=0; k<bb->regsin.count; k++) | ||||
|             { | ||||
|                 struct hreg*hreg = bb->regsin.item[k].left; | ||||
|                 struct hreg* hreg = bb->regsin.item[k].left; | ||||
|                 struct vreg* vreg = bb->regsin.item[k].right; | ||||
|                 struct hreg* src = pmap_findright(prevbb->regsout, vreg); | ||||
|                 if (!pmap_findleft(&bb->phis, vreg)) | ||||
|                 { | ||||
|                     tracef('R', "R: input map %%%d (%s) -> (%s)\n", | ||||
|                         vreg->id, src->id, hreg->id); | ||||
|                     if ((src->id != hreg->id) && src->is_stacked && hreg->is_stacked) | ||||
|                         fatal("vreg %%%d is stacked in %s on entry to %s, but is passed in in %s from %s", | ||||
|                             vreg->id, hreg->id, bb->name, | ||||
|                             src->id, prevbb->name); | ||||
| 
 | ||||
|                     pmap_add(&destregs, hreg, vreg); | ||||
|                 } | ||||
|  |  | |||
|  | @ -9,6 +9,7 @@ struct phicongruence | |||
|     ARRAYOF(struct vreg) vregs; | ||||
|     ARRAYOF(struct hop) definitions; | ||||
|     uint32_t type; | ||||
|     struct hreg* evicted; /* stack slot to evict to */ | ||||
| }; | ||||
| 
 | ||||
| struct hreg | ||||
|  | @ -28,6 +29,7 @@ struct vreg | |||
|     struct phicongruence* congruence; | ||||
|     struct hop* defined; | ||||
|     ARRAYOF(struct hop) used; | ||||
|     struct hreg* evicted; /* stack slot to evict to */ | ||||
| }; | ||||
| 
 | ||||
| typedef PMAPOF(struct hreg, struct vreg) register_assignment_t; | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue