Phi copies are now inserted as part of type inference. More opcodes.
This commit is contained in:
		
							parent
							
								
									111c13e253
								
							
						
					
					
						commit
						45a7f2e993
					
				
					 3 changed files with 87 additions and 29 deletions
				
			
		|  | @ -184,6 +184,11 @@ struct hop* platform_move(struct basicblock* bb, struct hreg* src, struct hreg* | ||||||
|                     hop_add_insel(hop, "stfs %H, %S(fp) ! %H", src, dest, dest); |                     hop_add_insel(hop, "stfs %H, %S(fp) ! %H", src, dest, dest); | ||||||
|                     break; |                     break; | ||||||
| 
 | 
 | ||||||
|  |                 case burm_long_ATTR: | ||||||
|  |                     hop_add_insel(hop, "stw %0H, 4+%S(fp) ! %H", src, dest, dest); | ||||||
|  |                     hop_add_insel(hop, "stw %1H, 0+%S(fp) ! %H", src, dest, dest); | ||||||
|  |                     break; | ||||||
|  | 
 | ||||||
|                 case burm_double_ATTR: |                 case burm_double_ATTR: | ||||||
|                     hop_add_insel(hop, "stfd %H, %S(fp) ! %H", src, dest, dest); |                     hop_add_insel(hop, "stfd %H, %S(fp) ! %H", src, dest, dest); | ||||||
|                     break; |                     break; | ||||||
|  |  | ||||||
|  | @ -237,7 +237,7 @@ PATTERNS | ||||||
|         cost 16; |         cost 16; | ||||||
| 
 | 
 | ||||||
|     out:(long)reg = COPYD.L(in:(double)reg) |     out:(long)reg = COPYD.L(in:(double)reg) | ||||||
|         emit "sfdu %in, -8(sp)" |         emit "stfdu %in, -8(sp)" | ||||||
|         emit "lwz %out.0, 4(sp)" |         emit "lwz %out.0, 4(sp)" | ||||||
|         emit "lwz %out.1, 0(sp)" |         emit "lwz %out.1, 0(sp)" | ||||||
|         emit "addi sp, sp, 8" |         emit "addi sp, sp, 8" | ||||||
|  | @ -249,10 +249,14 @@ PATTERNS | ||||||
| 
 | 
 | ||||||
|     /* Stores */ |     /* Stores */ | ||||||
| 
 | 
 | ||||||
|  | 	STORE.D(addr:address, value:(double)reg) | ||||||
|  |         emit "sfd %value, %addr" | ||||||
|  | 		cost 4; | ||||||
|  | 
 | ||||||
| 	STORE.L(addr:address, value:(long)reg) | 	STORE.L(addr:address, value:(long)reg) | ||||||
| 		emit "stw %value.0, 4+%addr" | 		emit "stw %value.0, 4+%addr" | ||||||
| 		emit "stw %value.1, 0+%addr" | 		emit "stw %value.1, 0+%addr" | ||||||
| 		cost 4; | 		cost 8; | ||||||
| 
 | 
 | ||||||
| 	STORE.I(addr:address, value:(int)reg) | 	STORE.I(addr:address, value:(int)reg) | ||||||
| 		emit "stw %value, %addr" | 		emit "stw %value, %addr" | ||||||
|  | @ -379,6 +383,11 @@ PATTERNS | ||||||
|         emit "bl .fromf2l" |         emit "bl .fromf2l" | ||||||
|         cost 4; |         cost 4; | ||||||
| 
 | 
 | ||||||
|  |     out:(long)reg = FROMSI.D(in:(double)reg) | ||||||
|  |         with corrupted(volatile) | ||||||
|  |         emit "bl .fromsi2d" | ||||||
|  |         cost 4; | ||||||
|  | 
 | ||||||
| #if 0 | #if 0 | ||||||
| 	/* byte conversions */ | 	/* byte conversions */ | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -226,7 +226,37 @@ static struct ir* new_copy(char wanted, char real, struct ir* ir) | ||||||
| 	return copy; | 	return copy; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void insert_copies(void) | static void insert_copy(struct ir* ir, struct ir** child, char returntype, char childtype) | ||||||
|  | { | ||||||
|  |     if (*child) | ||||||
|  |     { | ||||||
|  |         char wanted; | ||||||
|  |         char real; | ||||||
|  | 
 | ||||||
|  |         if ((returntype == '?') && (childtype == '?')) | ||||||
|  |         { | ||||||
|  |             wanted = ir->type; | ||||||
|  |             real = (*child)->type; | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             wanted = effective_type(ir, childtype); | ||||||
|  |             real = (*child)->type; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (wanted) | ||||||
|  |         { | ||||||
|  |             if (wanted != real) | ||||||
|  |             { | ||||||
|  |                 struct ir* copy = new_copy(wanted, real, *child); | ||||||
|  |                 copy->root = ir->root; | ||||||
|  |                 *child = copy; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void insert_ir_copies(void) | ||||||
| { | { | ||||||
| 	int i; | 	int i; | ||||||
| 
 | 
 | ||||||
|  | @ -237,29 +267,42 @@ static void insert_copies(void) | ||||||
| 		struct ir* ir = irs.item[i]; | 		struct ir* ir = irs.item[i]; | ||||||
| 		const struct ir_data* ird = &ir_data[ir->opcode]; | 		const struct ir_data* ird = &ir_data[ir->opcode]; | ||||||
| 
 | 
 | ||||||
| 		if (ir->left) |         insert_copy(ir, &ir->left, ird->returntype, ird->lefttype); | ||||||
| 		{ |         insert_copy(ir, &ir->right, ird->returntype, ird->righttype); | ||||||
| 			char wanted = effective_type(ir, ird->lefttype); |  | ||||||
| 			char real = ir->left->type; |  | ||||||
| 
 |  | ||||||
| 			if (wanted && (wanted != real)) |  | ||||||
| 			{ |  | ||||||
| 				struct ir* copy = new_copy(wanted, real, ir->left); |  | ||||||
| 				copy->root = ir->root; |  | ||||||
| 				ir->left = copy; |  | ||||||
| 			} |  | ||||||
| 	} | 	} | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| 		if (ir->right) | static void insert_phi_copies(void) | ||||||
| 		{ | { | ||||||
| 			char wanted = effective_type(ir, ird->righttype); |     int i, j; | ||||||
| 			char real = ir->right->type; |  | ||||||
| 
 | 
 | ||||||
| 			if (wanted && (wanted != real)) |     /* If the child of a phi isn't the same type as the phi itself, we need to
 | ||||||
|  |      * insert the copy at the end of the block that exported the value. */ | ||||||
|  | 
 | ||||||
|  |     for (i=0; i<irs.count; i++) | ||||||
|     { |     { | ||||||
| 				struct ir* copy = new_copy(wanted, real, ir->right); | 		struct ir* ir = irs.item[i]; | ||||||
| 				copy->root = ir->root; | 
 | ||||||
| 				ir->right = copy; |         for (j=0; j<ir->u.phivalue.count; j++) | ||||||
|  |         { | ||||||
|  |             struct ir* childir = ir->u.phivalue.item[j].right; | ||||||
|  |             int wanted = ir->type; | ||||||
|  |             int real = childir->type; | ||||||
|  |             if (wanted != real) | ||||||
|  |             { | ||||||
|  |                 struct basicblock* childbb = ir->u.phivalue.item[j].left; | ||||||
|  |                 struct ir* copy = new_copy(wanted, real, childir); | ||||||
|  |                 copy->root = copy; | ||||||
|  | 
 | ||||||
|  |                 /* The copy gets inserted as the second last item of the child
 | ||||||
|  |                  * basic block. That way it'll happen before the final jump | ||||||
|  |                  * that exits the block. */ | ||||||
|  | 
 | ||||||
|  |                 array_insert(&childbb->irs, copy, childbb->irs.count-1); | ||||||
|  | 
 | ||||||
|  |                 /* And replace the value in the phi with our copy. */ | ||||||
|  | 
 | ||||||
|  |                 ir->u.phivalue.item[j].right = copy; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | @ -270,7 +313,8 @@ void pass_infer_types(void) | ||||||
| 	collect_irs(); | 	collect_irs(); | ||||||
| 	propagate_types(); | 	propagate_types(); | ||||||
| 	assign_fallback_types(); | 	assign_fallback_types(); | ||||||
| 	insert_copies(); | 	insert_ir_copies(); | ||||||
|  |     insert_phi_copies(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* vim: set sw=4 ts=4 expandtab : */ | /* vim: set sw=4 ts=4 expandtab : */ | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue