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; | 	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); |     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; |                     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 |         else | ||||||
|             goto nomove; |             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); |     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(!src->is_stacked); | ||||||
|     assert(!dest->is_stacked); |     assert(!dest->is_stacked); | ||||||
|     assert((src->attrs & TYPE_ATTRS) == (dest->attrs & TYPE_ATTRS)); |     assert((src->attrs & TYPE_ATTRS) == (dest->attrs & TYPE_ATTRS)); | ||||||
|  |  | ||||||
|  | @ -128,7 +128,7 @@ struct hop* platform_epilogue(void) | ||||||
| 	return hop; | 	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); |     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 void platform_calculate_offsets(void); | ||||||
| extern struct hop* platform_prologue(void); | extern struct hop* platform_prologue(void); | ||||||
| extern struct hop* platform_epilogue(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 struct hop* platform_swap(struct basicblock* bb, struct hreg* src, struct hreg* dest); | ||||||
| extern const char* platform_label(const char* label); | 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++) | 	for (i=0; i<cfg.preorder.count; i++) | ||||||
| 	{ | 	{ | ||||||
| 		struct basicblock* bb = cfg.preorder.item[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++) | 		for (j=0; j<bb->phis.count; j++) | ||||||
| 		{ | 		{ | ||||||
| 			struct vreg* vreg = bb->phis.item[j].left; | 			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++) |     for (i=0; i<hregs.count; i++) | ||||||
|     { |     { | ||||||
|         hreg = hregs.item[i]; |         hreg = hregs.item[i]; | ||||||
|         if ((hreg->attrs & srctype) && |         if (!hreg->is_stacked && (hreg->attrs & srctype) && | ||||||
|             allocatable_through(hreg, vreg)) |             allocatable_through(hreg, vreg)) | ||||||
|         { |         { | ||||||
|             goto found; |             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); |     array_append(&hregs, hreg); | ||||||
| 
 | 
 | ||||||
| found: | found: | ||||||
|  | @ -617,7 +629,8 @@ static int insert_moves(struct basicblock* bb, int index, | ||||||
|         { |         { | ||||||
|             /* Copy. */ |             /* 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); |             pmap_remove(&copies, src, dest); | ||||||
|         } |         } | ||||||
|         else |         else | ||||||
|  | @ -710,13 +723,17 @@ static void insert_phi_copies(void) | ||||||
| 
 | 
 | ||||||
|             for (k=0; k<bb->regsin.count; k++) |             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 vreg* vreg = bb->regsin.item[k].right; | ||||||
|                 struct hreg* src = pmap_findright(prevbb->regsout, vreg); |                 struct hreg* src = pmap_findright(prevbb->regsout, vreg); | ||||||
|                 if (!pmap_findleft(&bb->phis, vreg)) |                 if (!pmap_findleft(&bb->phis, vreg)) | ||||||
|                 { |                 { | ||||||
|                     tracef('R', "R: input map %%%d (%s) -> (%s)\n", |                     tracef('R', "R: input map %%%d (%s) -> (%s)\n", | ||||||
|                         vreg->id, src->id, hreg->id); |                         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); |                     pmap_add(&destregs, hreg, vreg); | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|  | @ -9,6 +9,7 @@ struct phicongruence | ||||||
|     ARRAYOF(struct vreg) vregs; |     ARRAYOF(struct vreg) vregs; | ||||||
|     ARRAYOF(struct hop) definitions; |     ARRAYOF(struct hop) definitions; | ||||||
|     uint32_t type; |     uint32_t type; | ||||||
|  |     struct hreg* evicted; /* stack slot to evict to */ | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct hreg | struct hreg | ||||||
|  | @ -28,6 +29,7 @@ struct vreg | ||||||
|     struct phicongruence* congruence; |     struct phicongruence* congruence; | ||||||
|     struct hop* defined; |     struct hop* defined; | ||||||
|     ARRAYOF(struct hop) used; |     ARRAYOF(struct hop) used; | ||||||
|  |     struct hreg* evicted; /* stack slot to evict to */ | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| typedef PMAPOF(struct hreg, struct vreg) register_assignment_t; | typedef PMAPOF(struct hreg, struct vreg) register_assignment_t; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue