]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR target/43995 (internal compiler error: Segmentation fault on Mips64 crossbuild...
authorRichard Sandiford <rdsandiford@googlemail.com>
Sun, 29 May 2011 17:50:53 +0000 (17:50 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Sun, 29 May 2011 17:50:53 +0000 (17:50 +0000)
gcc/
PR target/43995
* config/mips/mips.c (mips_pic_call_symbol_from_set): Add a
recurse_p argument.  Only follow register copies if it is set,
and prevent mips_find_pic_call_symbol from recursing.
(mips_find_pic_call_symbol): Add a recurse_p argument.
Pass it to mips_pic_call_symbol_from_set.
(mips_annotate_pic_calls): Update accordingly.

From-SVN: r174407

gcc/ChangeLog
gcc/config/mips/mips.c

index 5f20ec89f0a9f6670cf85ff5da7c623bf6ed41a6..996e0d916dac3325d6776cd4f52d5d0d4344d9dc 100644 (file)
@@ -1,3 +1,13 @@
+2011-05-29  Richard Sandiford  <rdsandiford@googlemail.com>
+
+       PR target/43995
+       * config/mips/mips.c (mips_pic_call_symbol_from_set): Add a
+       recurse_p argument.  Only follow register copies if it is set,
+       and prevent mips_find_pic_call_symbol from recursing.
+       (mips_find_pic_call_symbol): Add a recurse_p argument.
+       Pass it to mips_pic_call_symbol_from_set.
+       (mips_annotate_pic_calls): Update accordingly.
+
 2011-05-26  Eric Botcazou  <ebotcazou@adacore.com>
 
        * config/sparc/sparc-protos.h (sparc_optimization_options): Declare.
index 0207ffeae3fb70d93d92982eb4420ba6b13e8cea..d3c0709074e96b7fe4a0763b268aee8d743a2996 100644 (file)
@@ -1162,7 +1162,7 @@ static const struct mips_rtx_cost_data mips_rtx_cost_data[PROCESSOR_MAX] = {
   }
 };
 \f
-static rtx mips_find_pic_call_symbol (rtx, rtx);
+static rtx mips_find_pic_call_symbol (rtx, rtx, bool);
 \f
 /* This hash table keeps track of implicit "mips16" and "nomips16" attributes
    for -mflip_mips16.  It maps decl names onto a boolean mode setting.  */
@@ -14040,12 +14040,16 @@ mips_call_expr_from_insn (rtx insn, rtx *second_call)
 }
 
 /* REG is set in DEF.  See if the definition is one of the ways we load a
-   register with a symbol address for a mips_use_pic_fn_addr_reg_p call.  If
-   it is return the symbol reference of the function, otherwise return
-   NULL_RTX.  */
+   register with a symbol address for a mips_use_pic_fn_addr_reg_p call.
+   If it is, return the symbol reference of the function, otherwise return
+   NULL_RTX.
+
+   If RECURSE_P is true, use mips_find_pic_call_symbol to interpret
+   the values of source registers, otherwise treat such registers as
+   having an unknown value.  */
 
 static rtx
-mips_pic_call_symbol_from_set (df_ref def, rtx reg)
+mips_pic_call_symbol_from_set (df_ref def, rtx reg, bool recurse_p)
 {
   rtx def_insn, set;
 
@@ -14072,21 +14076,39 @@ mips_pic_call_symbol_from_set (df_ref def, rtx reg)
          return symbol;
        }
 
-      /* Follow simple register copies.  */
-      if (REG_P (src))
-       return mips_find_pic_call_symbol (def_insn, src);
+      /* Follow at most one simple register copy.  Such copies are
+        interesting in cases like:
+
+            for (...)
+              {
+                locally_binding_fn (...);
+              }
+
+        and:
+
+            locally_binding_fn (...);
+            ...
+            locally_binding_fn (...);
+
+        where the load of locally_binding_fn can legitimately be
+        hoisted or shared.  However, we do not expect to see complex
+        chains of copies, so a full worklist solution to the problem
+        would probably be overkill.  */
+      if (recurse_p && REG_P (src))
+       return mips_find_pic_call_symbol (def_insn, src, false);
     }
 
   return NULL_RTX;
 }
 
-/* Find the definition of the use of REG in INSN.  See if the definition is
-   one of the ways we load a register with a symbol address for a
-   mips_use_pic_fn_addr_reg_p call.  If it is return the symbol reference of
-   the function, otherwise return NULL_RTX.  */
+/* Find the definition of the use of REG in INSN.  See if the definition
+   is one of the ways we load a register with a symbol address for a
+   mips_use_pic_fn_addr_reg_p call.  If it is return the symbol reference
+   of the function, otherwise return NULL_RTX.  RECURSE_P is as for
+   mips_pic_call_symbol_from_set.  */
 
 static rtx
-mips_find_pic_call_symbol (rtx insn, rtx reg)
+mips_find_pic_call_symbol (rtx insn, rtx reg, bool recurse_p)
 {
   df_ref use;
   struct df_link *defs;
@@ -14098,7 +14120,7 @@ mips_find_pic_call_symbol (rtx insn, rtx reg)
   defs = DF_REF_CHAIN (use);
   if (!defs)
     return NULL_RTX;
-  symbol = mips_pic_call_symbol_from_set (defs->ref, reg);
+  symbol = mips_pic_call_symbol_from_set (defs->ref, reg, recurse_p);
   if (!symbol)
     return NULL_RTX;
 
@@ -14107,7 +14129,7 @@ mips_find_pic_call_symbol (rtx insn, rtx reg)
     {
       rtx other;
 
-      other = mips_pic_call_symbol_from_set (defs->ref, reg);
+      other = mips_pic_call_symbol_from_set (defs->ref, reg, recurse_p);
       if (!rtx_equal_p (symbol, other))
        return NULL_RTX;
     }
@@ -14178,7 +14200,7 @@ mips_annotate_pic_calls (void)
       if (!REG_P (reg))
        continue;
 
-      symbol = mips_find_pic_call_symbol (insn, reg);
+      symbol = mips_find_pic_call_symbol (insn, reg, true);
       if (symbol)
        {
          mips_annotate_pic_call_expr (call, symbol);