aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vrp.c
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2020-11-11 20:10:42 +0100
committerAldy Hernandez <aldyh@redhat.com>2020-11-13 08:34:48 +0100
commit7cc52bc85e90ed71e67c443f14137f2fcf6adf3c (patch)
treee0a0d23d1701a01278b0611f4b8e9c5fa5dc73ee /gcc/tree-vrp.c
parent2efb9eaaedfaa5b3d194c3184a1d56b702e2fe39 (diff)
downloadgcc-7cc52bc85e90ed71e67c443f14137f2fcf6adf3c.zip
gcc-7cc52bc85e90ed71e67c443f14137f2fcf6adf3c.tar.gz
gcc-7cc52bc85e90ed71e67c443f14137f2fcf6adf3c.tar.bz2
Refactor VRP threading code into vrp_jump_threader class.
gcc/ChangeLog: * tree-vrp.c (identify_jump_threads): Refactor to.. (vrp_jump_threader::vrp_jump_threader): ...here (vrp_jump_threader::~vrp_jump_threader): ...and here. (vrp_jump_threader::after_dom_children): Rename vr_values to m_vr_values. (execute_vrp): Use vrp_jump_threader.
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r--gcc/tree-vrp.c144
1 files changed, 72 insertions, 72 deletions
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index d3816ab..6b77c35 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -4152,32 +4152,87 @@ vrp_prop::finalize ()
}
}
+/* Blocks which have more than one predecessor and more than
+ one successor present jump threading opportunities, i.e.,
+ when the block is reached from a specific predecessor, we
+ may be able to determine which of the outgoing edges will
+ be traversed. When this optimization applies, we are able
+ to avoid conditionals at runtime and we may expose secondary
+ optimization opportunities.
+
+ This class is effectively a driver for the generic jump
+ threading code. It basically just presents the generic code
+ with edges that may be suitable for jump threading.
+
+ Unlike DOM, we do not iterate VRP if jump threading was successful.
+ While iterating may expose new opportunities for VRP, it is expected
+ those opportunities would be very limited and the compile time cost
+ to expose those opportunities would be significant.
+
+ As jump threading opportunities are discovered, they are registered
+ for later realization. */
+
class vrp_jump_threader : public dom_walker
{
public:
- vrp_jump_threader (cdi_direction direction,
- class const_and_copies *const_and_copies,
- class avail_exprs_stack *avail_exprs_stack)
- : dom_walker (direction, REACHABLE_BLOCKS),
- m_const_and_copies (const_and_copies),
- m_avail_exprs_stack (avail_exprs_stack),
- m_dummy_cond (NULL) {}
-
- virtual edge before_dom_children (basic_block);
- virtual void after_dom_children (basic_block);
+ vrp_jump_threader (struct function *, vr_values *);
+ ~vrp_jump_threader ();
- class vr_values *vr_values;
+ void thread_jumps ()
+ {
+ walk (m_fun->cfg->x_entry_block_ptr);
+ }
private:
static tree simplify_stmt (gimple *stmt, gimple *within_stmt,
avail_exprs_stack *, basic_block);
+ virtual edge before_dom_children (basic_block);
+ virtual void after_dom_children (basic_block);
- class const_and_copies *m_const_and_copies;
- class avail_exprs_stack *m_avail_exprs_stack;
-
+ function *m_fun;
+ vr_values *m_vr_values;
+ const_and_copies *m_const_and_copies;
+ avail_exprs_stack *m_avail_exprs_stack;
+ hash_table<expr_elt_hasher> *m_avail_exprs;
gcond *m_dummy_cond;
};
+vrp_jump_threader::vrp_jump_threader (struct function *fun, vr_values *v)
+ : dom_walker (CDI_DOMINATORS, REACHABLE_BLOCKS)
+{
+ /* Ugh. When substituting values earlier in this pass we can wipe
+ the dominance information. So rebuild the dominator information
+ as we need it within the jump threading code. */
+ calculate_dominance_info (CDI_DOMINATORS);
+
+ /* We do not allow VRP information to be used for jump threading
+ across a back edge in the CFG. Otherwise it becomes too
+ difficult to avoid eliminating loop exit tests. Of course
+ EDGE_DFS_BACK is not accurate at this time so we have to
+ recompute it. */
+ mark_dfs_back_edges ();
+
+ /* Allocate our unwinder stack to unwind any temporary equivalences
+ that might be recorded. */
+ m_const_and_copies = new const_and_copies ();
+
+ m_dummy_cond = NULL;
+ m_fun = fun;
+ m_vr_values = v;
+ m_avail_exprs = new hash_table<expr_elt_hasher> (1024);
+ m_avail_exprs_stack = new avail_exprs_stack (m_avail_exprs);
+}
+
+vrp_jump_threader::~vrp_jump_threader ()
+{
+ /* We do not actually update the CFG or SSA graphs at this point as
+ ASSERT_EXPRs are still in the IL and cfg cleanup code does not
+ yet handle ASSERT_EXPRs gracefully. */
+ delete m_const_and_copies;
+ delete m_avail_exprs;
+ delete m_avail_exprs_stack;
+}
+
/* Called before processing dominator children of BB. We want to look
at ASSERT_EXPRs and record information from them in the appropriate
tables.
@@ -4295,7 +4350,7 @@ vrp_jump_threader::after_dom_children (basic_block bb)
integer_zero_node, integer_zero_node,
NULL, NULL);
- x_vr_values = vr_values;
+ x_vr_values = m_vr_values;
thread_outgoing_edges (bb, m_dummy_cond, m_const_and_copies,
m_avail_exprs_stack, NULL,
simplify_stmt);
@@ -4305,62 +4360,6 @@ vrp_jump_threader::after_dom_children (basic_block bb)
m_const_and_copies->pop_to_marker ();
}
-/* Blocks which have more than one predecessor and more than
- one successor present jump threading opportunities, i.e.,
- when the block is reached from a specific predecessor, we
- may be able to determine which of the outgoing edges will
- be traversed. When this optimization applies, we are able
- to avoid conditionals at runtime and we may expose secondary
- optimization opportunities.
-
- This routine is effectively a driver for the generic jump
- threading code. It basically just presents the generic code
- with edges that may be suitable for jump threading.
-
- Unlike DOM, we do not iterate VRP if jump threading was successful.
- While iterating may expose new opportunities for VRP, it is expected
- those opportunities would be very limited and the compile time cost
- to expose those opportunities would be significant.
-
- As jump threading opportunities are discovered, they are registered
- for later realization. */
-
-static void
-identify_jump_threads (struct function *fun, class vr_values *vr_values)
-{
- /* Ugh. When substituting values earlier in this pass we can
- wipe the dominance information. So rebuild the dominator
- information as we need it within the jump threading code. */
- calculate_dominance_info (CDI_DOMINATORS);
-
- /* We do not allow VRP information to be used for jump threading
- across a back edge in the CFG. Otherwise it becomes too
- difficult to avoid eliminating loop exit tests. Of course
- EDGE_DFS_BACK is not accurate at this time so we have to
- recompute it. */
- mark_dfs_back_edges ();
-
- /* Allocate our unwinder stack to unwind any temporary equivalences
- that might be recorded. */
- const_and_copies *equiv_stack = new const_and_copies ();
-
- hash_table<expr_elt_hasher> *avail_exprs
- = new hash_table<expr_elt_hasher> (1024);
- avail_exprs_stack *avail_exprs_stack
- = new class avail_exprs_stack (avail_exprs);
-
- vrp_jump_threader walker (CDI_DOMINATORS, equiv_stack, avail_exprs_stack);
- walker.vr_values = vr_values;
- walker.walk (fun->cfg->x_entry_block_ptr);
-
- /* We do not actually update the CFG or SSA graphs at this point as
- ASSERT_EXPRs are still in the IL and cfg cleanup code does not yet
- handle ASSERT_EXPRs gracefully. */
- delete equiv_stack;
- delete avail_exprs;
- delete avail_exprs_stack;
-}
-
/* STMT is a conditional at the end of a basic block.
If the conditional is of the form SSA_NAME op constant and the SSA_NAME
@@ -4516,7 +4515,8 @@ execute_vrp (struct function *fun, bool warn_array_bounds_p)
/* We must identify jump threading opportunities before we release
the datastructures built by VRP. */
- identify_jump_threads (fun, &vrp_prop.vr_values);
+ vrp_jump_threader threader (fun, &vrp_prop.vr_values);
+ threader.thread_jumps ();
/* A comparison of an SSA_NAME against a constant where the SSA_NAME
was set by a type conversion can often be rewritten to use the