aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.8/gcc/tree-ssa-ter.c
diff options
context:
space:
mode:
authorAndrew Hsieh <andrewhsieh@google.com>2014-06-18 13:00:04 -0700
committerPavel Chupin <pavel.v.chupin@intel.com>2014-06-19 22:38:42 +0400
commitf190d6284359da8ae8694b2d2e14b01602a959ed (patch)
treed4e0548e7cec02d60b1082368032e66a1c509a02 /gcc-4.8/gcc/tree-ssa-ter.c
parent4ff2f42147bc128ce38789071d98e55844cd3a5e (diff)
downloadtoolchain_gcc-f190d6284359da8ae8694b2d2e14b01602a959ed.tar.gz
toolchain_gcc-f190d6284359da8ae8694b2d2e14b01602a959ed.tar.bz2
toolchain_gcc-f190d6284359da8ae8694b2d2e14b01602a959ed.zip
Merge GCC 4.8.3
Change-Id: I0abe59f7705b3eccc6b2f123af75b2e30917696a
Diffstat (limited to 'gcc-4.8/gcc/tree-ssa-ter.c')
-rw-r--r--gcc-4.8/gcc/tree-ssa-ter.c49
1 files changed, 46 insertions, 3 deletions
diff --git a/gcc-4.8/gcc/tree-ssa-ter.c b/gcc-4.8/gcc/tree-ssa-ter.c
index 2a2e143de..8f27d374b 100644
--- a/gcc-4.8/gcc/tree-ssa-ter.c
+++ b/gcc-4.8/gcc/tree-ssa-ter.c
@@ -590,6 +590,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. */
@@ -643,8 +667,7 @@ find_replaceable_in_bb (temp_expr_table_p tab, basic_block bb)
/* If the stmt does a memory store and the replacement
is a load aliasing it avoid creating overlapping
assignments which we cannot expand correctly. */
- if (gimple_vdef (stmt)
- && gimple_assign_single_p (stmt))
+ if (gimple_vdef (stmt))
{
gimple def_stmt = SSA_NAME_DEF_STMT (use);
while (is_gimple_assign (def_stmt)
@@ -653,10 +676,30 @@ find_replaceable_in_bb (temp_expr_table_p tab, basic_block bb)
= SSA_NAME_DEF_STMT (gimple_assign_rhs1 (def_stmt));
if (gimple_vuse (def_stmt)
&& gimple_assign_single_p (def_stmt)
- && refs_may_alias_p (gimple_assign_lhs (stmt),
+ && stmt_may_clobber_ref_p (stmt,
gimple_assign_rhs1 (def_stmt)))
+ {
+ /* 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
def variable has the same root variable as something in the