From fd7cf6bd6a2ad7f000c6f21082cf462408aea3eb Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Tue, 13 Oct 2020 14:53:12 -0400
Subject: [PATCH 49/49] FIXME: hacked up paths-for-ranges experiment

---
 gcc/c/c-objc-common.c        | 16 +++++++++++++++
 gcc/gimple-range.cc          | 28 +++++++++++++++++++++++++-
 gcc/gimple-range.h           |  5 ++++-
 gcc/gimple-ssa-warn-alloca.c | 29 ++++++++++++++++++++++++++-
 gcc/value-range.cc           | 38 ++++++++++++++++++++++++++++++++++++
 gcc/value-range.h            |  1 +
 6 files changed, 114 insertions(+), 3 deletions(-)

diff --git a/gcc/c/c-objc-common.c b/gcc/c/c-objc-common.c
index 378288fb5e1..6bc2097eb38 100644
--- a/gcc/c/c-objc-common.c
+++ b/gcc/c/c-objc-common.c
@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gcc-rich-location.h"
 #include "stringpool.h"
 #include "attribs.h"
+#include "value-range.h"
 
 static bool c_tree_printer (pretty_printer *, text_info *, const char *,
 			    int, bool, bool, bool, bool *, const char **);
@@ -247,6 +248,7 @@ print_type (c_pretty_printer *cpp, tree t, bool *quoted)
    %V: a list of type qualifiers from a tree.
    %v: an explicit list of type qualifiers
    %#v: an explicit list of type qualifiers of a function type.
+   %!: int and const irange *
 
    Please notice when called, the `%' part was already skipped by the
    diagnostic machinery.  */
@@ -276,6 +278,20 @@ c_tree_printer (pretty_printer *pp, text_info *text, const char *spec,
       return true;
     }
 
+  if (*spec == '!')
+    {
+      int res = va_arg (*text->args_ptr, int);
+      const irange *r = va_arg (*text->args_ptr, const irange *);
+      if (res)
+	{
+	  pp_string (pp, "TRUE: ");
+	  r->dump_to_pp (pp);
+	}
+      else
+	pp_string (pp, "FALSE");
+      return true;
+    }
+
   if (*spec != 'v')
     {
       t = va_arg (*text->args_ptr, tree);
diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc
index c5520e0700b..28d18413030 100644
--- a/gcc/gimple-range.cc
+++ b/gcc/gimple-range.cc
@@ -1170,7 +1170,8 @@ gimple_ranger::range_of_ssa_name_with_loop_info (irange &r, tree name,
 // trace_ranger implementation.
 
 
-trace_ranger::trace_ranger ()
+trace_ranger::trace_ranger (simple_diagnostic_path *out_path)
+: m_out_path (out_path)
 {
   indent = 0;
   trace_count = 0;
@@ -1243,6 +1244,11 @@ trace_ranger::range_on_edge (irange &r, edge e, tree name)
 
   bool res = gimple_ranger::range_on_edge (r, e, name);
   trailer (idx, "range_on_edge", true, name, r);
+
+  if (m_out_path)
+    m_out_path->add_event (UNKNOWN_LOCATION, NULL, 0,
+			   "range_on_edge(%qE): %!", name, (int)res, &r);
+
   return res;
 }
 
@@ -1262,6 +1268,11 @@ trace_ranger::range_on_entry (irange &r, basic_block bb, tree name)
 
   gimple_ranger::range_on_entry (r, bb, name);
 
+  if (m_out_path)
+    m_out_path->add_event (UNKNOWN_LOCATION, NULL, 0,
+			   "range_on_entry(%qE) to BB %d: %!",
+			   name, bb->index, 1, &r);
+
   trailer (idx, "range_on_entry", true, name, r);
 }
 
@@ -1281,6 +1292,11 @@ trace_ranger::range_on_exit (irange &r, basic_block bb, tree name)
 
   gimple_ranger::range_on_exit (r, bb, name);
 
+  if (m_out_path)
+    m_out_path->add_event (UNKNOWN_LOCATION, NULL, 0,
+			   "range_on_exit(%qE) from BB %d: %!",
+			   name, bb->index, 1, &r);
+
   trailer (idx, "range_on_exit", true, name, r);
 }
 
@@ -1303,6 +1319,11 @@ trace_ranger::range_of_stmt (irange &r, gimple *s, tree name)
 
   res = gimple_ranger::range_of_stmt (r, s, name);
 
+  if (m_out_path)
+    m_out_path->add_event (s->location, NULL, 0,
+			   "range_of_stmt(%qE): %!",
+			   name, (int)res, &r);
+
   return trailer (idx, "range_of_stmt", res, name, r);
 }
 
@@ -1330,5 +1351,10 @@ trace_ranger::range_of_expr (irange &r, tree name, gimple *s)
 
   res = gimple_ranger::range_of_expr (r, name, s);
 
+  if (m_out_path)
+    m_out_path->add_event (s->location, NULL, 0,
+			   "range_of_expr(%qE): %!",
+			   name, (int)res, &r);
+
   return trailer (idx, "range_of_expr", res, name, r);
 }
diff --git a/gcc/gimple-range.h b/gcc/gimple-range.h
index 0aa6d4672ee..907e1b2f6a9 100644
--- a/gcc/gimple-range.h
+++ b/gcc/gimple-range.h
@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple-range-gori.h"
 #include "gimple-range-cache.h"
 #include "value-query.h"
+#include "diagnostic-path.h"
 
 // This is the basic range generator interface.
 //
@@ -159,7 +160,7 @@ gimple_range_global (tree name)
 class trace_ranger : public gimple_ranger
 {
 public:
-  trace_ranger ();
+  trace_ranger (simple_diagnostic_path *out_path = NULL);
   virtual bool range_of_stmt (irange &r, gimple *s, tree name = NULL_TREE);
   virtual bool range_of_expr (irange &r, tree name, gimple *s = NULL);
   virtual bool range_on_edge (irange &r, edge e, tree name);
@@ -173,6 +174,8 @@ private:
   bool dumping (unsigned counter, bool trailing = false);
   bool trailer (unsigned counter, const char *caller, bool result, tree name,
 		const irange &r);
+
+  simple_diagnostic_path *m_out_path;
 };
 
 // Flag to enable debugging the various internal Caches.
diff --git a/gcc/gimple-ssa-warn-alloca.c b/gcc/gimple-ssa-warn-alloca.c
index 33824a7a091..110adfa03f7 100644
--- a/gcc/gimple-ssa-warn-alloca.c
+++ b/gcc/gimple-ssa-warn-alloca.c
@@ -28,6 +28,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "ssa.h"
 #include "gimple-pretty-print.h"
 #include "diagnostic-core.h"
+#include "diagnostic-path.h"
+#include "gcc-rich-location.h"
 #include "fold-const.h"
 #include "gimple-iterator.h"
 #include "tree-ssa.h"
@@ -255,6 +257,28 @@ in_loop_p (gimple *stmt)
     bb->loop_father && bb->loop_father->header != ENTRY_BLOCK_PTR_FOR_FN (cfun);
 }
 
+/* FIXME.  */
+
+class ranger_rich_location : public gcc_rich_location
+{
+ public:
+  ranger_rich_location (location_t loc)
+  : gcc_rich_location (loc),
+    m_pp (global_dc->printer->clone ()),
+    m_path (m_pp)
+  {
+    set_path (&m_path);
+  }
+  ~ranger_rich_location ()
+  {
+    delete m_pp; // FIXME: cloning and deleting is inefficient
+  }
+
+  // TODO:
+  pretty_printer *m_pp;
+  simple_diagnostic_path m_path;
+};
+
 unsigned int
 pass_walloca::execute (function *fun)
 {
@@ -319,7 +343,10 @@ pass_walloca::execute (function *fun)
 	    case ALLOCA_BOUND_MAYBE_LARGE:
 	      {
 		auto_diagnostic_group d;
-		if (warning_at (loc, wcode,
+		ranger_rich_location richloc (loc);
+		trace_ranger trace_ranger (&richloc.m_path);
+		alloca_call_type (trace_ranger, stmt, is_vla);
+		if (warning_at (&richloc, wcode,
 				(is_vla
 				 ? G_("%Gargument to variable-length "
 				      "array may be too large")
diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index 7847104050c..eb55ae732c6 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -1978,6 +1978,44 @@ debug (const value_range &vr)
   fprintf (stderr, "\n");
 }
 
+void
+irange::dump_to_pp (pretty_printer *pp) const
+{
+  if (undefined_p ())
+    {
+      pp_string (pp, "UNDEFINED");
+      return;
+    }
+  //TODO: (printing not reentrant): print_generic_expr (file, type ());
+  pp_space (pp);
+  if (varying_p ())
+    {
+      pp_string (pp, "VARYING");
+      return;
+    }
+#if 0
+ if (legacy_mode_p ())
+    {
+      fprintf (file, "%s[", (m_kind == VR_ANTI_RANGE) ? "~" : "");
+      dump_bound_with_infinite_markers (file, min ());
+      fprintf (file, ", ");
+      dump_bound_with_infinite_markers (file, max ());
+      fprintf (file, "]");
+      return;
+    }
+ #endif
+  for (unsigned i = 0; i < m_num_ranges; ++i)
+    {
+      tree lb = m_base[i * 2];
+      tree ub = m_base[i * 2 + 1];
+      pp_string (pp, "[");
+      //TODO: dump_bound_with_infinite_markers (file, lb);
+      pp_string (pp, ", ");
+      //TODO: dump_bound_with_infinite_markers (file, ub);
+      pp_string (pp, "]");
+    }
+}
+
 /* Create two value-ranges in *VR0 and *VR1 from the anti-range *AR
    so that *VR0 U *VR1 == *AR.  Returns true if that is possible,
    false otherwise.  If *AR can be represented with a single range
diff --git a/gcc/value-range.h b/gcc/value-range.h
index 760ee772316..5fc3c596e1d 100644
--- a/gcc/value-range.h
+++ b/gcc/value-range.h
@@ -83,6 +83,7 @@ public:
   // Misc methods.
   bool fits_p (const irange &r) { return m_max_ranges >= r.num_pairs (); }
   void dump (FILE * = stderr) const;
+  void dump_to_pp (pretty_printer *pp) const;
 
   // Deprecated legacy public methods.
   enum value_range_kind kind () const;		// DEPRECATED
-- 
2.26.2

