Initial implementation of value query class.
authorAldy Hernandez <aldyh@redhat.com>
Thu, 17 Sep 2020 07:23:12 +0000 (09:23 +0200)
committerAldy Hernandez <aldyh@redhat.com>
Thu, 1 Oct 2020 12:55:08 +0000 (14:55 +0200)
gcc/ChangeLog:

* Makefile.in: Add value-query.o.
* value-query.cc: New file.
* value-query.h: New file.

gcc/Makefile.in
gcc/value-query.cc [new file with mode: 0644]
gcc/value-query.h [new file with mode: 0644]

index 9c6c1c93b976aaf350cc1f9b3bdc538308fdf08b..50d6c83eb768de4d62c35c27b478aada4062e320 100644 (file)
@@ -1646,6 +1646,7 @@ OBJS = \
        typed-splay-tree.o \
        unique-ptr-tests.o \
        valtrack.o \
+       value-query.o \
        value-range.o \
        value-range-equiv.o \
        value-prof.o \
diff --git a/gcc/value-query.cc b/gcc/value-query.cc
new file mode 100644 (file)
index 0000000..5370a23
--- /dev/null
@@ -0,0 +1,162 @@
+/* Support routines for value queries.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   Contributed by Aldy Hernandez <aldyh@redhat.com> and
+   Andrew MacLeod <amacleod@redhat.com>.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "backend.h"
+#include "tree.h"
+#include "gimple.h"
+#include "ssa.h"
+#include "tree-pretty-print.h"
+#include "fold-const.h"
+#include "value-range-equiv.h"
+#include "value-query.h"
+#include "alloc-pool.h"
+
+// value_query default methods.
+
+tree
+value_query::value_on_edge (edge, tree name)
+{
+  return value_of_expr (name);
+}
+
+tree
+value_query::value_of_stmt (gimple *stmt, tree name)
+{
+  if (!name)
+    name = gimple_get_lhs (stmt);
+
+  gcc_checking_assert (!name || name == gimple_get_lhs (stmt));
+
+  if (name)
+    return value_of_expr (name);
+  return NULL_TREE;
+}
+
+// range_query default methods.
+
+bool
+range_query::range_on_edge (irange &r, edge, tree name)
+{
+  return range_of_expr (r, name);
+}
+
+bool
+range_query::range_of_stmt (irange &r, gimple *stmt, tree name)
+{
+  if (!name)
+    name = gimple_get_lhs (stmt);
+
+  gcc_checking_assert (!name || name == gimple_get_lhs (stmt));
+
+  if (name)
+    return range_of_expr (r, name);
+  return false;
+}
+
+tree
+range_query::value_of_expr (tree name, gimple *stmt)
+{
+  tree t;
+  value_range r;
+
+  if (!irange::supports_type_p (TREE_TYPE (name)))
+    return NULL_TREE;
+  if (range_of_expr (r, name, stmt) && r.singleton_p (&t))
+    return t;
+  return NULL_TREE;
+}
+
+tree
+range_query::value_on_edge (edge e, tree name)
+{
+  tree t;
+  value_range r;
+
+  if (!irange::supports_type_p (TREE_TYPE (name)))
+    return NULL_TREE;
+  if (range_on_edge (r, e, name) && r.singleton_p (&t))
+    return t;
+  return NULL_TREE;
+
+}
+
+tree
+range_query::value_of_stmt (gimple *stmt, tree name)
+{
+  tree t;
+  value_range r;
+
+  if (!name)
+    name = gimple_get_lhs (stmt);
+
+  gcc_checking_assert (!name || name == gimple_get_lhs (stmt));
+
+  if (!name || !irange::supports_type_p (TREE_TYPE (name)))
+    return NULL_TREE;
+  if (range_of_stmt (r, stmt, name) && r.singleton_p (&t))
+    return t;
+  return NULL_TREE;
+
+}
+
+// valuation_query support routines for value_range_equiv's.
+
+class equiv_allocator : public object_allocator<value_range_equiv>
+{
+public:
+  equiv_allocator ()
+    : object_allocator<value_range_equiv> ("equiv_allocator pool") { }
+};
+
+value_range_equiv *
+range_query::allocate_value_range_equiv ()
+{
+  return new (equiv_alloc->allocate ()) value_range_equiv;
+}
+
+void
+range_query::free_value_range_equiv (value_range_equiv *v)
+{
+  equiv_alloc->remove (v);
+}
+
+const class value_range_equiv *
+range_query::get_value_range (const_tree expr, gimple *stmt)
+{
+  int_range_max r;
+  if (range_of_expr (r, const_cast<tree> (expr), stmt))
+    return new (equiv_alloc->allocate ()) value_range_equiv (r);
+  return new (equiv_alloc->allocate ()) value_range_equiv (TREE_TYPE (expr));
+}
+
+range_query::range_query ()
+{
+  equiv_alloc = new equiv_allocator;
+}
+
+range_query::~range_query ()
+{
+  equiv_alloc->release ();
+  delete equiv_alloc;
+}
diff --git a/gcc/value-query.h b/gcc/value-query.h
new file mode 100644 (file)
index 0000000..cf0b6ed
--- /dev/null
@@ -0,0 +1,107 @@
+/* Support routines for value queries.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   Contributed by Aldy Hernandez <aldyh@redhat.com> and
+   Andrew Macleod <amacleod@redhat.com>.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#ifndef GCC_QUERY_H
+#define GCC_QUERY_H
+
+// The value_query class is used by optimization passes that require
+// valueizing SSA names in terms of a tree value, but have no neeed
+// for ranges.
+//
+// value_of_expr must be provided.  The default for value_on_edge and
+// value_of_stmt is to call value_of_expr.
+//
+// This implies the valuation is global in nature.  If a pass can make
+// use of more specific information, it can override the other queries.
+//
+// Proper usage of the correct query in passes will enable other
+// valuation mechanisms to produce more precise results.
+
+class value_query
+{
+public:
+  value_query () { }
+  // Return the singleton expression for NAME at a gimple statement,
+  // or NULL if none found.
+  virtual tree value_of_expr (tree name, gimple * = NULL) = 0;
+  // Return the singleton expression for NAME at an edge, or NULL if
+  // none found.
+  virtual tree value_on_edge (edge, tree name);
+  // Return the singleton expression for the LHS of a gimple
+  // statement, assuming an (optional) initial value of NAME.  Returns
+  // NULL if none found.
+  //
+  // Note that this method calculates the range the LHS would have
+  // *after* the statement has executed.
+  virtual tree value_of_stmt (gimple *, tree name = NULL);
+
+private:
+  DISABLE_COPY_AND_ASSIGN (value_query);
+};
+
+// The range_query class is used by optimization passes which are
+// range aware.
+//
+// range_of_expr must be provided.  The default for range_on_edge and
+// range_of_stmt is to call range_of_expr.  If a pass can make use of
+// more specific information, then it can override the other queries.
+//
+// The default for the value_* routines is to call the equivalent
+// range_* routines, check if the range is a singleton, and return it
+// if so.
+//
+// The get_value_range method is currently provided for compatibility
+// with vr-values.  It will be deprecated when possible.
+
+class range_query : public value_query
+{
+public:
+  range_query ();
+  virtual ~range_query ();
+
+  virtual tree value_of_expr (tree name, gimple * = NULL) OVERRIDE;
+  virtual tree value_on_edge (edge, tree name) OVERRIDE;
+  virtual tree value_of_stmt (gimple *, tree name = NULL) OVERRIDE;
+
+  // These are the range equivalents of the value_* methods.  Instead
+  // of returning a singleton, they calculate a range and return it in
+  // R.  TRUE is returned on success or FALSE if no range was found.
+  //
+  // Note that range_of_expr must always return TRUE unless ranges are
+  // unsupported for NAME's type (supports_type_p is false).
+  virtual bool range_of_expr (irange &r, tree name, gimple * = NULL) = 0;
+  virtual bool range_on_edge (irange &r, edge, tree name);
+  virtual bool range_of_stmt (irange &r, gimple *, tree name = NULL);
+
+  // DEPRECATED: This method is used from vr-values.  The plan is to
+  // rewrite all uses of it to the above API.
+  virtual const class value_range_equiv *get_value_range (const_tree,
+                                                         gimple * = NULL);
+
+protected:
+  class value_range_equiv *allocate_value_range_equiv ();
+  void free_value_range_equiv (class value_range_equiv *);
+
+private:
+  class equiv_allocator *equiv_alloc;
+};
+
+#endif // GCC_QUERY_H