summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2011-02-04 15:50:51 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2011-02-04 15:50:51 +0000
commit351b6ccf86d48ad98795df9defe0af7f35fdd66d (patch)
tree414dfa9293092030de0a06170c839b69d92e5b67 /gcc
parent8119d93591ec9a4d1cb160a13c51584e79478b7c (diff)
downloadgcc-351b6ccf86d48ad98795df9defe0af7f35fdd66d.tar.gz
PR inline-asm/23200
* tree-ssa-ter.c (is_replaceable_p): Add TER argument. Don't do bb, locus and block comparison and disallow loads if it is not set. (stmt_is_replaceable_p): New function. (process_replaceable, find_replaceable_in_bb): Adjust is_replaceable_p callers. * expr.c (expand_expr_real_1) <case SSA_NAME>: If get_gimple_for_ssa_name try for EXPAND_INITIALIZER harder to use SSA_NAME_DEF_STMT. * tree-flow.h (stmt_is_replaceable_p): New prototype. * gcc.dg/pr23200.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@169831 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/expr.c7
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/pr23200.c22
-rw-r--r--gcc/tree-flow.h5
-rw-r--r--gcc/tree-ssa-ter.c32
6 files changed, 77 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 995ca86db18..e94de889b2d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+2011-02-04 Jakub Jelinek <jakub@redhat.com>
+
+ PR inline-asm/23200
+ * tree-ssa-ter.c (is_replaceable_p): Add TER argument. Don't
+ do bb, locus and block comparison and disallow loads if it is
+ not set.
+ (stmt_is_replaceable_p): New function.
+ (process_replaceable, find_replaceable_in_bb): Adjust is_replaceable_p
+ callers.
+ * expr.c (expand_expr_real_1) <case SSA_NAME>: If
+ get_gimple_for_ssa_name try for EXPAND_INITIALIZER harder to use
+ SSA_NAME_DEF_STMT.
+ * tree-flow.h (stmt_is_replaceable_p): New prototype.
+
2011-02-04 Joseph Myers <joseph@codesourcery.com>
* config/rs6000/xilinx.opt: New.
diff --git a/gcc/expr.c b/gcc/expr.c
index df15c928bee..b09b1ac07c2 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -8387,6 +8387,13 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
NULL);
g = get_gimple_for_ssa_name (exp);
+ /* For EXPAND_INITIALIZER try harder to get something simpler. */
+ if (g == NULL
+ && modifier == EXPAND_INITIALIZER
+ && !SSA_NAME_IS_DEFAULT_DEF (exp)
+ && (optimize || DECL_IGNORED_P (SSA_NAME_VAR (exp)))
+ && stmt_is_replaceable_p (SSA_NAME_DEF_STMT (exp)))
+ g = SSA_NAME_DEF_STMT (exp);
if (g)
return expand_expr_real (gimple_assign_rhs_to_tree (g), target, tmode,
modifier, NULL);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c10cabb6723..c4a145c4c69 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2011-02-04 Jakub Jelinek <jakub@redhat.com>
+
+ PR inline-asm/23200
+ * gcc.dg/pr23200.c: New test.
+
2011-02-03 Jonathan Wakely <jwakely.gcc@gmail.com>
PR c++/47589
diff --git a/gcc/testsuite/gcc.dg/pr23200.c b/gcc/testsuite/gcc.dg/pr23200.c
new file mode 100644
index 00000000000..56bf59c861a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr23200.c
@@ -0,0 +1,22 @@
+/* PR inline-asm/23200 */
+/* { dg-do compile { target nonpic } } */
+/* { dg-options "-O0" } */
+
+static char var;
+
+void
+foo (void)
+{
+ asm volatile ("" :: "i" (&var + 1));
+}
+
+typedef int T[];
+typedef T *P;
+
+int var2;
+
+void
+bar (void)
+{
+ asm volatile ("" :: "i"(&(*(P)&var2)[1]));
+}
diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
index 17208590897..e5642a0fbe3 100644
--- a/gcc/tree-flow.h
+++ b/gcc/tree-flow.h
@@ -1,5 +1,5 @@
/* Data and Control Flow Analysis for Trees.
- Copyright (C) 2001, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+ Copyright (C) 2001, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
Free Software Foundation, Inc.
Contributed by Diego Novillo <dnovillo@redhat.com>
@@ -852,6 +852,9 @@ bool fixup_noreturn_call (gimple stmt);
/* In ipa-pure-const.c */
void warn_function_noreturn (tree);
+/* In tree-ssa-ter.c */
+bool stmt_is_replaceable_p (gimple);
+
#include "tree-flow-inline.h"
void swap_tree_operands (gimple, tree *, tree *);
diff --git a/gcc/tree-ssa-ter.c b/gcc/tree-ssa-ter.c
index 47954cfa348..af8aae04a74 100644
--- a/gcc/tree-ssa-ter.c
+++ b/gcc/tree-ssa-ter.c
@@ -1,5 +1,5 @@
/* Routines for performing Temporary Expression Replacement (TER) in SSA trees.
- Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
Free Software Foundation, Inc.
Contributed by Andrew MacLeod <amacleod@redhat.com>
@@ -357,10 +357,17 @@ add_dependence (temp_expr_table_p tab, int version, tree var)
}
-/* Return TRUE if expression STMT is suitable for replacement. */
+/* Return TRUE if expression STMT is suitable for replacement.
+ TER is true if is_replaceable_p is called from within TER, false
+ when used from within stmt_is_replaceable_p, i.e. EXPAND_INITIALIZER
+ expansion. The differences are that with !TER some tests are skipped
+ to make it more aggressive (doesn't require the same bb, or for -O0
+ same locus and same BLOCK), on the other side never considers memory
+ loads as replaceable, because those don't ever lead into constant
+ expressions. */
static inline bool
-is_replaceable_p (gimple stmt)
+is_replaceable_p (gimple stmt, bool ter)
{
use_operand_p use_p;
tree def;
@@ -386,7 +393,7 @@ is_replaceable_p (gimple stmt)
return false;
/* If the use isn't in this block, it wont be replaced either. */
- if (gimple_bb (use_stmt) != gimple_bb (stmt))
+ if (ter && gimple_bb (use_stmt) != gimple_bb (stmt))
return false;
locus1 = gimple_location (stmt);
@@ -404,6 +411,7 @@ is_replaceable_p (gimple stmt)
}
if (!optimize
+ && ter
&& ((locus1 && locus1 != locus2) || (block1 && block1 != block2)))
return false;
@@ -416,7 +424,7 @@ is_replaceable_p (gimple stmt)
return false;
/* Without alias info we can't move around loads. */
- if (!optimize
+ if ((!optimize || !ter)
&& gimple_assign_single_p (stmt)
&& !is_gimple_val (gimple_assign_rhs1 (stmt)))
return false;
@@ -444,6 +452,16 @@ is_replaceable_p (gimple stmt)
}
+/* Variant of is_replaceable_p test for use in EXPAND_INITIALIZER
+ expansion. */
+
+bool
+stmt_is_replaceable_p (gimple stmt)
+{
+ return is_replaceable_p (stmt, false);
+}
+
+
/* This function will remove the expression for VERSION from replacement
consideration in table TAB. If FREE_EXPR is true, then remove the
expression from consideration as well by freeing the decl uid bitmap. */
@@ -477,7 +495,7 @@ process_replaceable (temp_expr_table_p tab, gimple stmt, int call_cnt)
ssa_op_iter iter;
bitmap def_vars, use_vars;
- gcc_checking_assert (is_replaceable_p (stmt));
+ gcc_checking_assert (is_replaceable_p (stmt, true));
def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF);
version = SSA_NAME_VERSION (def);
@@ -589,7 +607,7 @@ find_replaceable_in_bb (temp_expr_table_p tab, basic_block bb)
if (is_gimple_debug (stmt))
continue;
- stmt_replaceable = is_replaceable_p (stmt);
+ stmt_replaceable = is_replaceable_p (stmt, true);
/* Determine if this stmt finishes an existing expression. */
FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)