Move ranger only VRP folder to tree-vrp.
Consolidate the RVRP folder into a single "execute_vrp" routine that mimics the format used by the vrp1 and vrp2 passes. Relocate into the tree-vrp file. * gimple-ssa-evrp.c (class rvrp_folder): Move to tree-vrp.c. (execute_early_vrp): For ranger only mode, invoke ranger_vrp. * tree-vrp.c (class rvrp_folder): Relocate here. (execute_ranger_vrp): New. * tree-vrp.h (execute_ranger_vrp): Export.
This commit is contained in:
parent
b470227661
commit
434ebc1e08
|
@ -44,6 +44,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "gimple-range.h"
|
||||
#include "fold-const.h"
|
||||
#include "value-pointer-equiv.h"
|
||||
#include "tree-vrp.h"
|
||||
|
||||
// This is the classic EVRP folder which uses a dominator walk and pushes
|
||||
// ranges into the next block if it is a single predecessor block.
|
||||
|
@ -110,88 +111,6 @@ protected:
|
|||
simplify_using_ranges simplifier;
|
||||
};
|
||||
|
||||
// This is a ranger based folder which continues to use the dominator
|
||||
// walk to access the substitute and fold machinery. Ranges are calculated
|
||||
// on demand.
|
||||
|
||||
class rvrp_folder : public substitute_and_fold_engine
|
||||
{
|
||||
public:
|
||||
|
||||
rvrp_folder () : substitute_and_fold_engine (), m_simplifier ()
|
||||
{
|
||||
m_ranger = enable_ranger (cfun);
|
||||
m_simplifier.set_range_query (m_ranger, m_ranger->non_executable_edge_flag);
|
||||
m_pta = new pointer_equiv_analyzer (m_ranger);
|
||||
}
|
||||
|
||||
~rvrp_folder ()
|
||||
{
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
m_ranger->dump (dump_file);
|
||||
|
||||
m_ranger->export_global_ranges ();
|
||||
disable_ranger (cfun);
|
||||
delete m_pta;
|
||||
}
|
||||
|
||||
tree value_of_expr (tree name, gimple *s = NULL) OVERRIDE
|
||||
{
|
||||
// Shortcircuit subst_and_fold callbacks for abnormal ssa_names.
|
||||
if (TREE_CODE (name) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name))
|
||||
return NULL;
|
||||
tree ret = m_ranger->value_of_expr (name, s);
|
||||
if (!ret && supported_pointer_equiv_p (name))
|
||||
ret = m_pta->get_equiv (name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
tree value_on_edge (edge e, tree name) OVERRIDE
|
||||
{
|
||||
// Shortcircuit subst_and_fold callbacks for abnormal ssa_names.
|
||||
if (TREE_CODE (name) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name))
|
||||
return NULL;
|
||||
tree ret = m_ranger->value_on_edge (e, name);
|
||||
if (!ret && supported_pointer_equiv_p (name))
|
||||
ret = m_pta->get_equiv (name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
tree value_of_stmt (gimple *s, tree name = NULL) OVERRIDE
|
||||
{
|
||||
// Shortcircuit subst_and_fold callbacks for abnormal ssa_names.
|
||||
if (TREE_CODE (name) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name))
|
||||
return NULL;
|
||||
return m_ranger->value_of_stmt (s, name);
|
||||
}
|
||||
|
||||
void pre_fold_bb (basic_block bb) OVERRIDE
|
||||
{
|
||||
m_pta->enter (bb);
|
||||
}
|
||||
|
||||
void post_fold_bb (basic_block bb) OVERRIDE
|
||||
{
|
||||
m_pta->leave (bb);
|
||||
}
|
||||
|
||||
void pre_fold_stmt (gimple *stmt) OVERRIDE
|
||||
{
|
||||
m_pta->visit_stmt (stmt);
|
||||
}
|
||||
|
||||
bool fold_stmt (gimple_stmt_iterator *gsi) OVERRIDE
|
||||
{
|
||||
return m_simplifier.simplify (gsi);
|
||||
}
|
||||
|
||||
private:
|
||||
DISABLE_COPY_AND_ASSIGN (rvrp_folder);
|
||||
gimple_ranger *m_ranger;
|
||||
simplify_using_ranges m_simplifier;
|
||||
pointer_equiv_analyzer *m_pta;
|
||||
};
|
||||
|
||||
// In a hybrid folder, start with an EVRP folder, and add the required
|
||||
// fold_stmt bits to either try the ranger first or second.
|
||||
//
|
||||
|
@ -393,6 +312,9 @@ hybrid_folder::choose_value (tree evrp_val, tree ranger_val)
|
|||
static unsigned int
|
||||
execute_early_vrp ()
|
||||
{
|
||||
if ((param_evrp_mode & EVRP_MODE_RVRP_FIRST) == EVRP_MODE_RVRP_ONLY)
|
||||
return execute_ranger_vrp (cfun, false);
|
||||
|
||||
/* Ideally this setup code would move into the ctor for the folder
|
||||
However, this setup can change the number of blocks which
|
||||
invalidates the internal arrays that are set up by the dominator
|
||||
|
@ -411,12 +333,6 @@ execute_early_vrp ()
|
|||
folder.substitute_and_fold ();
|
||||
break;
|
||||
}
|
||||
case EVRP_MODE_RVRP_ONLY:
|
||||
{
|
||||
rvrp_folder folder;
|
||||
folder.substitute_and_fold ();
|
||||
break;
|
||||
}
|
||||
case EVRP_MODE_EVRP_FIRST:
|
||||
{
|
||||
hybrid_folder folder (true);
|
||||
|
|
122
gcc/tree-vrp.c
122
gcc/tree-vrp.c
|
@ -49,6 +49,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "gimple-array-bounds.h"
|
||||
#include "gimple-range.h"
|
||||
#include "gimple-range-path.h"
|
||||
#include "value-pointer-equiv.h"
|
||||
|
||||
/* Set of SSA names found live during the RPO traversal of the function
|
||||
for still active basic-blocks. */
|
||||
|
@ -4313,6 +4314,127 @@ execute_vrp (struct function *fun, bool warn_array_bounds_p)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// This is a ranger based folder which continues to use the dominator
|
||||
// walk to access the substitute and fold machinery. Ranges are calculated
|
||||
// on demand.
|
||||
|
||||
class rvrp_folder : public substitute_and_fold_engine
|
||||
{
|
||||
public:
|
||||
|
||||
rvrp_folder (gimple_ranger *r) : substitute_and_fold_engine (),
|
||||
m_simplifier (r, r->non_executable_edge_flag)
|
||||
{
|
||||
m_ranger = r;
|
||||
m_pta = new pointer_equiv_analyzer (m_ranger);
|
||||
}
|
||||
|
||||
~rvrp_folder ()
|
||||
{
|
||||
delete m_pta;
|
||||
}
|
||||
|
||||
tree value_of_expr (tree name, gimple *s = NULL) OVERRIDE
|
||||
{
|
||||
// Shortcircuit subst_and_fold callbacks for abnormal ssa_names.
|
||||
if (TREE_CODE (name) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name))
|
||||
return NULL;
|
||||
tree ret = m_ranger->value_of_expr (name, s);
|
||||
if (!ret && supported_pointer_equiv_p (name))
|
||||
ret = m_pta->get_equiv (name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
tree value_on_edge (edge e, tree name) OVERRIDE
|
||||
{
|
||||
// Shortcircuit subst_and_fold callbacks for abnormal ssa_names.
|
||||
if (TREE_CODE (name) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name))
|
||||
return NULL;
|
||||
tree ret = m_ranger->value_on_edge (e, name);
|
||||
if (!ret && supported_pointer_equiv_p (name))
|
||||
ret = m_pta->get_equiv (name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
tree value_of_stmt (gimple *s, tree name = NULL) OVERRIDE
|
||||
{
|
||||
// Shortcircuit subst_and_fold callbacks for abnormal ssa_names.
|
||||
if (TREE_CODE (name) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name))
|
||||
return NULL;
|
||||
return m_ranger->value_of_stmt (s, name);
|
||||
}
|
||||
|
||||
void pre_fold_bb (basic_block bb) OVERRIDE
|
||||
{
|
||||
m_pta->enter (bb);
|
||||
}
|
||||
|
||||
void post_fold_bb (basic_block bb) OVERRIDE
|
||||
{
|
||||
m_pta->leave (bb);
|
||||
}
|
||||
|
||||
void pre_fold_stmt (gimple *stmt) OVERRIDE
|
||||
{
|
||||
m_pta->visit_stmt (stmt);
|
||||
}
|
||||
|
||||
bool fold_stmt (gimple_stmt_iterator *gsi) OVERRIDE
|
||||
{
|
||||
return m_simplifier.simplify (gsi);
|
||||
}
|
||||
|
||||
private:
|
||||
DISABLE_COPY_AND_ASSIGN (rvrp_folder);
|
||||
gimple_ranger *m_ranger;
|
||||
simplify_using_ranges m_simplifier;
|
||||
pointer_equiv_analyzer *m_pta;
|
||||
};
|
||||
|
||||
/* Main entry point for a VRP pass using just ranger. This can be called
|
||||
from anywhere to perform a VRP pass, including from EVRP. */
|
||||
|
||||
unsigned int
|
||||
execute_ranger_vrp (struct function *fun, bool warn_array_bounds_p)
|
||||
{
|
||||
loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
|
||||
rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
|
||||
scev_initialize ();
|
||||
calculate_dominance_info (CDI_DOMINATORS);
|
||||
|
||||
gimple_ranger *ranger = enable_ranger (fun);
|
||||
rvrp_folder folder (ranger);
|
||||
folder.substitute_and_fold ();
|
||||
ranger->export_global_ranges ();
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
ranger->dump (dump_file);
|
||||
|
||||
|
||||
if (warn_array_bounds && warn_array_bounds_p)
|
||||
{
|
||||
// Set all edges as executable, except those ranger says aren't.
|
||||
int non_exec_flag = ranger->non_executable_edge_flag;
|
||||
basic_block bb;
|
||||
FOR_ALL_BB_FN (bb, fun)
|
||||
{
|
||||
edge_iterator ei;
|
||||
edge e;
|
||||
FOR_EACH_EDGE (e, ei, bb->succs)
|
||||
if (e->flags & non_exec_flag)
|
||||
e->flags &= ~EDGE_EXECUTABLE;
|
||||
else
|
||||
e->flags |= EDGE_EXECUTABLE;
|
||||
}
|
||||
array_bounds_checker array_checker (fun, ranger);
|
||||
array_checker.check ();
|
||||
}
|
||||
|
||||
disable_ranger (fun);
|
||||
scev_finalize ();
|
||||
loop_optimizer_finalize ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
const pass_data pass_data_vrp =
|
||||
|
|
|
@ -65,4 +65,6 @@ extern void maybe_set_nonzero_bits (edge, tree);
|
|||
extern wide_int masked_increment (const wide_int &val_in, const wide_int &mask,
|
||||
const wide_int &sgnbit, unsigned int prec);
|
||||
|
||||
extern unsigned int execute_ranger_vrp (struct function *fun,
|
||||
bool warn_array_bounds_p = false);
|
||||
#endif /* GCC_TREE_VRP_H */
|
||||
|
|
Loading…
Reference in New Issue