[12/32] Remove global call sets: cselib.c

Message ID mpt36h2y7it.fsf@arm.com
State New
Headers show
Series
  • Support multiple ABIs in the same translation unit
Related show

Commit Message

Richard Sandiford Sept. 11, 2019, 7:09 p.m.
cselib_invalidate_regno is a no-op if REG_VALUES (i) is null,
so we can check that first.  Then, if we know what mode the register
currently has, we can check whether it's clobbered in that mode.

Using GET_MODE (values->elt->val_rtx) to get the mode of the last
set is taken from cselib_reg_set_mode.


2019-09-11  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
	* cselib.c (cselib_process_insn): If we know what mode a
	register was set in, check whether it is clobbered in that
	mode by a call.  Only fall back to reg_raw_mode if that fails.

Comments

Jeff Law Sept. 29, 2019, 9:05 p.m. | #1
On 9/11/19 1:09 PM, Richard Sandiford wrote:
> cselib_invalidate_regno is a no-op if REG_VALUES (i) is null,

> so we can check that first.  Then, if we know what mode the register

> currently has, we can check whether it's clobbered in that mode.

> 

> Using GET_MODE (values->elt->val_rtx) to get the mode of the last

> set is taken from cselib_reg_set_mode.

> 

> 

> 2019-09-11  Richard Sandiford  <richard.sandiford@arm.com>

> 

> gcc/

> 	* cselib.c (cselib_process_insn): If we know what mode a

> 	register was set in, check whether it is clobbered in that

> 	mode by a call.  Only fall back to reg_raw_mode if that fails.

OK
jeff
Martin Liška Oct. 29, 2019, 9:19 a.m. | #2
On 9/29/19 11:05 PM, Jeff Law wrote:
> On 9/11/19 1:09 PM, Richard Sandiford wrote:

>> cselib_invalidate_regno is a no-op if REG_VALUES (i) is null,

>> so we can check that first.  Then, if we know what mode the register

>> currently has, we can check whether it's clobbered in that mode.

>>

>> Using GET_MODE (values->elt->val_rtx) to get the mode of the last

>> set is taken from cselib_reg_set_mode.

>>

>>

>> 2019-09-11  Richard Sandiford  <richard.sandiford@arm.com>

>>

>> gcc/

>> 	* cselib.c (cselib_process_insn): If we know what mode a

>> 	register was set in, check whether it is clobbered in that

>> 	mode by a call.  Only fall back to reg_raw_mode if that fails.

> OK

> jeff

> 


Caused https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92264

Martin

Patch

Index: gcc/cselib.c
===================================================================
--- gcc/cselib.c	2019-09-11 19:47:32.894202944 +0100
+++ gcc/cselib.c	2019-09-11 19:48:04.229982128 +0100
@@ -2768,11 +2768,23 @@  cselib_process_insn (rtx_insn *insn)
     {
       function_abi abi = call_insn_abi (insn);
       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-	if (call_used_or_fixed_reg_p (i)
-	    || (REG_VALUES (i) && REG_VALUES (i)->elt
-		&& (targetm.hard_regno_call_part_clobbered
-		    (abi.id (), i, GET_MODE (REG_VALUES (i)->elt->val_rtx)))))
-	  cselib_invalidate_regno (i, reg_raw_mode[i]);
+	if (elt_list *values = REG_VALUES (i))
+	  {
+	    /* If we know what mode the value was set in, check whether
+	       it is still available after the call in that mode.  If we
+	       don't know the mode, we have to check for the worst-case
+	       scenario instead.  */
+	    if (values->elt)
+	      {
+		if (abi.clobbers_reg_p (GET_MODE (values->elt->val_rtx), i))
+		  cselib_invalidate_regno (i, GET_MODE (values->elt->val_rtx));
+	      }
+	    else
+	      {
+		if (abi.clobbers_at_least_part_of_reg_p (i))
+		  cselib_invalidate_regno (i, reg_raw_mode[i]);
+	      }
+	  }
 
       /* Since it is not clear how cselib is going to be used, be
 	 conservative here and treat looping pure or const functions