Remove global call sets: cselib.c
authorRichard Sandiford <richard.sandiford@arm.com>
Mon, 30 Sep 2019 16:20:26 +0000 (16:20 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Mon, 30 Sep 2019 16:20:26 +0000 (16:20 +0000)
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-30  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.

From-SVN: r276318

gcc/ChangeLog
gcc/cselib.c

index 181fd8056e051eec1fb9b02136cd9e5aa2ab1112..5440a339ca6b729b57b9f7669fead10ea3c0a0e4 100644 (file)
@@ -1,3 +1,9 @@
+2019-09-30  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * 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.
+
 2019-09-30  Richard Sandiford  <richard.sandiford@arm.com>
 
        * cse.c: Include regs.h and function-abi.h.
index 5de14a07317fd4f8c17d641a7f62057ad37d8197..36f649de79ccd86149b68ca99f1479d223c027aa 100644 (file)
@@ -2768,12 +2768,24 @@ cselib_process_insn (rtx_insn *insn)
     {
       function_abi callee_abi = insn_callee_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
-                   (callee_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)
+             {
+               machine_mode mode = GET_MODE (values->elt->val_rtx);
+               if (callee_abi.clobbers_reg_p (mode, i))
+                 cselib_invalidate_regno (i, mode);
+             }
+           else
+             {
+               if (callee_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