diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2022-06-14 06:35:18 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-14 06:35:18 +0000 |
commit | 25974baf19caf2b38c3755ce00a3065c62472053 (patch) | |
tree | 989dbb68790910b01c497a7c50ba38cd606ab41f /gcc/rust | |
parent | 5a62eb20638eab1cbad99e25db6126875b12bf2d (diff) | |
parent | 859b1debbdb9c8795af37b4f08bace1635a61061 (diff) | |
download | gcc-25974baf19caf2b38c3755ce00a3065c62472053.zip gcc-25974baf19caf2b38c3755ce00a3065c62472053.tar.gz gcc-25974baf19caf2b38c3755ce00a3065c62472053.tar.bz2 |
Merge #1286
1286: gccrs const folding: port over cp_walk_subtrees() r=CohenArthur a=abbasfaisal
Card: [Link](https://github.com/Rust-GCC/gccrs/projects/16#card-82441327)
Most of TREE_CODEs in the original function belonged to cp/cp-tree.def which have been removed so this ported function is a lot smaller.
Co-authored-by: Faisal Abbas <90.abbasfaisal@gmail.com>
Diffstat (limited to 'gcc/rust')
-rw-r--r-- | gcc/rust/backend/rust-tree.cc | 86 | ||||
-rw-r--r-- | gcc/rust/backend/rust-tree.h | 38 |
2 files changed, 124 insertions, 0 deletions
diff --git a/gcc/rust/backend/rust-tree.cc b/gcc/rust/backend/rust-tree.cc index 6f7614d..a2a8a22 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 2b480ad..f164a10 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 |