summaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-tail-merge.c
diff options
context:
space:
mode:
authorbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2013-11-22 14:58:36 +0000
committerbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2013-11-22 14:58:36 +0000
commitcfea6514a4b6ced0930593ebb48d0037e9716d87 (patch)
treeeeccf866e18463f7dc7ea882ea944247d4ed1010 /gcc/tree-ssa-tail-merge.c
parent9456798d72d0e81a2a553287f436dcb05cff175a (diff)
downloadgcc-cfea6514a4b6ced0930593ebb48d0037e9716d87.tar.gz
[./]
2013-11-22 Basile Starynkevitch <basile@starynkevitch.net> {{merge with trunk GCC 4.9 svn rev 205247 now in stage 3}} [gcc/] 2013-11-22 Basile Starynkevitch <basile@starynkevitch.net> {{merge with trunk GCC 4.9 svn rev 205247 now in stage 3}} * Makefile.in (MELT_GCC_VERSION_NUM): New make variable. (melt-run-md5.h, melt-run.h): Use it. * melt-runtime.cc: With GCC 4.9 include print-tree.h, gimple-iterator.h, gimple-walk.h. (meltgc_start_all_new_modules, meltgc_start_flavored_module) (meltgc_do_initial_mode, meltgc_set_user_options) (meltgc_load_modules_and_do_mode): Improve debugprintf... (melt_gt_ggc_mx_gimple_seq_d): Handle GCC 4.9 specifically. * melt-runtime.h (gt_ggc_mx_gimple_statement_d): Temporarily define this macro. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@205264 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-tail-merge.c')
-rw-r--r--gcc/tree-ssa-tail-merge.c81
1 files changed, 48 insertions, 33 deletions
diff --git a/gcc/tree-ssa-tail-merge.c b/gcc/tree-ssa-tail-merge.c
index db95ce1059c..2e1df69b7bd 100644
--- a/gcc/tree-ssa-tail-merge.c
+++ b/gcc/tree-ssa-tail-merge.c
@@ -190,11 +190,14 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
+#include "stor-layout.h"
+#include "trans-mem.h"
#include "tm_p.h"
#include "basic-block.h"
#include "flags.h"
#include "function.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
@@ -208,6 +211,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-dump.h"
#include "cfgloop.h"
#include "tree-pass.h"
+#include "trans-mem.h"
/* Describes a group of bbs with the same successors. The successor bbs are
cached in succs, and the successor edge flags are cached in succ_flags.
@@ -305,6 +309,7 @@ stmt_local_def (gimple stmt)
def_operand_p def_p;
if (gimple_has_side_effects (stmt)
+ || stmt_could_throw_p (stmt)
|| gimple_vdef (stmt) != NULL_TREE)
return false;
@@ -761,11 +766,11 @@ static void
init_worklist (void)
{
alloc_aux_for_blocks (sizeof (struct aux_bb_info));
- same_succ_htab.create (n_basic_blocks);
+ same_succ_htab.create (n_basic_blocks_for_fn (cfun));
same_succ_edge_flags = XCNEWVEC (int, last_basic_block);
deleted_bbs = BITMAP_ALLOC (NULL);
deleted_bb_preds = BITMAP_ALLOC (NULL);
- worklist.create (n_basic_blocks);
+ worklist.create (n_basic_blocks_for_fn (cfun));
find_same_succ ();
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -993,7 +998,7 @@ static vec<bb_cluster> all_clusters;
static void
alloc_cluster_vectors (void)
{
- all_clusters.create (n_basic_blocks);
+ all_clusters.create (n_basic_blocks_for_fn (cfun));
}
/* Reset all cluster vectors. */
@@ -1075,6 +1080,24 @@ set_cluster (basic_block bb1, basic_block bb2)
gcc_unreachable ();
}
+/* Return true if gimple operands T1 and T2 have the same value. */
+
+static bool
+gimple_operand_equal_value_p (tree t1, tree t2)
+{
+ if (t1 == t2)
+ return true;
+
+ if (t1 == NULL_TREE
+ || t2 == NULL_TREE)
+ return false;
+
+ if (operand_equal_p (t1, t2, 0))
+ return true;
+
+ return gvn_uses_equal (t1, t2);
+}
+
/* Return true if gimple statements S1 and S2 are equal. Gimple_bb (s1) and
gimple_bb (s2) are members of SAME_SUCC. */
@@ -1085,7 +1108,7 @@ gimple_equal_p (same_succ same_succ, gimple s1, gimple s2)
tree lhs1, lhs2;
basic_block bb1 = gimple_bb (s1), bb2 = gimple_bb (s2);
tree t1, t2;
- bool equal, inv_cond;
+ bool inv_cond;
enum tree_code code1, code2;
if (gimple_code (s1) != gimple_code (s2))
@@ -1099,28 +1122,14 @@ gimple_equal_p (same_succ same_succ, gimple s1, gimple s2)
if (!gimple_call_same_target_p (s1, s2))
return false;
- /* Eventually, we'll significantly complicate the CFG by adding
- back edges to properly model the effects of transaction restart.
- For the bulk of optimization this does not matter, but what we
- cannot recover from is tail merging blocks between two separate
- transactions. Avoid that by making commit not match. */
- if (gimple_call_builtin_p (s1, BUILT_IN_TM_COMMIT))
- return false;
-
- equal = true;
for (i = 0; i < gimple_call_num_args (s1); ++i)
{
t1 = gimple_call_arg (s1, i);
t2 = gimple_call_arg (s2, i);
- if (operand_equal_p (t1, t2, 0))
+ if (gimple_operand_equal_value_p (t1, t2))
continue;
- if (gvn_uses_equal (t1, t2))
- continue;
- equal = false;
- break;
+ return false;
}
- if (!equal)
- return false;
lhs1 = gimple_get_lhs (s1);
lhs2 = gimple_get_lhs (s2);
@@ -1137,8 +1146,17 @@ gimple_equal_p (same_succ same_succ, gimple s1, gimple s2)
lhs2 = gimple_get_lhs (s2);
if (TREE_CODE (lhs1) != SSA_NAME
&& TREE_CODE (lhs2) != SSA_NAME)
- return (vn_valueize (gimple_vdef (s1))
- == vn_valueize (gimple_vdef (s2)));
+ {
+ /* If the vdef is the same, it's the same statement. */
+ if (vn_valueize (gimple_vdef (s1))
+ == vn_valueize (gimple_vdef (s2)))
+ return true;
+
+ /* Test for structural equality. */
+ return (operand_equal_p (lhs1, lhs2, 0)
+ && gimple_operand_equal_value_p (gimple_assign_rhs1 (s1),
+ gimple_assign_rhs1 (s2)));
+ }
else if (TREE_CODE (lhs1) == SSA_NAME
&& TREE_CODE (lhs2) == SSA_NAME)
return vn_valueize (lhs1) == vn_valueize (lhs2);
@@ -1147,14 +1165,12 @@ gimple_equal_p (same_succ same_succ, gimple s1, gimple s2)
case GIMPLE_COND:
t1 = gimple_cond_lhs (s1);
t2 = gimple_cond_lhs (s2);
- if (!operand_equal_p (t1, t2, 0)
- && !gvn_uses_equal (t1, t2))
+ if (!gimple_operand_equal_value_p (t1, t2))
return false;
t1 = gimple_cond_rhs (s1);
t2 = gimple_cond_rhs (s2);
- if (!operand_equal_p (t1, t2, 0)
- && !gvn_uses_equal (t1, t2))
+ if (!gimple_operand_equal_value_p (t1, t2))
return false;
code1 = gimple_expr_code (s1);
@@ -1224,15 +1240,14 @@ find_duplicate (same_succ same_succ, basic_block bb1, basic_block bb2)
gimple stmt1 = gsi_stmt (gsi1);
gimple stmt2 = gsi_stmt (gsi2);
- if (!gimple_equal_p (same_succ, stmt1, stmt2))
+ /* What could be better than to this this here is to blacklist the bb
+ containing the stmt, when encountering the stmt f.i. in
+ same_succ_hash. */
+ if (is_tm_ending (stmt1)
+ || is_tm_ending (stmt2))
return;
- // We cannot tail-merge the builtins that end transactions.
- // ??? The alternative being unsharing of BBs in the tm_init pass.
- if (flag_tm
- && is_gimple_call (stmt1)
- && (gimple_call_flags (stmt1) & ECF_TM_BUILTIN)
- && is_tm_ending_fndecl (gimple_call_fndecl (stmt1)))
+ if (!gimple_equal_p (same_succ, stmt1, stmt2))
return;
gsi_prev_nondebug (&gsi1);