public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/rust/master] gccrs const folding: port over cp_walk_subtrees() from cp/tree.cc
@ 2022-06-14  7:37 Thomas Schwinge
  0 siblings, 0 replies; only message in thread
From: Thomas Schwinge @ 2022-06-14  7:37 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:859b1debbdb9c8795af37b4f08bace1635a61061

commit 859b1debbdb9c8795af37b4f08bace1635a61061
Author: Faisal Abbas <90.abbasfaisal@gmail.com>
Date:   Sun Jun 12 18:18:36 2022 +0100

    gccrs const folding: port over cp_walk_subtrees() from cp/tree.cc
    
    Signed-off-by: Faisal Abbas <90.abbasfaisal@gmail.com>

Diff:
---
 gcc/rust/backend/rust-tree.cc | 86 +++++++++++++++++++++++++++++++++++++++++++
 gcc/rust/backend/rust-tree.h  | 38 +++++++++++++++++++
 2 files changed, 124 insertions(+)

diff --git a/gcc/rust/backend/rust-tree.cc b/gcc/rust/backend/rust-tree.cc
index 6f7614d0413..a2a8a223156 100644
--- a/gcc/rust/backend/rust-tree.cc
+++ b/gcc/rust/backend/rust-tree.cc
@@ -674,4 +674,90 @@ pointer_offset_expression (tree base_tree, tree index_tree, location_t location)
 			  base_tree, offset);
 }
 
+// forked from gcc/cp/tree.cc cp_walk_subtrees
+/* Apply FUNC to all language-specific sub-trees of TP in a pre-order
+   traversal.  Called from walk_tree.  */
+
+tree
+rs_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func, void *data,
+		  hash_set<tree> *pset)
+{
+  enum tree_code code = TREE_CODE (*tp);
+  tree result;
+
+#define WALK_SUBTREE(NODE)                                                     \
+  do                                                                           \
+    {                                                                          \
+      result = rs_walk_tree (&(NODE), func, data, pset);                       \
+      if (result)                                                              \
+	goto out;                                                              \
+    }                                                                          \
+  while (0)
+
+  if (TYPE_P (*tp))
+    {
+      /* If *WALK_SUBTREES_P is 1, we're interested in the syntactic form of
+	 the argument, so don't look through typedefs, but do walk into
+	 template arguments for alias templates (and non-typedefed classes).
+
+	 If *WALK_SUBTREES_P > 1, we're interested in type identity or
+	 equivalence, so look through typedefs, ignoring template arguments for
+	 alias templates, and walk into template args of classes.
+
+	 See find_abi_tags_r for an example of setting *WALK_SUBTREES_P to 2
+	 when that's the behavior the walk_tree_fn wants.  */
+      if (*walk_subtrees_p == 1 && typedef_variant_p (*tp))
+	{
+	  *walk_subtrees_p = 0;
+	  return NULL_TREE;
+	}
+    }
+
+  /* Not one of the easy cases.  We must explicitly go through the
+     children.  */
+  result = NULL_TREE;
+  switch (code)
+    {
+    case TREE_LIST:
+      WALK_SUBTREE (TREE_PURPOSE (*tp));
+      break;
+
+    case RECORD_TYPE:
+      if (TYPE_PTRMEMFUNC_P (*tp))
+	WALK_SUBTREE (TYPE_PTRMEMFUNC_FN_TYPE_RAW (*tp));
+      break;
+
+    case CONSTRUCTOR:
+      if (COMPOUND_LITERAL_P (*tp))
+	WALK_SUBTREE (TREE_TYPE (*tp));
+      break;
+
+    case DECL_EXPR:
+      /* User variables should be mentioned in BIND_EXPR_VARS
+	 and their initializers and sizes walked when walking
+	 the containing BIND_EXPR.  Compiler temporaries are
+	 handled here.  And also normal variables in templates,
+	 since do_poplevel doesn't build a BIND_EXPR then.  */
+      if (VAR_P (TREE_OPERAND (*tp, 0))
+	  && (DECL_ARTIFICIAL (TREE_OPERAND (*tp, 0))
+	      && !TREE_STATIC (TREE_OPERAND (*tp, 0))))
+	{
+	  tree decl = TREE_OPERAND (*tp, 0);
+	  WALK_SUBTREE (DECL_INITIAL (decl));
+	  WALK_SUBTREE (DECL_SIZE (decl));
+	  WALK_SUBTREE (DECL_SIZE_UNIT (decl));
+	}
+      break;
+
+    default:
+      return NULL_TREE;
+    }
+
+  /* We didn't find what we were looking for.  */
+out:
+  return result;
+
+#undef WALK_SUBTREE
+}
+
 } // namespace Rust
diff --git a/gcc/rust/backend/rust-tree.h b/gcc/rust/backend/rust-tree.h
index 2b480ada400..f164a1043de 100644
--- a/gcc/rust/backend/rust-tree.h
+++ b/gcc/rust/backend/rust-tree.h
@@ -80,6 +80,37 @@
 #define SLICE_TYPE_P(TYPE)                                                     \
   (TREE_CODE (TYPE) == RECORD_TYPE && TREE_LANG_FLAG_0 (TYPE))
 
+/* Returns true if NODE is a pointer to member function type.  */
+#define TYPE_PTRMEMFUNC_P(NODE)                                                \
+  (TREE_CODE (NODE) == RECORD_TYPE && TYPE_PTRMEMFUNC_FLAG (NODE))
+
+#define TYPE_PTRMEMFUNC_FLAG(NODE) (TYPE_LANG_FLAG_2 (RECORD_TYPE_CHECK (NODE)))
+
+#define TYPE_PTRMEMFUNC_FN_TYPE_RAW(NODE) (TREE_TYPE (TYPE_FIELDS (NODE)))
+
+/* True if NODE is a compound-literal, i.e., a brace-enclosed
+   initializer cast to a particular type.  This is mostly only set during
+   template parsing; once the initializer has been digested into an actual
+   value of the type, the expression is represented by a TARGET_EXPR.  */
+#define COMPOUND_LITERAL_P(NODE)                                               \
+  (TREE_CODE (NODE) == CONSTRUCTOR && TREE_HAS_CONSTRUCTOR (NODE))
+
+/* When appearing in an INDIRECT_REF, it means that the tree structure
+   underneath is actually a call to a constructor.  This is needed
+   when the constructor must initialize local storage (which can
+   be automatically destroyed), rather than allowing it to allocate
+   space from the heap.
+
+   When appearing in a SAVE_EXPR, it means that underneath
+   is a call to a constructor.
+
+   When appearing in a CONSTRUCTOR, the expression is an unconverted
+   compound literal.
+
+   When appearing in a FIELD_DECL, it means that this field
+   has been duly initialized in its constructor.  */
+#define TREE_HAS_CONSTRUCTOR(NODE) (TREE_LANG_FLAG_4 (NODE))
+
 namespace Rust {
 
 // forked from gcc/cp/cvt.cc convert_to_void
@@ -189,6 +220,13 @@ get_fndecl_from_callee (tree fn);
 extern tree
 pointer_offset_expression (tree base_tree, tree index_tree, location_t locus);
 
+extern tree
+rs_walk_subtrees (tree *, int *, walk_tree_fn, void *, hash_set<tree> *);
+#define rs_walk_tree(tp, func, data, pset)                                     \
+  walk_tree_1 (tp, func, data, pset, rs_walk_subtrees)
+#define rs_walk_tree_without_duplicates(tp, func, data)                        \
+  walk_tree_without_duplicates_1 (tp, func, data, rs_walk_subtrees)
+
 } // namespace Rust
 
 #endif // RUST_TREE


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

only message in thread, other threads:[~2022-06-14  7:37 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-14  7:37 [gcc/devel/rust/master] gccrs const folding: port over cp_walk_subtrees() from cp/tree.cc Thomas Schwinge

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).