diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-02-04 15:50:51 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-02-04 15:50:51 +0000 |
commit | 351b6ccf86d48ad98795df9defe0af7f35fdd66d (patch) | |
tree | 414dfa9293092030de0a06170c839b69d92e5b67 /gcc | |
parent | 8119d93591ec9a4d1cb160a13c51584e79478b7c (diff) | |
download | gcc-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/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/expr.c | 7 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr23200.c | 22 | ||||
-rw-r--r-- | gcc/tree-flow.h | 5 | ||||
-rw-r--r-- | gcc/tree-ssa-ter.c | 32 |
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) |