aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2020-04-08 10:22:46 +0200
committerAldy Hernandez <aldyh@redhat.com>2020-04-08 13:31:21 -0400
commit302ef01db3d2e078b064a1d4db5a694b3a6bde45 (patch)
treea86dbeea98e9a3280e2aeff2e9dc793023bda4f4 /gcc
parent9eac184417b02eede7fd909b4f61024a7d5d8e81 (diff)
downloadgcc-302ef01db3d2e078b064a1d4db5a694b3a6bde45.zip
gcc-302ef01db3d2e078b064a1d4db5a694b3a6bde45.tar.gz
gcc-302ef01db3d2e078b064a1d4db5a694b3a6bde45.tar.bz2
Take into account PHI args in the loop_ranger.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/gimple-range-cfg.h2
-rw-r--r--gcc/gimple-ranger.cc97
-rw-r--r--gcc/gimple-ranger.h12
3 files changed, 76 insertions, 35 deletions
diff --git a/gcc/gimple-range-cfg.h b/gcc/gimple-range-cfg.h
index 373fe1e..747b0d7 100644
--- a/gcc/gimple-range-cfg.h
+++ b/gcc/gimple-range-cfg.h
@@ -30,9 +30,9 @@ public:
virtual void range_on_entry (irange &r, basic_block bb, tree name);
virtual void range_on_exit (irange &r, basic_block bb, tree name);
+ virtual bool range_of_phi (irange &r, gphi *phi);
protected:
bool range_of_range_op (irange &r, gimple *s);
- bool range_of_phi (irange &r, gphi *phi);
bool range_of_call (irange &r, gcall *call);
bool range_of_cond_expr (irange &r, gassign* cond);
private:
diff --git a/gcc/gimple-ranger.cc b/gcc/gimple-ranger.cc
index bb53ac9..bbd62a4 100644
--- a/gcc/gimple-ranger.cc
+++ b/gcc/gimple-ranger.cc
@@ -717,6 +717,9 @@ if (DEBUG_CACHE) fprintf (dump_file, "BACK visiting block %d\n", node->index);
iterative_cache_update (name);
}
+
+// loop_ranger implementation.
+
loop_ranger::loop_ranger ()
{
m_vr_values = new vr_values_tester;
@@ -727,51 +730,85 @@ loop_ranger::~loop_ranger ()
delete m_vr_values;
}
-// Adjust a PHI result with loop information.
-
void
-loop_ranger::adjust_phi_with_loop_info (irange &r, gphi *phi)
+loop_ranger::range_of_ssa_name_with_loop_info (irange &r, tree name,
+ class loop *l, gphi *phi)
+{
+ gcc_checking_assert (TREE_CODE (name) == SSA_NAME);
+ value_range_equiv vr;
+ vr.set_varying (TREE_TYPE (name));
+ m_vr_values->adjust_range_with_scev (&vr, l, phi, name);
+ vr.normalize_symbolics ();
+ r = vr;
+}
+
+// If NAME is either a PHI result or a PHI argument, see if we can
+// determine range information by querying loop info. If so, return
+// TRUE and set the range in R.
+
+bool
+loop_ranger::range_with_loop_info (irange &r, tree name)
{
- struct loop *l = loop_containing_stmt (phi);
- if (l && l->header == gimple_bb (phi))
+ if (!scev_initialized_p ())
+ return false;
+
+ gimple *def = SSA_NAME_DEF_STMT (name);
+ class loop *l = loop_containing_stmt (def);
+ if (!l)
+ return false;
+
+ basic_block header = l->header;
+ for (gphi_iterator iter = gsi_start_phis (header);
+ !gsi_end_p (iter); gsi_next (&iter))
{
- tree phi_result = PHI_RESULT (phi);
- value_range vl = r;
- value_range_equiv vr = vl;
- m_vr_values->adjust_range_with_scev (&vr, l, phi, phi_result);
- if (vr.constant_p ())
+ gphi *phi = iter.phi ();
+ if (PHI_RESULT (phi) == name)
{
- widest_irange old = r;
- r = vr;
- if (old != r
- && dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "LOOP_RANGER refined this PHI result: ");
- print_gimple_stmt (dump_file, phi, 0, TDF_SLIM);
- fprintf (dump_file, " from this range: ");
- old.dump (dump_file);
- fprintf (dump_file, "\n");
- fprintf (dump_file, " into this range: ");
- r.dump (dump_file);
- fprintf (dump_file, "\n");
- }
+ range_of_ssa_name_with_loop_info (r, name, l, phi);
+ return true;
}
+ for (size_t i = 0; i < gimple_phi_num_args (phi); ++i)
+ if (PHI_ARG_DEF (phi, i) == name)
+ {
+ range_of_ssa_name_with_loop_info (r, name, l, phi);
+ return true;
+ }
}
+ return false;
}
// Virtual override of global_ranger::range_of_phi() that adjusts the
// result with loop information if available.
bool
-loop_ranger::range_of_stmt (irange &r, gimple *s, tree name)
+loop_ranger::range_of_phi (irange &r, gphi *phi)
{
- bool result = global_ranger::range_of_stmt (r, s, name);
- if (result && is_a<gphi *> (s) && scev_initialized_p ())
- adjust_phi_with_loop_info (r, as_a<gphi *> (s));
- return result;
+ if (super::range_of_phi (r, phi))
+ {
+ value_range loop_range;
+ if (range_with_loop_info (loop_range, PHI_RESULT (phi)))
+ r.intersect (loop_range);
+ return true;
+ }
+ // ?? Is it worth querying loop info, or should we just return false?
+ return range_with_loop_info (r, PHI_RESULT (phi));
+}
+
+void
+loop_ranger::range_on_edge (irange &r, edge e, tree name)
+{
+ super::range_on_edge (r, e, name);
+
+ if (TREE_CODE (name) == SSA_NAME)
+ {
+ value_range loop_range;
+ if (range_with_loop_info (loop_range, name))
+ r.intersect (loop_range);
+ }
}
-// Constructor for trace_ranger.
+
+// trace_ranger implementation.
trace_ranger::trace_ranger ()
{
diff --git a/gcc/gimple-ranger.h b/gcc/gimple-ranger.h
index 575e670..f939253 100644
--- a/gcc/gimple-ranger.h
+++ b/gcc/gimple-ranger.h
@@ -58,7 +58,7 @@ protected:
virtual void range_of_ssa_name (irange &r, tree name, gimple *s = NULL);
bool range_from_import (irange &r, tree name, irange &import_range);
private:
- typedef gimple_ranger super; // Inherited from class for easy changing.
+ typedef gimple_ranger super;
bool non_null_deref_p (tree name, basic_block bb);
bool block_range (irange &r, basic_block bb, tree name, bool calc = true);
void dump_block (FILE *f, basic_block bb);
@@ -83,9 +83,13 @@ class loop_ranger : public global_ranger
public:
loop_ranger ();
~loop_ranger ();
- virtual bool range_of_stmt (irange &r, gimple *s, tree name = NULL_TREE);
+ virtual void range_on_edge (irange &r, edge e, tree name);
+ virtual bool range_of_phi (irange &r, gphi *phi);
private:
- void adjust_phi_with_loop_info (irange &r, gphi *phi);
+ typedef global_ranger super;
+ bool range_with_loop_info (irange &r, tree name);
+ void range_of_ssa_name_with_loop_info (irange &, tree, class loop *,
+ gphi *);
class vr_values *m_vr_values;
};
@@ -106,7 +110,7 @@ public:
protected:
virtual void range_of_ssa_name (irange &r, tree name, gimple *s = NULL);
private:
- typedef global_ranger super; // Inherited from class for easy changing.
+ typedef loop_ranger super;
static const unsigned bump = 2;
unsigned indent;
unsigned trace_count; // Current trace index count.