caller-save.c (insert_one_insn): If inserting before a call_insn then the registers...
authorPranav Bhandarkar <pranav.bhandarkar@celunite.com>
Mon, 10 Dec 2007 01:01:03 +0000 (01:01 +0000)
committerHans-Peter Nilsson <hp@gcc.gnu.org>
Mon, 10 Dec 2007 01:01:03 +0000 (01:01 +0000)
* caller-save.c (insert_one_insn): If inserting before a call_insn
then the registers containing the arguments of the call are
live_throughout in the new insn.

Co-Authored-By: Hans-Peter Nilsson <hp@axis.com>
From-SVN: r130733

gcc/ChangeLog
gcc/caller-save.c

index b3bb96efc087315a9600c7c39f598c97c2bd57e6..11088fdc8f01167e9caaa08f5b14babe6bc7ec1b 100644 (file)
@@ -1,3 +1,10 @@
+2007-12-10  Pranav Bhandarkar  <pranav.bhandarkar@celunite.com>
+           Hans-Peter Nilsson  <hp@axis.com>
+
+       * caller-save.c (insert_one_insn): If inserting before a call_insn
+       then the registers containing the arguments of the call are
+       live_throughout in the new insn.
+
 2007-12-09  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
 
        PR middle-end/32889
index 26ac50eadd11806c4619691bd65f66346c5003d4..7976fd5fd7509b7901f0e11836b2074887392827 100644 (file)
@@ -850,6 +850,38 @@ insert_one_insn (struct insn_chain *chain, int before_p, int code, rtx pat)
                SET_REGNO_REG_SET (&new->live_throughout, regno + i);
            }
        }
+
+      /* If CHAIN->INSN is a call, then the registers which contain
+        the arguments to the function are live in the new insn.  */
+      if (CALL_P (chain->insn))
+       {
+         for (link = CALL_INSN_FUNCTION_USAGE (chain->insn);
+              link != NULL_RTX;
+              link = XEXP (link, 1))
+           {
+             rtx arg = XEXP (link, 0);
+
+             if (GET_CODE (arg) == USE)
+               {
+                 rtx reg = XEXP (arg, 0);
+
+                 if (REG_P (reg))
+                   {
+                     int i, regno = REGNO (reg);
+
+                     /* Registers in CALL_INSN_FUNCTION_USAGE are always
+                        hard registers.  */
+                     gcc_assert (regno < FIRST_PSEUDO_REGISTER);
+
+                     for (i = hard_regno_nregs[regno][GET_MODE (reg)] - 1;
+                          i >= 0; i--)
+                       SET_REGNO_REG_SET (&new->live_throughout, regno + i);
+                   }
+               }
+           }
+         
+       }
+
       CLEAR_REG_SET (&new->dead_or_set);
       if (chain->insn == BB_HEAD (BASIC_BLOCK (chain->block)))
        BB_HEAD (BASIC_BLOCK (chain->block)) = new->insn;