On 12/10/15 16:49, Tom de Vries wrote:
Hi,
I've committed the following patch series to the gomp-4_0-branch.
1 Add pass_dominator::jump_threading_p ()
2 Add dom_walker::walk_until
3 Add pass_dominator::sese_mode_p ()
4 Add skip_stmt parm to pass_dominator::get_sese ()
5 Add oacc kernels related infra functions
6 Add pass_dominator_oacc_kernels
The patch series adds a pass pass_dominator_oacc_kernels, which does the
pass_dominator optimizations (with the exception of jump threading) on
each oacc kernels region rather than on the whole function.
Bootstrapped and reg-tested on x86_64.
I'll post the patches individually, in reply to this email.
This patch adds the possibility to pass_dominators to switch off the
jump threading optimization.
Note that we do not disable threadedge_initialize_values /
threadedge_finalize_values, since the values stored there are used for
other optimizations as well.
Thanks,
- Tom
Add pass_dominator::jump_threading_p ()
2015-10-12 Tom de Vries <t...@codesourcery.com>
* tree-ssa-dom.c (dom_opt_dom_walker::dom_opt_dom_walker): Add
jump_threading_p parameters.
(dom_opt_dom_walker::m_jump_threading_p): New private var.
(pass_dominator::jump_threading_p): New protected virtual function.
(pass_dominator::execute): Handle jump_threading_p.
(dom_opt_dom_walker::before_dom_children)
(dom_opt_dom_walker::after_dom_children): Handle m_jump_threading_p.
---
gcc/tree-ssa-dom.c | 109 +++++++++++++++++++++++++++++++----------------------
1 file changed, 64 insertions(+), 45 deletions(-)
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index a8b7038..162d9ed 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -492,11 +492,14 @@ class dom_opt_dom_walker : public dom_walker
public:
dom_opt_dom_walker (cdi_direction direction,
class const_and_copies *const_and_copies,
- class avail_exprs_stack *avail_exprs_stack)
+ class avail_exprs_stack *avail_exprs_stack,
+ bool jump_threading_p)
: dom_walker (direction),
m_const_and_copies (const_and_copies),
m_avail_exprs_stack (avail_exprs_stack),
- m_dummy_cond (NULL) {}
+ m_dummy_cond (NULL),
+ m_jump_threading_p (jump_threading_p)
+ {}
virtual void before_dom_children (basic_block);
virtual void after_dom_children (basic_block);
@@ -509,6 +512,7 @@ private:
class avail_exprs_stack *m_avail_exprs_stack;
gcond *m_dummy_cond;
+ bool m_jump_threading_p;
};
/* Jump threading, redundancy elimination and const/copy propagation.
@@ -544,6 +548,10 @@ public:
virtual bool gate (function *) { return flag_tree_dom != 0; }
virtual unsigned int execute (function *);
+ protected:
+ /* Return true if pass should perform jump threading. */
+ virtual bool jump_threading_p (void) { return true; }
+
}; // class pass_dominator
unsigned int
@@ -578,25 +586,29 @@ pass_dominator::execute (function *fun)
/* Initialize the value-handle array. */
threadedge_initialize_values ();
- /* We need accurate information regarding back edges in the CFG
- for jump threading; this may include back edges that are not part of
- a single loop. */
- mark_dfs_back_edges ();
-
- /* We want to create the edge info structures before the dominator walk
- so that they'll be in place for the jump threader, particularly when
- threading through a join block.
-
- The conditions will be lazily updated with global equivalences as
- we reach them during the dominator walk. */
- basic_block bb;
- FOR_EACH_BB_FN (bb, fun)
- record_edge_info (bb);
+ if (jump_threading_p ())
+ {
+ /* We need accurate information regarding back edges in the CFG
+ for jump threading; this may include back edges that are not part of
+ a single loop. */
+ mark_dfs_back_edges ();
+
+ /* We want to create the edge info structures before the dominator walk
+ so that they'll be in place for the jump threader, particularly when
+ threading through a join block.
+
+ The conditions will be lazily updated with global equivalences as
+ we reach them during the dominator walk. */
+ basic_block bb;
+ FOR_EACH_BB_FN (bb, fun)
+ record_edge_info (bb);
+ }
/* Recursively walk the dominator tree optimizing statements. */
dom_opt_dom_walker walker (CDI_DOMINATORS,
const_and_copies,
- avail_exprs_stack);
+ avail_exprs_stack,
+ jump_threading_p ());
walker.walk (fun->cfg->x_entry_block_ptr);
{
@@ -616,10 +628,13 @@ pass_dominator::execute (function *fun)
duplication and CFG manipulation. */
update_ssa (TODO_update_ssa);
- free_all_edge_infos ();
+ if (jump_threading_p ())
+ {
+ free_all_edge_infos ();
- /* Thread jumps, creating duplicate blocks as needed. */
- cfg_altered |= thread_through_all_blocks (first_pass_instance);
+ /* Thread jumps, creating duplicate blocks as needed. */
+ cfg_altered |= thread_through_all_blocks (first_pass_instance);
+ }
if (cfg_altered)
free_dominance_info (CDI_DOMINATORS);
@@ -1314,7 +1329,8 @@ dom_opt_dom_walker::before_dom_children (basic_block bb)
optimize_stmt (bb, gsi, m_const_and_copies, m_avail_exprs_stack);
/* Now prepare to process dominated blocks. */
- record_edge_info (bb);
+ if (m_jump_threading_p)
+ record_edge_info (bb);
cprop_into_successor_phis (bb, m_const_and_copies);
}
@@ -1327,35 +1343,38 @@ dom_opt_dom_walker::after_dom_children (basic_block bb)
{
gimple *last;
- /* If we have an outgoing edge to a block with multiple incoming and
- outgoing edges, then we may be able to thread the edge, i.e., we
- may be able to statically determine which of the outgoing edges
- will be traversed when the incoming edge from BB is traversed. */
- if (single_succ_p (bb)
- && (single_succ_edge (bb)->flags & EDGE_ABNORMAL) == 0
- && potentially_threadable_block (single_succ (bb)))
- {
- thread_across_edge (single_succ_edge (bb));
- }
- else if ((last = last_stmt (bb))
- && gimple_code (last) == GIMPLE_COND
- && EDGE_COUNT (bb->succs) == 2
- && (EDGE_SUCC (bb, 0)->flags & EDGE_ABNORMAL) == 0
- && (EDGE_SUCC (bb, 1)->flags & EDGE_ABNORMAL) == 0)
+ if (m_jump_threading_p)
{
- edge true_edge, false_edge;
+ /* If we have an outgoing edge to a block with multiple incoming and
+ outgoing edges, then we may be able to thread the edge, i.e., we
+ may be able to statically determine which of the outgoing edges
+ will be traversed when the incoming edge from BB is traversed. */
+ if (single_succ_p (bb)
+ && (single_succ_edge (bb)->flags & EDGE_ABNORMAL) == 0
+ && potentially_threadable_block (single_succ (bb)))
+ {
+ thread_across_edge (single_succ_edge (bb));
+ }
+ else if ((last = last_stmt (bb))
+ && gimple_code (last) == GIMPLE_COND
+ && EDGE_COUNT (bb->succs) == 2
+ && (EDGE_SUCC (bb, 0)->flags & EDGE_ABNORMAL) == 0
+ && (EDGE_SUCC (bb, 1)->flags & EDGE_ABNORMAL) == 0)
+ {
+ edge true_edge, false_edge;
- extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
+ extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
- /* Only try to thread the edge if it reaches a target block with
- more than one predecessor and more than one successor. */
- if (potentially_threadable_block (true_edge->dest))
- thread_across_edge (true_edge);
+ /* Only try to thread the edge if it reaches a target block with
+ more than one predecessor and more than one successor. */
+ if (potentially_threadable_block (true_edge->dest))
+ thread_across_edge (true_edge);
- /* Similarly for the ELSE arm. */
- if (potentially_threadable_block (false_edge->dest))
- thread_across_edge (false_edge);
+ /* Similarly for the ELSE arm. */
+ if (potentially_threadable_block (false_edge->dest))
+ thread_across_edge (false_edge);
+ }
}
/* These remove expressions local to BB from the tables. */
--
1.9.1