public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/aldyh/heads/ranger-staging)] Audit/comment/cleamup gimple-range-edge
@ 2020-09-26  3:38 Andrew Macleod
  0 siblings, 0 replies; only message in thread
From: Andrew Macleod @ 2020-09-26  3:38 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:205e38144973c86bc888cd7dd2321b187dbe763f

commit 205e38144973c86bc888cd7dd2321b187dbe763f
Author: Andrew MacLeod <amacleod@redhat.com>
Date:   Fri Sep 25 23:37:38 2020 -0400

    Audit/comment/cleamup gimple-range-edge

Diff:
---
 gcc/gimple-range-edge.cc | 81 +++++++++++++++++++++++++-----------------------
 gcc/gimple-range-edge.h  | 15 ++++++++-
 2 files changed, 57 insertions(+), 39 deletions(-)

diff --git a/gcc/gimple-range-edge.cc b/gcc/gimple-range-edge.cc
index 4a4878722e8..b7c0603e136 100644
--- a/gcc/gimple-range-edge.cc
+++ b/gcc/gimple-range-edge.cc
@@ -32,6 +32,25 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-cfg.h"
 #include "gimple-range.h"
 
+// If there is a range control statment at the end of block BB, return it.
+// Otherwise return NULL.
+
+gimple *
+gimple_outgoing_range_stmt_p (basic_block bb)
+{
+  gimple_stmt_iterator gsi = gsi_last_nondebug_bb (bb);
+  if (!gsi_end_p (gsi))
+    {
+      gimple *s = gsi_stmt (gsi);
+      if (is_a<gcond *> (s) && gimple_range_handler (s))
+	return gsi_stmt (gsi);
+      gswitch *sw = dyn_cast<gswitch *> (s);
+      if (sw && irange::supports_type_p (TREE_TYPE (gimple_switch_index (sw))))
+	return gsi_stmt (gsi);
+    }
+  return NULL;
+}
+
 
 outgoing_range::outgoing_range ()
 {
@@ -44,6 +63,10 @@ outgoing_range::~outgoing_range ()
     delete m_edge_table;
 }
 
+
+// Get a range for a switch edge E from statement S and return it in R.
+// Use a cached value if it exists, or calculate it if not.
+
 bool
 outgoing_range::get_edge_range (irange &r, gimple *s, edge e)
 {
@@ -53,7 +76,7 @@ outgoing_range::get_edge_range (irange &r, gimple *s, edge e)
   // ADA currently has cases where the index is 64 bits and the case
   // arguments are  32 bit, causing a trap when we create a case_range.
   // Until this is resolved (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87798)
-  // punt on these switches.
+  // punt on switches where the labels dont match the argument.
   if (gimple_switch_num_labels (sw) > 1 && 
       TYPE_PRECISION (TREE_TYPE (CASE_LOW (gimple_switch_label (sw, 1)))) !=
       TYPE_PRECISION (TREE_TYPE (gimple_switch_index (sw))))
@@ -73,6 +96,8 @@ outgoing_range::get_edge_range (irange &r, gimple *s, edge e)
   return true;
 }
 
+
+// calculate all switch edges from SW and cache them in the hash table.
 void
 outgoing_range::calc_switch_ranges (gswitch *sw)
 {
@@ -83,11 +108,14 @@ outgoing_range::calc_switch_ranges (gswitch *sw)
   
   edge default_edge = gimple_switch_default_edge (cfun, sw);
   irange *&default_slot = m_edge_table->get_or_insert (default_edge, &existed);
+
   // This should be the first call into this switch.
   // For the default range case, start with varying and intersect each other 
   // case from it. 
+
   gcc_assert (!existed);
-  // Allocatea int_range_max for default case.
+
+  // Allocate an int_range_max for default case.
   default_slot = range_pool.allocate (255);
   default_slot->set_varying (type);
 
@@ -97,14 +125,14 @@ outgoing_range::calc_switch_ranges (gswitch *sw)
 
       // If this edge is the same as the default edge, do nothing else.
       if (e == default_edge)
-        continue;
+	continue;
 
       tree low = CASE_LOW (gimple_switch_label (sw, x));
       tree high = CASE_HIGH (gimple_switch_label (sw, x));
       if (!high)
 	high = low;
 
-      // intersect the case from the default case.
+      // Remove the case range from the default case.
       int_range_max def_range (low, high);
       range_cast (def_range, type);
       def_range.invert ();
@@ -115,42 +143,22 @@ outgoing_range::calc_switch_ranges (gswitch *sw)
       range_cast (case_range, type);
       irange *&slot = m_edge_table->get_or_insert (e, &existed);
       if (existed)
-	case_range.union_ (*slot);
-      // If there was an existing range, we lose the memory, but it'll get
-      // reclaimed when the obstack is freed.  This seems less intrusive than
-      // allocating max ranges for each case.
+	{
+	  case_range.union_ (*slot);
+	  if (slot->fits_p (case_range))
+	    {
+	      *slot = case_range;
+	      continue;
+	    }
+	}
+      // If there was an existing range and it doesn't fit, we lose the memory.
+      // it'll get reclaimed when the obstack is freed.  This seems less
+      // intrusive than allocating max ranges for each case.
       slot = range_pool.allocate (case_range);
     }
 }
 
 
-// If there is a range control statment at the end of block BB, return it.
-
-static inline gimple_stmt_iterator
-gsi_outgoing_range_stmt (basic_block bb)
-{
-  gimple_stmt_iterator gsi = gsi_last_nondebug_bb (bb);
-  if (!gsi_end_p (gsi))
-    {
-      gimple *s = gsi_stmt (gsi);
-      if (is_a<gcond *> (s) && gimple_range_handler (s))
-	return gsi;
-      gswitch *sw = dyn_cast<gswitch *> (s);
-      if (sw && irange::supports_type_p (TREE_TYPE (gimple_switch_index (sw))))
-	return gsi;
-    }
-  return gsi_none ();
-}
-
-// If there is a range control statment at the end of block BB, return it.
-gimple *
-gimple_outgoing_range_stmt_p (basic_block bb)
-{
-  // This will return NULL if there is not a branch statement.
-  gimple *stmt = gsi_stmt (gsi_outgoing_range_stmt (bb));
-  return stmt;
-}
-
 // Calculate the range forced on on edge E by control flow, return it
 // in R.  Return the statment which defines the range, otherwise
 // return NULL
@@ -186,6 +194,3 @@ outgoing_range::edge_range_p (irange &r, edge e)
 
   return NULL;
 }
-
-
-
diff --git a/gcc/gimple-range-edge.h b/gcc/gimple-range-edge.h
index 82a1aec49a7..6e161306c06 100644
--- a/gcc/gimple-range-edge.h
+++ b/gcc/gimple-range-edge.h
@@ -22,6 +22,19 @@ along with GCC; see the file COPYING3.  If not see
 #ifndef GIMPLE_RANGE_EDGE_H
 #define GIMPLE_RANGE_EDGE_H
 
+// This class is used to query ranges on constant edges in GIMPLE.
+//
+// For a COND_EXPR,  the TRUE edge will return [1,1] and the false edge a [0,0].
+//
+// For SWITCH_EXPR it is awkward to calculate ranges. When a request
+// is made, the entire switch is evalauted and the results cached. 
+// Any future requests to that switch will use the cached value, providing
+// dramatic decrease in computation time.
+//
+// The API is simple. just ask for the range on the edge.
+// The return value is NULL for no range, or the branch statement which the
+// edge gets the range from, along with the range.
+
 class outgoing_range
 {
 public:
@@ -36,7 +49,7 @@ private:
   irange_pool range_pool;
 }; 
 
-
+// If there is a range control statment at the end of block BB, return it.
 gimple *gimple_outgoing_range_stmt_p (basic_block bb);
 
 #endif  // GIMPLE_RANGE_EDGE_H


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2020-09-26  3:38 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-26  3:38 [gcc(refs/users/aldyh/heads/ranger-staging)] Audit/comment/cleamup gimple-range-edge Andrew Macleod

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).