gcse.c (pre_insert_insn): When a call ends a bb, insert the new insns before the...
authorRichard Henderson <rth@cygnus.com>
Wed, 7 Oct 1998 10:08:16 +0000 (03:08 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Wed, 7 Oct 1998 10:08:16 +0000 (03:08 -0700)
        * gcse.c (pre_insert_insn): When a call ends a bb, insert
        the new insns before the argument regs are loaded.

From-SVN: r22891

gcc/ChangeLog
gcc/gcse.c

index 674da88166f0ef8efedb59a3dae7da65242272cf..e6ff59387965f5925e5e79c25a9f67c40b4604dd 100644 (file)
@@ -1,3 +1,8 @@
+Wed Oct  7 10:07:29 1998  Richard Henderson  <rth@cygnus.com>
+
+       * gcse.c (pre_insert_insn): When a call ends a bb, insert
+       the new insns before the argument regs are loaded.
+
 Wed Oct  7 12:55:26 1998  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
 
        * Makefile.in (c-gperf.h): Add -L KR-C -F ', 0, 0' flags to gperf.
index a992d111ea18d19ea9e3bbb4fefd58422673db06..463959d520ac58661813c04e400c8212b1661353 100644 (file)
@@ -4373,22 +4373,72 @@ pre_insert_insn (expr, bb)
       add_label_notes (SET_SRC (pat), new_insn);
       if (BLOCK_HEAD (bb) == insn)
        BLOCK_HEAD (bb) = new_insn;
-      /* Keep block number table up to date.  */
-      set_block_num (new_insn, bb);
-      /* Keep register set table up to date.  */
-      record_one_set (regno, new_insn);
+    }
+  /* Likewise if the last insn is a call, as will happen in the presence
+     of exception handling.  */
+  else if (GET_CODE (insn) == CALL_INSN)
+    {
+      HARD_REG_SET parm_regs;
+      int nparm_regs;
+      rtx p;
+
+      /* Keeping in mind SMALL_REGISTER_CLASSES and parameters in registers,
+        we search backward and place the instructions before the first
+        parameter is loaded.  Do this for everyone for consistency and a
+        presumtion that we'll get better code elsewhere as well.  */
+
+      /* It should always be the case that we can put these instructions
+        anywhere in the basic block.  Check this.  */
+      if (!TEST_BIT (pre_antloc[bb], expr->bitmap_index)
+         && !TEST_BIT (pre_transp[bb], expr->bitmap_index))
+       abort ();
+
+      /* Since different machines initialize their parameter registers
+        in different orders, assume nothing.  Collect the set of all
+        parameter registers.  */
+      CLEAR_HARD_REG_SET (parm_regs);
+      nparm_regs = 0;
+      for (p = CALL_INSN_FUNCTION_USAGE (insn); p ; p = XEXP (p, 1))
+       if (GET_CODE (XEXP (p, 0)) == USE
+           && GET_CODE (XEXP (XEXP (p, 0), 0)) == REG)
+         {
+           int regno = REGNO (XEXP (XEXP (p, 0), 0));
+           if (regno >= FIRST_PSEUDO_REGISTER)
+             abort();
+           SET_HARD_REG_BIT (parm_regs, regno);
+           nparm_regs++;
+         }
+
+      /* Search backward for the first set of a register in this set.  */
+      while (nparm_regs && BLOCK_HEAD (bb) != insn)
+       {
+         insn = PREV_INSN (insn);
+         p = single_set (insn);
+         if (p && GET_CODE (SET_DEST (p)) == REG
+             && REGNO (SET_DEST (p)) < FIRST_PSEUDO_REGISTER
+             && TEST_HARD_REG_BIT (parm_regs, REGNO (SET_DEST (p))))
+           {
+             CLEAR_HARD_REG_BIT (parm_regs, REGNO (SET_DEST (p)));
+             nparm_regs--;
+           }
+       }
+      
+      new_insn = emit_insn_before (pat, insn);
+      if (BLOCK_HEAD (bb) == insn)
+       BLOCK_HEAD (bb) = new_insn;
     }
   else
     {
       new_insn = emit_insn_after (pat, insn);
       add_label_notes (SET_SRC (pat), new_insn);
       BLOCK_END (bb) = new_insn;
-      /* Keep block number table up to date.  */
-      set_block_num (new_insn, bb);
-      /* Keep register set table up to date.  */
-      record_one_set (regno, new_insn);
     }
 
+  /* Keep block number table up to date.  */
+  set_block_num (new_insn, bb);
+  /* Keep register set table up to date.  */
+  record_one_set (regno, new_insn);
+
   gcse_create_count++;
 
   if (gcse_file)