/* Support routines for Value Range Propagation (VRP).
- Copyright (C) 2005-2017 Free Software Foundation, Inc.
+ Copyright (C) 2005-2019 Free Software Foundation, Inc.
This file is part of GCC.
public:
tree get_value (tree) FINAL OVERRIDE;
evrp_folder (class vr_values *vr_values_) : vr_values (vr_values_) { }
+ bool simplify_stmt_using_ranges (gimple_stmt_iterator *gsi)
+ { return vr_values->simplify_stmt_using_ranges (gsi); }
class vr_values *vr_values;
private:
public:
evrp_dom_walker ()
: dom_walker (CDI_DOMINATORS),
+ evrp_range_analyzer (true),
evrp_folder (evrp_range_analyzer.get_vr_values ())
{
need_eh_cleanup = BITMAP_ALLOC (NULL);
value_range *vr = evrp_range_analyzer.get_value_range (lhs);
/* Mark PHIs whose lhs we fully propagate for removal. */
- tree val = value_range_constant_singleton (vr);
- if (val && may_propagate_copy (lhs, val))
+ tree val;
+ if (vr->singleton_p (&val) && may_propagate_copy (lhs, val))
{
stmts_to_remove.safe_push (phi);
continue;
print_gimple_stmt (dump_file, stmt, 0);
}
- evrp_range_analyzer.record_ranges_from_stmt (stmt);
+ evrp_range_analyzer.record_ranges_from_stmt (stmt, false);
if (gcond *cond = dyn_cast <gcond *> (stmt))
{
value_range *vr = evrp_range_analyzer.get_value_range (output);
/* Mark stmts whose output we fully propagate for removal. */
- if ((vr->type == VR_RANGE || vr->type == VR_ANTI_RANGE)
- && (val = value_range_constant_singleton (vr))
+ if (vr->singleton_p (&val)
&& may_propagate_copy (output, val)
- && !stmt_could_throw_p (stmt)
+ && !stmt_could_throw_p (cfun, stmt)
&& !gimple_has_side_effects (stmt))
{
stmts_to_remove.safe_push (stmt);
/* Try folding stmts with the VR discovered. */
bool did_replace = evrp_folder.replace_uses_in (stmt);
+ gimple_stmt_iterator prev_gsi = gsi;
+ gsi_prev (&prev_gsi);
if (fold_stmt (&gsi, follow_single_use_edges)
|| did_replace)
{
update_stmt (stmt);
did_replace = true;
}
+ if (evrp_folder.simplify_stmt_using_ranges (&gsi))
+ {
+ stmt = gsi_stmt (gsi);
+ update_stmt (stmt);
+ did_replace = true;
+ }
if (did_replace)
{
+ /* If we wound up generating new stmts during folding
+ drop all their defs to VARYING. We can't easily
+ process them because we've already instantiated
+ ranges on uses on STMT that only hold after it. */
+ if (gsi_end_p (prev_gsi))
+ prev_gsi = gsi_start_bb (bb);
+ else
+ gsi_next (&prev_gsi);
+ while (gsi_stmt (prev_gsi) != gsi_stmt (gsi))
+ {
+ evrp_range_analyzer.get_vr_values ()
+ ->set_defs_to_varying (gsi_stmt (prev_gsi));
+ gsi_next (&prev_gsi);
+ }
+
/* If we cleaned up EH information from the statement,
remove EH edges. */
if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt))
|| virtual_operand_p (arg))
continue;
value_range *vr = evrp_range_analyzer.get_value_range (arg);
- tree val = value_range_constant_singleton (vr);
- if (val && may_propagate_copy (arg, val))
+ tree val;
+ if (vr->singleton_p (&val) && may_propagate_copy (arg, val))
propagate_value (use_p, val);
}
}
gimple *stmt = stmts_to_fixup.pop ();
fixup_noreturn_call (stmt);
}
+
+ evrp_folder.vr_values->cleanup_edges_and_switches ();
}
/* Main entry point for the early vrp pass which is a simplified non-iterative