aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2011-05-29 17:47:51 +0000
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2011-05-29 17:47:51 +0000
commit158892fce220b03d3fe3d8d7656e1b0786609283 (patch)
tree3c3acdb4ea083e15f745d94d865457ffe24ee4f9
parentd5ea0b26fccb8359f0edce472053beca74f50f93 (diff)
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch@174404 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/config/mips/mips.c54
2 files changed, 48 insertions, 16 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 369a4fc3a80..32933d9244f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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 Guenther <rguenther@suse.de>
PR tree-optimization/49217
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 9de479bf5c8..027fc2d7a01 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -1186,7 +1186,7 @@ static const struct mips_rtx_cost_data
}
};
-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);
@@ -14160,12 +14160,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;
@@ -14192,21 +14196,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;
@@ -14218,7 +14240,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;
@@ -14227,7 +14249,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;
}
@@ -14298,7 +14320,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);