summaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-ter.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2013-12-16 09:09:05 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2013-12-16 09:09:05 +0100
commit9f1363cd0d72667eac019840e929e64431ee5d4e (patch)
tree05010ae56236744b03a8fd2cb1415586dd321f47 /gcc/tree-ssa-ter.c
parent317c1849286a2acdf6e72bc2b0973d52b4ba5202 (diff)
re PR middle-end/58956 (wrong code at -O1 and above (affecting gcc 4.6 to trunk))
PR middle-end/58956 PR middle-end/59470 * gimple-walk.h (walk_stmt_load_store_addr_fn): New typedef. (walk_stmt_load_store_addr_ops, walk_stmt_load_store_ops): Use it for callback params. * gimple-walk.c (walk_stmt_load_store_ops): Likewise. (walk_stmt_load_store_addr_ops): Likewise. Adjust all callback calls to supply the gimple operand containing the base tree as an extra argument. * tree-ssa-ter.c: Include gimple-walk.h. (find_ssaname, find_ssaname_in_store): New helper functions. (find_replaceable_in_bb): For calls or GIMPLE_ASM, only set same_root_var if USE is used somewhere in the stores of the stmt. * ipa-prop.c (visit_ref_for_mod_analysis): Remove name of the stmt argument and ATTRIBUTE_UNUSED, add another unnamed tree argument. * ipa-pure-const.c (check_load, check_store, check_ipa_load, check_ipa_store): Likewise. * gimple.c (gimple_ior_addresses_taken_1, check_loadstore): Likewise. * ipa-split.c (test_nonssa_use, mark_nonssa_use): Likewise. (verify_non_ssa_vars, visit_bb): Adjust their callers. * cfgexpand.c (add_scope_conflicts_1): Use walk_stmt_load_store_addr_fn type for visit variable. (visit_op, visit_conflict): Remove name of the stmt argument and ATTRIBUTE_UNUSED, add another unnamed tree argument. * tree-sra.c (asm_visit_addr): Likewise. Remove name of the data argument and ATTRIBUTE_UNUSED. * cgraphbuild.c (mark_address, mark_load, mark_store): Add another unnamed tree argument. * gimple-ssa-isolate-paths.c (check_loadstore): Likewise. Remove ATTRIBUTE_UNUSED from stmt parameter. * gcc.target/i386/pr59470.c: New test. From-SVN: r206009
Diffstat (limited to 'gcc/tree-ssa-ter.c')
-rw-r--r--gcc/tree-ssa-ter.c47
1 files changed, 46 insertions, 1 deletions
diff --git a/gcc/tree-ssa-ter.c b/gcc/tree-ssa-ter.c
index 22ae47b766b..cefe47c6d5f 100644
--- a/gcc/tree-ssa-ter.c
+++ b/gcc/tree-ssa-ter.c
@@ -43,6 +43,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-ssa-ter.h"
#include "tree-outof-ssa.h"
#include "flags.h"
+#include "gimple-walk.h"
/* Temporary Expression Replacement (TER)
@@ -554,6 +555,30 @@ mark_replaceable (temp_expr_table_p tab, tree var, bool more_replacing)
}
+/* Helper function for find_ssaname_in_stores. Called via walk_tree to
+ find a SSA_NAME DATA somewhere in *TP. */
+
+static tree
+find_ssaname (tree *tp, int *walk_subtrees, void *data)
+{
+ tree var = (tree) data;
+ if (*tp == var)
+ return var;
+ else if (IS_TYPE_OR_DECL_P (*tp))
+ *walk_subtrees = 0;
+ return NULL_TREE;
+}
+
+/* Helper function for find_replaceable_in_bb. Return true if SSA_NAME DATA
+ is used somewhere in T, which is a store in the statement. Called via
+ walk_stmt_load_store_addr_ops. */
+
+static bool
+find_ssaname_in_store (gimple, tree, tree t, void *data)
+{
+ return walk_tree (&t, find_ssaname, data, NULL) != NULL_TREE;
+}
+
/* This function processes basic block BB, and looks for variables which can
be replaced by their expressions. Results are stored in the table TAB. */
@@ -618,7 +643,27 @@ find_replaceable_in_bb (temp_expr_table_p tab, basic_block bb)
&& gimple_assign_single_p (def_stmt)
&& stmt_may_clobber_ref_p (stmt,
gimple_assign_rhs1 (def_stmt)))
- same_root_var = true;
+ {
+ /* For calls, it is not a problem if USE is among
+ call's arguments or say OBJ_TYPE_REF argument,
+ all those necessarily need to be evaluated before
+ the call that may clobber the memory. But if
+ LHS of the call refers to USE, expansion might
+ evaluate it after the call, prevent TER in that
+ case.
+ For inline asm, allow TER of loads into input
+ arguments, but disallow TER for USEs that occur
+ somewhere in outputs. */
+ if (is_gimple_call (stmt)
+ || gimple_code (stmt) == GIMPLE_ASM)
+ {
+ if (walk_stmt_load_store_ops (stmt, use, NULL,
+ find_ssaname_in_store))
+ same_root_var = true;
+ }
+ else
+ same_root_var = true;
+ }
}
/* Mark expression as replaceable unless stmt is volatile, or the