re PR target/43995 (internal compiler error: Segmentation fault on Mips64 crossbuild...
authorRichard Sandiford <rdsandiford@googlemail.com>
Sun, 29 May 2011 17:41:50 +0000 (17:41 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Sun, 29 May 2011 17:41:50 +0000 (17:41 +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: r174402

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

index 63ba525d08a43c92a7e96b2833f9730263d1017b..2d11011054546ef9f164e54be20c166a3c525654 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-29  Richard Sandiford  <rdsandiford@googlemail.com>
 
        * emit-rtl.c (try_split): Use a loop to search for
index 46b25f7b985296b57637ce865b3041602569c202..39042386930c00037e31defe2ee9b19a23ef8eae 100644 (file)
@@ -1060,7 +1060,7 @@ static const struct mips_rtx_cost_data
   }
 };
 \f
-static rtx mips_find_pic_call_symbol (rtx, rtx);
+static rtx mips_find_pic_call_symbol (rtx, rtx, bool);
 static int mips_register_move_cost (enum machine_mode, reg_class_t,
                                    reg_class_t);
 static unsigned int mips_function_arg_boundary (enum machine_mode, const_tree);
@@ -14026,12 +14026,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;
 
@@ -14058,21 +14062,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;
@@ -14084,7 +14106,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;
 
@@ -14093,7 +14115,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;
     }
@@ -14164,7 +14186,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);