re PR rtl-optimization/72778 (internal compiler error: in create_pre_exit, at mode...
authorVladimir Makarov <vmakarov@redhat.com>
Wed, 3 Aug 2016 18:54:49 +0000 (18:54 +0000)
committerVladimir Makarov <vmakarov@gcc.gnu.org>
Wed, 3 Aug 2016 18:54:49 +0000 (18:54 +0000)
2016-08-03  Vladimir Makarov  <vmakarov@redhat.com>

PR middle-end/72778
* lra-spills.c (regno_in_use_p): Check bb and regno modification.
Don't stop on regular insns.

From-SVN: r239091

gcc/ChangeLog
gcc/lra-spills.c

index 2223290bd53469d4a56cf024be0aab2adc1fdf76..8dcd430a6c7a9474700588d15ab66384b21ea063 100644 (file)
@@ -1,3 +1,9 @@
+2016-08-03  Vladimir Makarov  <vmakarov@redhat.com>
+
+       PR middle-end/72778
+       * lra-spills.c (regno_in_use_p): Check bb and regno modification.
+       Don't stop on regular insns.
+
 2016-08-03  Nathan Sidwell  <nathan@codesourcery.com>
 
        * config/nvptx/nvptx.c (nvptx_declare_function_name): Round frame
index a5073b69f46a79f639b0624eaea1300f511c18d1..d7529ea371fd4129fcba0b3475b72e60b15a0845 100644 (file)
@@ -686,16 +686,40 @@ return_regno_p (unsigned int regno)
   return false;
 }
 
-/* Return true if REGNO is one of subsequent USE after INSN.  */
+/* Return true if REGNO is in one of subsequent USE after INSN in the
+   same BB.  */
 static bool
 regno_in_use_p (rtx_insn *insn, unsigned int regno)
 {
+  static lra_insn_recog_data_t id;
+  static struct lra_static_insn_data *static_id;
+  struct lra_insn_reg *reg;
+  int i, arg_regno;
+  basic_block bb = BLOCK_FOR_INSN (insn);
+
   while ((insn = next_nondebug_insn (insn)) != NULL_RTX
-        && INSN_P (insn) && GET_CODE (PATTERN (insn)) == USE)
+        && bb == BLOCK_FOR_INSN (insn))
     {
-      if (REG_P (XEXP (PATTERN (insn), 0))
+      if (! INSN_P (insn))
+       continue;
+      if (GET_CODE (PATTERN (insn)) == USE
+         && REG_P (XEXP (PATTERN (insn), 0))
          && regno == REGNO (XEXP (PATTERN (insn), 0)))
-       return TRUE;
+       return true;
+      /* Check that the regno is not modified.  */
+      id = lra_get_insn_recog_data (insn);
+      for (reg = id->regs; reg != NULL; reg = reg->next)
+       if (reg->type != OP_IN && reg->regno == (int) regno)
+         return false;
+      static_id = id->insn_static_data;
+      for (reg = static_id->hard_regs; reg != NULL; reg = reg->next)
+       if (reg->type != OP_IN && reg->regno == (int) regno)
+         return false;
+      if (id->arg_hard_regs != NULL)
+       for (i = 0; (arg_regno = id->arg_hard_regs[i]) >= 0; i++)
+         if ((int) regno == (arg_regno >= FIRST_PSEUDO_REGISTER
+                             ? arg_regno : arg_regno - FIRST_PSEUDO_REGISTER))
+           return false;
     }
   return false;
 }