With the earlier rework of VRP which removed the array_bounds pass, it
is now possible to invoke a different VRP for any pass. This patch adds
the ability to call fast_vrp with the final_pass flag set, and remove
invoke the remove_unreachable object to remove __builtin_unreachable
calls if it is the final pass.
Bootstraps on x86_64-pc-linux-gnu with no regressions. Pushed.
Andrew
From 82c704c69fab610afcf4a1947577ed97dd72c429 Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <amacl...@redhat.com>
Date: Mon, 17 Jun 2024 11:23:12 -0400
Subject: [PATCH 1/5] Add builtin_unreachable processing for fast_vrp.
Add a remove_unreachable object to fast vrp, and honor the final_p flag.
* tree-vrp.cc (remove_unreachable::remove): Export global range
if builtin_unreachable dominates all uses.
(remove_unreachable::remove_and_update_globals): Do not reset SCEV.
(execute_ranger_vrp): Reset SCEV here instead.
(fvrp_folder::fvrp_folder): Take final pass flag
and create a remove_unreachable object when specified.
(fvrp_folder::pre_fold_stmt): Register GIMPLE_CONDs with
the remove_unreachcable object.
(fvrp_folder::m_unreachable): New.
(execute_fast_vrp): Process remove_unreachable object.
(pass_vrp::execute): Add final_p flag to execute_fast_vrp.
---
gcc/tree-vrp.cc | 52 ++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 41 insertions(+), 11 deletions(-)
diff --git a/gcc/tree-vrp.cc b/gcc/tree-vrp.cc
index 5f5eb9b57e9..a3b1a5cd337 100644
--- a/gcc/tree-vrp.cc
+++ b/gcc/tree-vrp.cc
@@ -280,6 +280,25 @@ remove_unreachable::remove ()
gimple *s = gimple_outgoing_range_stmt_p (e->src);
gcc_checking_assert (gimple_code (s) == GIMPLE_COND);
+ tree name = gimple_range_ssa_p (gimple_cond_lhs (s));
+ if (!name)
+ name = gimple_range_ssa_p (gimple_cond_rhs (s));
+ // Check if global value can be set for NAME.
+ if (name && fully_replaceable (name, src))
+ {
+ value_range r (TREE_TYPE (name));
+ if (gori_name_on_edge (r, name, e, &m_ranger)
+ && set_range_info (name, r) &&(dump_file))
+ {
+ fprintf (dump_file, "Global Exported (via unreachable): ");
+ print_generic_expr (dump_file, name, TDF_SLIM);
+ fprintf (dump_file, " = ");
+ gimple_range_global (r, name);
+ r.dump (dump_file);
+ fputc ('\n', dump_file);
+ }
+ }
+
change = true;
// Rewrite the condition.
if (e->flags & EDGE_TRUE_VALUE)
@@ -305,14 +324,10 @@ remove_unreachable::remove_and_update_globals ()
if (m_list.length () == 0)
return false;
- // If there is no import/export info, just remove unreachables if necessary.
+ // If there is no import/export info, Do basic removal.
if (!m_ranger.gori_ssa ())
return remove ();
- // Ensure the cache in SCEV has been cleared before processing
- // globals to be removed.
- scev_reset ();
-
bool change = false;
tree name;
unsigned i;
@@ -1107,6 +1122,9 @@ execute_ranger_vrp (struct function *fun, bool final_p)
rvrp_folder folder (ranger, final_p);
phi_analysis_initialize (ranger->const_query ());
folder.substitute_and_fold ();
+ // Ensure the cache in SCEV has been cleared before processing
+ // globals to be removed.
+ scev_reset ();
// Remove tagged builtin-unreachable and maybe update globals.
folder.m_unreachable.remove_and_update_globals ();
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -1168,9 +1186,15 @@ execute_ranger_vrp (struct function *fun, bool final_p)
class fvrp_folder : public substitute_and_fold_engine
{
public:
- fvrp_folder (dom_ranger *dr) : substitute_and_fold_engine (),
- m_simplifier (dr)
- { m_dom_ranger = dr; }
+ fvrp_folder (dom_ranger *dr, bool final_p) : substitute_and_fold_engine (),
+ m_simplifier (dr)
+ {
+ m_dom_ranger = dr;
+ if (final_p)
+ m_unreachable = new remove_unreachable (*dr, final_p);
+ else
+ m_unreachable = NULL;
+ }
~fvrp_folder () { }
@@ -1228,6 +1252,9 @@ public:
value_range vr(type);
m_dom_ranger->range_of_stmt (vr, s);
}
+ if (m_unreachable && gimple_code (s) == GIMPLE_COND)
+ m_unreachable->maybe_register (s);
+
}
bool fold_stmt (gimple_stmt_iterator *gsi) override
@@ -1238,6 +1265,7 @@ public:
return ret;
}
+ remove_unreachable *m_unreachable;
private:
DISABLE_COPY_AND_ASSIGN (fvrp_folder);
simplify_using_ranges m_simplifier;
@@ -1248,16 +1276,18 @@ private:
// Main entry point for a FAST VRP pass using a dom ranger.
unsigned int
-execute_fast_vrp (struct function *fun)
+execute_fast_vrp (struct function *fun, bool final_p)
{
calculate_dominance_info (CDI_DOMINATORS);
dom_ranger dr;
- fvrp_folder folder (&dr);
+ fvrp_folder folder (&dr, final_p);
gcc_checking_assert (!fun->x_range_query);
fun->x_range_query = &dr;
folder.substitute_and_fold ();
+ if (folder.m_unreachable)
+ folder.m_unreachable->remove ();
fun->x_range_query = NULL;
return 0;
@@ -1325,7 +1355,7 @@ public:
{
// Check for fast vrp.
if (&data == &pass_data_fast_vrp)
- return execute_fast_vrp (fun);
+ return execute_fast_vrp (fun, final_p);
return execute_ranger_vrp (fun, final_p);
}
--
2.45.0