diff options
author | Aldy Hernandez <aldyh@redhat.com> | 2020-04-08 10:22:46 +0200 |
---|---|---|
committer | Aldy Hernandez <aldyh@redhat.com> | 2020-04-08 13:31:21 -0400 |
commit | 302ef01db3d2e078b064a1d4db5a694b3a6bde45 (patch) | |
tree | a86dbeea98e9a3280e2aeff2e9dc793023bda4f4 | |
parent | 9eac184417b02eede7fd909b4f61024a7d5d8e81 (diff) | |
download | gcc-302ef01db3d2e078b064a1d4db5a694b3a6bde45.zip gcc-302ef01db3d2e078b064a1d4db5a694b3a6bde45.tar.gz gcc-302ef01db3d2e078b064a1d4db5a694b3a6bde45.tar.bz2 |
Take into account PHI args in the loop_ranger.
-rw-r--r-- | gcc/gimple-range-cfg.h | 2 | ||||
-rw-r--r-- | gcc/gimple-ranger.cc | 97 | ||||
-rw-r--r-- | gcc/gimple-ranger.h | 12 |
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. |