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:
Andrew MacLeod 2021-10-15 12:26:13 -04:00
parent b470227661
commit 434ebc1e08
3 changed files with 128 additions and 88 deletions

View File

@ -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);

View File

@ -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 =

View File

@ -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 */