aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-if-conv.c
diff options
context:
space:
mode:
authorYuri Rumyantsev <ysrumyan@gmail.com>2016-10-17 18:05:12 +0000
committerH.J. Lu <hjl@gcc.gnu.org>2016-10-17 11:05:12 -0700
commit1d30acf68750f2617c3779176781a26b0b50cfa8 (patch)
treeb6ddb1ae919d71ade64e2f439d42ae08f57e4d6d /gcc/tree-if-conv.c
parent871267e19da270df32c9ffe8be194228a14ddd87 (diff)
downloadgcc-1d30acf68750f2617c3779176781a26b0b50cfa8.zip
gcc-1d30acf68750f2617c3779176781a26b0b50cfa8.tar.gz
gcc-1d30acf68750f2617c3779176781a26b0b50cfa8.tar.bz2
Update dom_info
2016-10-17 Yuri Rumyantsev <ysrumyan@gmail.com> * dominance.c (dom_info::dom_info): Add new constructor for region which is vector of basic blocks. (dom_init): New method to initialize members common for both constructors. (dom_info::dom_info): Invoke dom_init for partial initialization. (dom_info::get_idom): Add check to corner cases on basic blocks which are not in region. (dom_info::calc_dfs_tree): Check M_FAKE_EXIT_EDGE instead of M_REVERSE to detect unreachable bbs. (dom_info::calc_idoms): Likewise. (compute_dom_fast_query_in_region): New function. (calculate_dominance_info_for_region): Likewise. (free_dominance_info_for_region): Likewise. * dominance.h: Add prototypes for introduced region-based functions tree-if-conv.c: (build_region): New function. (if_convertible_loop_p_1): Invoke local version of post-dominators calculation before basic block predication with subsequent freeing post-dominator info. (tree_if_conversion): Remove free of post-dominator info (pass_if_conversion::execute): Delete detection of infinite loops and fake edges to exit block since post-dominator calculation is performed per if-converted loop only. From-SVN: r241275
Diffstat (limited to 'gcc/tree-if-conv.c')
-rw-r--r--gcc/tree-if-conv.c53
1 files changed, 41 insertions, 12 deletions
diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c
index eec431e..0a20189 100644
--- a/gcc/tree-if-conv.c
+++ b/gcc/tree-if-conv.c
@@ -1309,6 +1309,38 @@ predicate_bbs (loop_p loop)
&& bb_predicate_gimplified_stmts (loop->latch) == NULL);
}
+/* Build region by adding loop pre-header and post-header blocks. */
+
+static vec<basic_block>
+build_region (struct loop *loop)
+{
+ vec<basic_block> region = vNULL;
+ basic_block exit_bb = NULL;
+
+ gcc_assert (ifc_bbs);
+ /* The first element is loop pre-header. */
+ region.safe_push (loop_preheader_edge (loop)->src);
+
+ for (unsigned int i = 0; i < loop->num_nodes; i++)
+ {
+ basic_block bb = ifc_bbs[i];
+ region.safe_push (bb);
+ /* Find loop postheader. */
+ edge e;
+ edge_iterator ei;
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ if (loop_exit_edge_p (loop, e))
+ {
+ exit_bb = e->dest;
+ break;
+ }
+ }
+ /* The last element is loop post-header. */
+ gcc_assert (exit_bb);
+ region.safe_push (exit_bb);
+ return region;
+}
+
/* Return true when LOOP is if-convertible. This is a helper function
for if_convertible_loop_p. REFS and DDRS are initialized and freed
in if_convertible_loop_p. */
@@ -1318,6 +1350,7 @@ if_convertible_loop_p_1 (struct loop *loop, vec<data_reference_p> *refs)
{
unsigned int i;
basic_block exit_bb = NULL;
+ vec<basic_block> region;
if (find_data_references_in_loop (loop, refs) == chrec_dont_know)
return false;
@@ -1370,9 +1403,16 @@ if_convertible_loop_p_1 (struct loop *loop, vec<data_reference_p> *refs)
= new hash_map<innermost_loop_behavior_hash, data_reference_p>;
baseref_DR_map = new hash_map<tree_operand_hash, data_reference_p>;
- calculate_dominance_info (CDI_POST_DOMINATORS);
+ /* Compute post-dominator tree locally. */
+ region = build_region (loop);
+ calculate_dominance_info_for_region (CDI_POST_DOMINATORS, region);
+
predicate_bbs (loop);
+ /* Free post-dominator tree since it is not used after predication. */
+ free_dominance_info_for_region (cfun, CDI_POST_DOMINATORS, region);
+ region.release ();
+
for (i = 0; refs->iterate (i, &dr); i++)
{
tree ref = DR_REF (dr);
@@ -2752,7 +2792,6 @@ tree_if_conversion (struct loop *loop)
free (ifc_bbs);
ifc_bbs = NULL;
}
- free_dominance_info (CDI_POST_DOMINATORS);
return todo;
}
@@ -2805,14 +2844,6 @@ pass_if_conversion::execute (function *fun)
if (number_of_loops (fun) <= 1)
return 0;
- /* If there are infinite loops, during CDI_POST_DOMINATORS computation
- we can pick pretty much random bb inside of the infinite loop that
- has the fake edge. If we are unlucky enough, this can confuse the
- add_to_predicate_list post-dominator check to optimize as if that
- bb or some other one is a join block when it actually is not.
- See PR70916. */
- connect_infinite_loops_to_exit ();
-
FOR_EACH_LOOP (loop, 0)
if (flag_tree_loop_if_convert == 1
|| flag_tree_loop_if_convert_stores == 1
@@ -2820,8 +2851,6 @@ pass_if_conversion::execute (function *fun)
&& !loop->dont_vectorize))
todo |= tree_if_conversion (loop);
- remove_fake_exit_edges ();
-
if (flag_checking)
{
basic_block bb;