diff options
author | Jeff Law <law@redhat.com> | 2015-12-10 09:34:43 -0700 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 2015-12-10 09:34:43 -0700 |
commit | 3daacdcd5f20d084294f2cc50f84e3e8769205f1 (patch) | |
tree | d015d8a16670f07cb924dc37566a552de34a31e7 /gcc/domwalk.h | |
parent | 9dd920ab7090041bc4983209b0807c69339299f8 (diff) | |
download | gcc-3daacdcd5f20d084294f2cc50f84e3e8769205f1.zip gcc-3daacdcd5f20d084294f2cc50f84e3e8769205f1.tar.gz gcc-3daacdcd5f20d084294f2cc50f84e3e8769205f1.tar.bz2 |
re PR tree-optimization/68619 (error: loop with header 6 not in loop tree)
2015-12-10 Jeff Law <law@redhat.com>
PR tree-optimization/68619
* tree-ssa-dom.c (dom_opt_dom_walker::before_dom_children): Propgate
return value from optimize_stmt.
(dom_opt_dom_walker): Add new argument to dom_walker constructor.
(pass_dominator:execute): If a block has an unreachable edge,
remove all jump threads through any successor of the affected block.
(record_equivalences_from_phis): Ignore alternative if the edge
does not have EDGE_EXECUTABLE set.
(single_incoming_edge_ignoring_loop_edges): Similarly.
(optimize_stmt): If a gimple_code has a compile-time constant
condition, return the edge taken for that constant value. Also
change the condition to true/false as necessary.
* domwalk.h (dom_walker::dom_walker): Add new argument
skip_unreachable_blocks. Don't provide empty constructor body.
(dom_walker::before_dom_children): Change return type.
(dom_walker::bb_reachable): Declare new private method.
(dom_walker::propagate_unreachable_to_edges): Likewise.
(dom_walker::m_unreachable_dom): Declare new private data member.
(dom_walker::m_skip_unreachable_blocks): Likewise.
* domwalk.c: Include dumpfile.h.
(dom_walker::dom_walker): New constructor. Initialize private data
members. If needed, set EDGE_EXECUTABLE for all edges in the CFG,
extracted from tree-ssa-sccvn.c.
(dom_walker::bb_reachable): New method extracted from tree-ssa-sccvn.c
(dom_walker::propagate_unreachable_to_edges): Likewise.
(dom_walker::walk): Only call before_dom_children on reachable
blocks. If before_dom_children returns an edge, then clear
EDGE_EXECUTABLE for all other outgoing edges from the same block.
For unreachable blocks, call propagate_unreachable_to_edges.
Similarly, only call after_dom_children on reachable blocks. For
unreachable blocks, conditionally clear m_unreachable_dom.
* tree-ssa-sccvn.c (sccvn_dom_walker::unreachable_dom): Remove
private data member.
(sccvn_dom_walker::after_dom_children): Use methods from dom_walker
class.
(run_scc_vn): Likewise.
(sccvn_dom_walker::before_dom_children): Likewise. Return the taken
outgoing edge if a COND, SWITCH, or GOTO are optimized.
* compare-elim.c (find_comparison_dom_walker::before_dom_children):
Change return type to an edge. Always return NULL.
* fwprop.c (single_def_use_dom_walker::before_dom_children): Likewise.
* gimple-ssa-strength-reduction.c
(find_candidates_dom_walker::before_dom_children): Likewise.
* ipa-prop.c (analysis_dom_walker::before_dom_children): Likewise.
(ipcp_modif_dom_walker::before_dom_children): Likewise.
* tree-into-ssa.c (rewrite_dom_walker::before_dom_children): Likewise.
(rewrite_update_dom_walker::before_dom_children): Likewise.
(mark_def_dom_children::before_dom_children): Likewise.
* tree-ssa-dse.c (dse_dom_walker::before_dom_children): Likewise.
* tree-ssa-loop-im.c
(invariantness_dom_walker::before_dom_children): Likewise.
(move_computations_dom_walker::before_dom_walker): Likewise.
* tree-ssa-phiopt.c
(nontrapping_dom_walker::before_dom_children): Likewise.
* tree-ssa-pre.c
(eliminate_dom_walker::before_dom_children): Likewise.
* tree-ssa-propagate.c
(substitute_and_fold_dom_walker::before_dom_children): Likewise.
* tree-ssa-strlen.c
(strlen_dom_walker::before_dom_children): Likewise.
* tree-ssa-uncprop.c
(uncprop_dom_walker::before_dom_children): Likewise.
PR tree-optimization/68619
* gcc.dg/tree-ssa/pr68619-1.c: New test.
* gcc.dg/tree-ssa/pr68619-2.c: New test.
* gcc.dg/tree-ssa/pr68619-3.c: New test.
* gcc.dg/tree-ssa/pr68619-4.c: New test.
* gcc.dg/tree-ssa/pr68619-5.c: New test.
From-SVN: r231527
Diffstat (limited to 'gcc/domwalk.h')
-rw-r--r-- | gcc/domwalk.h | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/gcc/domwalk.h b/gcc/domwalk.h index 71a7c47..e631a67 100644 --- a/gcc/domwalk.h +++ b/gcc/domwalk.h @@ -30,13 +30,26 @@ along with GCC; see the file COPYING3. If not see class dom_walker { public: - dom_walker (cdi_direction direction) : m_dom_direction (direction) {} + /* Use SKIP_UNREACHBLE_BLOCKS = true when your client can discover + that some edges are not executable. + + If a client can discover that a COND, SWITCH or GOTO has a static + target in the before_dom_children callback, the taken edge should + be returned. The generic walker will clear EDGE_EXECUTABLE on all + edges it can determine are not executable. */ + dom_walker (cdi_direction direction, bool skip_unreachable_blocks = false); /* Walk the dominator tree. */ void walk (basic_block); - /* Function to call before the recursive walk of the dominator children. */ - virtual void before_dom_children (basic_block) {} + /* Function to call before the recursive walk of the dominator children. + + Return value is the always taken edge if the block has multiple outgoing + edges, NULL otherwise. When skipping unreachable blocks, the walker + uses the taken edge information to clear EDGE_EXECUTABLE on the other + edges, exposing unreachable blocks. A NULL return value means all + outgoing edges should still be considered executable. */ + virtual edge before_dom_children (basic_block) { return NULL; } /* Function to call after the recursive walk of the dominator children. */ virtual void after_dom_children (basic_block) {} @@ -47,6 +60,18 @@ private: if it is set to CDI_POST_DOMINATORS, then we walk the post dominator tree. */ const ENUM_BITFIELD (cdi_direction) m_dom_direction : 2; + bool m_skip_unreachable_blocks; + basic_block m_unreachable_dom; + + /* Query whether or not the given block is reachable or not. */ + bool bb_reachable (struct function *, basic_block); + + /* Given an unreachable block, propagate that property to outgoing + and possibly incoming edges for the block. Typically called after + determining a block is unreachable in the before_dom_children + callback. */ + void propagate_unreachable_to_edges (basic_block, FILE *, int); + }; #endif |