mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			lra-constraints.c (valid_address_p): Move earlier in file.
gcc/ * lra-constraints.c (valid_address_p): Move earlier in file. (address_eliminator): New structure. (satisfies_memory_constraint_p): New function. (satisfies_address_constraint_p): Likewise. (process_alt_operands, process_address, curr_insn_transform): Use them. From-SVN: r211242
This commit is contained in:
		
							parent
							
								
									0c3317563e
								
							
						
					
					
						commit
						a953491ef2
					
				|  | @ -1,3 +1,11 @@ | ||||||
|  | 2014-06-04  Richard Sandiford  <rdsandiford@googlemail.com> | ||||||
|  | 
 | ||||||
|  | 	* lra-constraints.c (valid_address_p): Move earlier in file. | ||||||
|  | 	(address_eliminator): New structure. | ||||||
|  | 	(satisfies_memory_constraint_p): New function. | ||||||
|  | 	(satisfies_address_constraint_p): Likewise. | ||||||
|  | 	(process_alt_operands, process_address, curr_insn_transform): Use them. | ||||||
|  | 
 | ||||||
| 2014-06-04  Richard Sandiford  <rdsandiford@googlemail.com> | 2014-06-04  Richard Sandiford  <rdsandiford@googlemail.com> | ||||||
| 
 | 
 | ||||||
| 	* lra-int.h (lra_static_insn_data): Make operand_alternative a | 	* lra-int.h (lra_static_insn_data): Make operand_alternative a | ||||||
|  |  | ||||||
|  | @ -317,6 +317,118 @@ in_mem_p (int regno) | ||||||
|   return get_reg_class (regno) == NO_REGS; |   return get_reg_class (regno) == NO_REGS; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /* Return 1 if ADDR is a valid memory address for mode MODE in address
 | ||||||
|  |    space AS, and check that each pseudo has the proper kind of hard | ||||||
|  |    reg.	 */ | ||||||
|  | static int | ||||||
|  | valid_address_p (enum machine_mode mode ATTRIBUTE_UNUSED, | ||||||
|  | 		 rtx addr, addr_space_t as) | ||||||
|  | { | ||||||
|  | #ifdef GO_IF_LEGITIMATE_ADDRESS | ||||||
|  |   lra_assert (ADDR_SPACE_GENERIC_P (as)); | ||||||
|  |   GO_IF_LEGITIMATE_ADDRESS (mode, addr, win); | ||||||
|  |   return 0; | ||||||
|  | 
 | ||||||
|  |  win: | ||||||
|  |   return 1; | ||||||
|  | #else | ||||||
|  |   return targetm.addr_space.legitimate_address_p (mode, addr, 0, as); | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | namespace { | ||||||
|  |   /* Temporarily eliminates registers in an address (for the lifetime of
 | ||||||
|  |      the object).  */ | ||||||
|  |   class address_eliminator { | ||||||
|  |   public: | ||||||
|  |     address_eliminator (struct address_info *ad); | ||||||
|  |     ~address_eliminator (); | ||||||
|  | 
 | ||||||
|  |   private: | ||||||
|  |     struct address_info *m_ad; | ||||||
|  |     rtx *m_base_loc; | ||||||
|  |     rtx m_base_reg; | ||||||
|  |     rtx *m_index_loc; | ||||||
|  |     rtx m_index_reg; | ||||||
|  |   }; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | address_eliminator::address_eliminator (struct address_info *ad) | ||||||
|  |   : m_ad (ad), | ||||||
|  |     m_base_loc (strip_subreg (ad->base_term)), | ||||||
|  |     m_base_reg (NULL_RTX), | ||||||
|  |     m_index_loc (strip_subreg (ad->index_term)), | ||||||
|  |     m_index_reg (NULL_RTX) | ||||||
|  | { | ||||||
|  |   if (m_base_loc != NULL) | ||||||
|  |     { | ||||||
|  |       m_base_reg = *m_base_loc; | ||||||
|  |       lra_eliminate_reg_if_possible (m_base_loc); | ||||||
|  |       if (m_ad->base_term2 != NULL) | ||||||
|  | 	*m_ad->base_term2 = *m_ad->base_term; | ||||||
|  |     } | ||||||
|  |   if (m_index_loc != NULL) | ||||||
|  |     { | ||||||
|  |       m_index_reg = *m_index_loc; | ||||||
|  |       lra_eliminate_reg_if_possible (m_index_loc); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | address_eliminator::~address_eliminator () | ||||||
|  | { | ||||||
|  |   if (m_base_loc && *m_base_loc != m_base_reg) | ||||||
|  |     { | ||||||
|  |       *m_base_loc = m_base_reg; | ||||||
|  |       if (m_ad->base_term2 != NULL) | ||||||
|  | 	*m_ad->base_term2 = *m_ad->base_term; | ||||||
|  |     } | ||||||
|  |   if (m_index_loc && *m_index_loc != m_index_reg) | ||||||
|  |     *m_index_loc = m_index_reg; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* Return true if the eliminated form of AD is a legitimate target address.  */ | ||||||
|  | static bool | ||||||
|  | valid_address_p (struct address_info *ad) | ||||||
|  | { | ||||||
|  |   address_eliminator eliminator (ad); | ||||||
|  |   return valid_address_p (ad->mode, *ad->outer, ad->as); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #ifdef EXTRA_CONSTRAINT_STR | ||||||
|  | /* Return true if the eliminated form of memory reference OP satisfies
 | ||||||
|  |    extra memory constraint CONSTRAINT.  */ | ||||||
|  | static bool | ||||||
|  | satisfies_memory_constraint_p (rtx op, const char *constraint) | ||||||
|  | { | ||||||
|  |   struct address_info ad; | ||||||
|  | 
 | ||||||
|  |   decompose_mem_address (&ad, op); | ||||||
|  |   address_eliminator eliminator (&ad); | ||||||
|  |   return EXTRA_CONSTRAINT_STR (op, *constraint, constraint); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* Return true if the eliminated form of address AD satisfies extra
 | ||||||
|  |    address constraint CONSTRAINT.  */ | ||||||
|  | static bool | ||||||
|  | satisfies_address_constraint_p (struct address_info *ad, | ||||||
|  | 				const char *constraint) | ||||||
|  | { | ||||||
|  |   address_eliminator eliminator (ad); | ||||||
|  |   return EXTRA_CONSTRAINT_STR (*ad->outer, *constraint, constraint); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* Return true if the eliminated form of address OP satisfies extra
 | ||||||
|  |    address constraint CONSTRAINT.  */ | ||||||
|  | static bool | ||||||
|  | satisfies_address_constraint_p (rtx op, const char *constraint) | ||||||
|  | { | ||||||
|  |   struct address_info ad; | ||||||
|  | 
 | ||||||
|  |   decompose_lea_address (&ad, &op); | ||||||
|  |   return satisfies_address_constraint_p (&ad, constraint); | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| /* Initiate equivalences for LRA.  As we keep original equivalences
 | /* Initiate equivalences for LRA.  As we keep original equivalences
 | ||||||
|    before any elimination, we need to make copies otherwise any change |    before any elimination, we need to make copies otherwise any change | ||||||
|    in insns might change the equivalences.  */ |    in insns might change the equivalences.  */ | ||||||
|  | @ -1938,7 +2050,8 @@ process_alt_operands (int only_alternative) | ||||||
| #ifdef EXTRA_CONSTRAINT_STR | #ifdef EXTRA_CONSTRAINT_STR | ||||||
| 		      if (EXTRA_MEMORY_CONSTRAINT (c, p)) | 		      if (EXTRA_MEMORY_CONSTRAINT (c, p)) | ||||||
| 			{ | 			{ | ||||||
| 			  if (EXTRA_CONSTRAINT_STR (op, c, p)) | 			  if (MEM_P (op) | ||||||
|  | 			      && satisfies_memory_constraint_p (op, p)) | ||||||
| 			    win = true; | 			    win = true; | ||||||
| 			  else if (spilled_pseudo_p (op)) | 			  else if (spilled_pseudo_p (op)) | ||||||
| 			    win = true; | 			    win = true; | ||||||
|  | @ -1957,7 +2070,7 @@ process_alt_operands (int only_alternative) | ||||||
| 			} | 			} | ||||||
| 		      if (EXTRA_ADDRESS_CONSTRAINT (c, p)) | 		      if (EXTRA_ADDRESS_CONSTRAINT (c, p)) | ||||||
| 			{ | 			{ | ||||||
| 			  if (EXTRA_CONSTRAINT_STR (op, c, p)) | 			  if (satisfies_address_constraint_p (op, p)) | ||||||
| 			    win = true; | 			    win = true; | ||||||
| 
 | 
 | ||||||
| 			  /* If we didn't already win, we can reload
 | 			  /* If we didn't already win, we can reload
 | ||||||
|  | @ -2573,60 +2686,6 @@ process_alt_operands (int only_alternative) | ||||||
|   return ok_p; |   return ok_p; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* Return 1 if ADDR is a valid memory address for mode MODE in address
 |  | ||||||
|    space AS, and check that each pseudo has the proper kind of hard |  | ||||||
|    reg.	 */ |  | ||||||
| static int |  | ||||||
| valid_address_p (enum machine_mode mode ATTRIBUTE_UNUSED, |  | ||||||
| 		 rtx addr, addr_space_t as) |  | ||||||
| { |  | ||||||
| #ifdef GO_IF_LEGITIMATE_ADDRESS |  | ||||||
|   lra_assert (ADDR_SPACE_GENERIC_P (as)); |  | ||||||
|   GO_IF_LEGITIMATE_ADDRESS (mode, addr, win); |  | ||||||
|   return 0; |  | ||||||
| 
 |  | ||||||
|  win: |  | ||||||
|   return 1; |  | ||||||
| #else |  | ||||||
|   return targetm.addr_space.legitimate_address_p (mode, addr, 0, as); |  | ||||||
| #endif |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /* Return whether address AD is valid.  */ |  | ||||||
| 
 |  | ||||||
| static bool |  | ||||||
| valid_address_p (struct address_info *ad) |  | ||||||
| { |  | ||||||
|   /* Some ports do not check displacements for eliminable registers,
 |  | ||||||
|      so we replace them temporarily with the elimination target.  */ |  | ||||||
|   rtx saved_base_reg = NULL_RTX; |  | ||||||
|   rtx saved_index_reg = NULL_RTX; |  | ||||||
|   rtx *base_term = strip_subreg (ad->base_term); |  | ||||||
|   rtx *index_term = strip_subreg (ad->index_term); |  | ||||||
|   if (base_term != NULL) |  | ||||||
|     { |  | ||||||
|       saved_base_reg = *base_term; |  | ||||||
|       lra_eliminate_reg_if_possible (base_term); |  | ||||||
|       if (ad->base_term2 != NULL) |  | ||||||
| 	*ad->base_term2 = *ad->base_term; |  | ||||||
|     } |  | ||||||
|   if (index_term != NULL) |  | ||||||
|     { |  | ||||||
|       saved_index_reg = *index_term; |  | ||||||
|       lra_eliminate_reg_if_possible (index_term); |  | ||||||
|     } |  | ||||||
|   bool ok_p = valid_address_p (ad->mode, *ad->outer, ad->as); |  | ||||||
|   if (saved_base_reg != NULL_RTX) |  | ||||||
|     { |  | ||||||
|       *base_term = saved_base_reg; |  | ||||||
|       if (ad->base_term2 != NULL) |  | ||||||
| 	*ad->base_term2 = *ad->base_term; |  | ||||||
|     } |  | ||||||
|   if (saved_index_reg != NULL_RTX) |  | ||||||
|     *index_term = saved_index_reg; |  | ||||||
|   return ok_p; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /* Make reload base reg + disp from address AD.  Return the new pseudo.  */ | /* Make reload base reg + disp from address AD.  Return the new pseudo.  */ | ||||||
| static rtx | static rtx | ||||||
| base_plus_disp_to_reg (struct address_info *ad) | base_plus_disp_to_reg (struct address_info *ad) | ||||||
|  | @ -2834,7 +2893,7 @@ process_address_1 (int nop, rtx *before, rtx *after) | ||||||
|      EXTRA_CONSTRAINT_STR for the validation.  */ |      EXTRA_CONSTRAINT_STR for the validation.  */ | ||||||
|   if (constraint[0] != 'p' |   if (constraint[0] != 'p' | ||||||
|       && EXTRA_ADDRESS_CONSTRAINT (constraint[0], constraint) |       && EXTRA_ADDRESS_CONSTRAINT (constraint[0], constraint) | ||||||
|       && EXTRA_CONSTRAINT_STR (op, constraint[0], constraint)) |       && satisfies_address_constraint_p (&ad, constraint)) | ||||||
|     return change_p; |     return change_p; | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | @ -3553,7 +3612,7 @@ curr_insn_transform (void) | ||||||
| 		  break; | 		  break; | ||||||
| #ifdef EXTRA_CONSTRAINT_STR | #ifdef EXTRA_CONSTRAINT_STR | ||||||
| 		if (EXTRA_MEMORY_CONSTRAINT (c, constraint) | 		if (EXTRA_MEMORY_CONSTRAINT (c, constraint) | ||||||
| 		    && EXTRA_CONSTRAINT_STR (tem, c, constraint)) | 		    && satisfies_memory_constraint_p (tem, constraint)) | ||||||
| 		  break; | 		  break; | ||||||
| #endif | #endif | ||||||
| 	      } | 	      } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Richard Sandiford
						Richard Sandiford