tree, c++: optimize walk_tree_1 and cp_walk_subtrees

Message ID 20221205042109.4144777-1-ppalka@redhat.com
State New
Headers
Series tree, c++: optimize walk_tree_1 and cp_walk_subtrees |

Commit Message

Patrick Palka Dec. 5, 2022, 4:21 a.m. UTC
  These functions currently repeatedly dereference tp during the subtree
walk, dereferences which the compiler can't CSE because it can't
guarantee that the subtree walking doesn't modify *tp.

But we already implicitly require that TREE_CODE (*tp) remains the same
throughout the subtree walks, so it doesn't seem to be a huge leap to
strengthen that to requiring *tp remains the same.

So this patch manually CSEs the dereferences of *tp.  This means that
the callback function can no longer replace *tp with another tree (of
the same TREE_CODE) when walking one of its subtrees, but that doesn't
sound like a useful feature anyway.  This speeds up the C++ frontend by
about ~1.5% according to my experiments.

Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk stage3 or perhaps for stage1?

gcc/cp/ChangeLog:

	* tree.cc (cp_walk_subtrees): Avoid repeatedly dereferencing tp.

gcc/ChangeLog:

	* tree.cc (walk_tree_1): Avoid repeatedly dereferencing tp
	and type_p.
---
 gcc/cp/tree.cc | 113 +++++++++++++++++++++++++------------------------
 gcc/tree.cc    | 103 ++++++++++++++++++++++----------------------
 2 files changed, 108 insertions(+), 108 deletions(-)
  

Comments

Prathamesh Kulkarni Dec. 5, 2022, 11:09 a.m. UTC | #1
On Mon, 5 Dec 2022 at 09:51, Patrick Palka via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> These functions currently repeatedly dereference tp during the subtree
> walk, dereferences which the compiler can't CSE because it can't
> guarantee that the subtree walking doesn't modify *tp.
>
> But we already implicitly require that TREE_CODE (*tp) remains the same
> throughout the subtree walks, so it doesn't seem to be a huge leap to
> strengthen that to requiring *tp remains the same.
Hi Patrick,
Just wondering in that case, if marking tp with const_tree *, instead
of tree *, would perhaps help the compiler
for CSEing some of the dereferences to *tp ?

Thanks,
Prathamesh
>
> So this patch manually CSEs the dereferences of *tp.  This means that
> the callback function can no longer replace *tp with another tree (of
> the same TREE_CODE) when walking one of its subtrees, but that doesn't
> sound like a useful feature anyway.  This speeds up the C++ frontend by
> about ~1.5% according to my experiments.
>
> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
> trunk stage3 or perhaps for stage1?
>
> gcc/cp/ChangeLog:
>
>         * tree.cc (cp_walk_subtrees): Avoid repeatedly dereferencing tp.
>
> gcc/ChangeLog:
>
>         * tree.cc (walk_tree_1): Avoid repeatedly dereferencing tp
>         and type_p.
> ---
>  gcc/cp/tree.cc | 113 +++++++++++++++++++++++++------------------------
>  gcc/tree.cc    | 103 ++++++++++++++++++++++----------------------
>  2 files changed, 108 insertions(+), 108 deletions(-)
>
> diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
> index 4066b014f6e..ceb0c75f559 100644
> --- a/gcc/cp/tree.cc
> +++ b/gcc/cp/tree.cc
> @@ -5441,7 +5441,8 @@ tree
>  cp_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 t = *tp;
> +  enum tree_code code = TREE_CODE (t);
>    tree result;
>
>  #define WALK_SUBTREE(NODE)                             \
> @@ -5452,7 +5453,7 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
>      }                                                  \
>    while (0)
>
> -  if (TYPE_P (*tp))
> +  if (TYPE_P (t))
>      {
>        /* 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
> @@ -5464,15 +5465,15 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
>
>          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))
> +      if (*walk_subtrees_p == 1 && typedef_variant_p (t))
>         {
> -         if (tree ti = TYPE_ALIAS_TEMPLATE_INFO (*tp))
> +         if (tree ti = TYPE_ALIAS_TEMPLATE_INFO (t))
>             WALK_SUBTREE (TI_ARGS (ti));
>           *walk_subtrees_p = 0;
>           return NULL_TREE;
>         }
>
> -      if (tree ti = TYPE_TEMPLATE_INFO (*tp))
> +      if (tree ti = TYPE_TEMPLATE_INFO (t))
>         WALK_SUBTREE (TI_ARGS (ti));
>      }
>
> @@ -5482,8 +5483,8 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
>    switch (code)
>      {
>      case TEMPLATE_TYPE_PARM:
> -      if (template_placeholder_p (*tp))
> -       WALK_SUBTREE (CLASS_PLACEHOLDER_TEMPLATE (*tp));
> +      if (template_placeholder_p (t))
> +       WALK_SUBTREE (CLASS_PLACEHOLDER_TEMPLATE (t));
>        /* Fall through.  */
>      case DEFERRED_PARSE:
>      case TEMPLATE_TEMPLATE_PARM:
> @@ -5497,63 +5498,63 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
>        break;
>
>      case TYPENAME_TYPE:
> -      WALK_SUBTREE (TYPE_CONTEXT (*tp));
> -      WALK_SUBTREE (TYPENAME_TYPE_FULLNAME (*tp));
> +      WALK_SUBTREE (TYPE_CONTEXT (t));
> +      WALK_SUBTREE (TYPENAME_TYPE_FULLNAME (t));
>        *walk_subtrees_p = 0;
>        break;
>
>      case BASELINK:
> -      if (BASELINK_QUALIFIED_P (*tp))
> -       WALK_SUBTREE (BINFO_TYPE (BASELINK_ACCESS_BINFO (*tp)));
> -      WALK_SUBTREE (BASELINK_FUNCTIONS (*tp));
> +      if (BASELINK_QUALIFIED_P (t))
> +       WALK_SUBTREE (BINFO_TYPE (BASELINK_ACCESS_BINFO (t)));
> +      WALK_SUBTREE (BASELINK_FUNCTIONS (t));
>        *walk_subtrees_p = 0;
>        break;
>
>      case PTRMEM_CST:
> -      WALK_SUBTREE (TREE_TYPE (*tp));
> +      WALK_SUBTREE (TREE_TYPE (t));
>        *walk_subtrees_p = 0;
>        break;
>
>      case TREE_LIST:
> -      WALK_SUBTREE (TREE_PURPOSE (*tp));
> +      WALK_SUBTREE (TREE_PURPOSE (t));
>        break;
>
>      case OVERLOAD:
> -      WALK_SUBTREE (OVL_FUNCTION (*tp));
> -      WALK_SUBTREE (OVL_CHAIN (*tp));
> +      WALK_SUBTREE (OVL_FUNCTION (t));
> +      WALK_SUBTREE (OVL_CHAIN (t));
>        *walk_subtrees_p = 0;
>        break;
>
>      case USING_DECL:
> -      WALK_SUBTREE (DECL_NAME (*tp));
> -      WALK_SUBTREE (USING_DECL_SCOPE (*tp));
> -      WALK_SUBTREE (USING_DECL_DECLS (*tp));
> +      WALK_SUBTREE (DECL_NAME (t));
> +      WALK_SUBTREE (USING_DECL_SCOPE (t));
> +      WALK_SUBTREE (USING_DECL_DECLS (t));
>        *walk_subtrees_p = 0;
>        break;
>
>      case RECORD_TYPE:
> -      if (TYPE_PTRMEMFUNC_P (*tp))
> -       WALK_SUBTREE (TYPE_PTRMEMFUNC_FN_TYPE_RAW (*tp));
> +      if (TYPE_PTRMEMFUNC_P (t))
> +       WALK_SUBTREE (TYPE_PTRMEMFUNC_FN_TYPE_RAW (t));
>        break;
>
>      case TYPE_ARGUMENT_PACK:
>      case NONTYPE_ARGUMENT_PACK:
>        {
> -        tree args = ARGUMENT_PACK_ARGS (*tp);
> +       tree args = ARGUMENT_PACK_ARGS (t);
>         for (tree arg : tree_vec_range (args))
>           WALK_SUBTREE (arg);
>        }
>        break;
>
>      case TYPE_PACK_EXPANSION:
> -      WALK_SUBTREE (TREE_TYPE (*tp));
> -      WALK_SUBTREE (PACK_EXPANSION_EXTRA_ARGS (*tp));
> +      WALK_SUBTREE (TREE_TYPE (t));
> +      WALK_SUBTREE (PACK_EXPANSION_EXTRA_ARGS (t));
>        *walk_subtrees_p = 0;
>        break;
>
>      case EXPR_PACK_EXPANSION:
> -      WALK_SUBTREE (TREE_OPERAND (*tp, 0));
> -      WALK_SUBTREE (PACK_EXPANSION_EXTRA_ARGS (*tp));
> +      WALK_SUBTREE (TREE_OPERAND (t, 0));
> +      WALK_SUBTREE (PACK_EXPANSION_EXTRA_ARGS (t));
>        *walk_subtrees_p = 0;
>        break;
>
> @@ -5564,31 +5565,31 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
>      case DYNAMIC_CAST_EXPR:
>      case IMPLICIT_CONV_EXPR:
>      case BIT_CAST_EXPR:
> -      if (TREE_TYPE (*tp))
> -       WALK_SUBTREE (TREE_TYPE (*tp));
> +      if (TREE_TYPE (t))
> +       WALK_SUBTREE (TREE_TYPE (t));
>        break;
>
>      case CONSTRUCTOR:
> -      if (COMPOUND_LITERAL_P (*tp))
> -       WALK_SUBTREE (TREE_TYPE (*tp));
> +      if (COMPOUND_LITERAL_P (t))
> +       WALK_SUBTREE (TREE_TYPE (t));
>        break;
>
>      case TRAIT_EXPR:
> -      WALK_SUBTREE (TRAIT_EXPR_TYPE1 (*tp));
> -      WALK_SUBTREE (TRAIT_EXPR_TYPE2 (*tp));
> +      WALK_SUBTREE (TRAIT_EXPR_TYPE1 (t));
> +      WALK_SUBTREE (TRAIT_EXPR_TYPE2 (t));
>        *walk_subtrees_p = 0;
>        break;
>
>      case TRAIT_TYPE:
> -      WALK_SUBTREE (TRAIT_TYPE_TYPE1 (*tp));
> -      WALK_SUBTREE (TRAIT_TYPE_TYPE2 (*tp));
> +      WALK_SUBTREE (TRAIT_TYPE_TYPE1 (t));
> +      WALK_SUBTREE (TRAIT_TYPE_TYPE2 (t));
>        *walk_subtrees_p = 0;
>        break;
>
>      case DECLTYPE_TYPE:
>        ++cp_unevaluated_operand;
>        /* We can't use WALK_SUBTREE here because of the goto.  */
> -      result = cp_walk_tree (&DECLTYPE_TYPE_EXPR (*tp), func, data, pset);
> +      result = cp_walk_tree (&DECLTYPE_TYPE_EXPR (t), func, data, pset);
>        --cp_unevaluated_operand;
>        *walk_subtrees_p = 0;
>        break;
> @@ -5597,7 +5598,7 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
>      case SIZEOF_EXPR:
>      case NOEXCEPT_EXPR:
>        ++cp_unevaluated_operand;
> -      result = cp_walk_tree (&TREE_OPERAND (*tp, 0), func, data, pset);
> +      result = cp_walk_tree (&TREE_OPERAND (t, 0), func, data, pset);
>        --cp_unevaluated_operand;
>        *walk_subtrees_p = 0;
>        break;
> @@ -5605,12 +5606,12 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
>      case REQUIRES_EXPR:
>        {
>         cp_unevaluated u;
> -       for (tree parm = REQUIRES_EXPR_PARMS (*tp); parm; parm = DECL_CHAIN (parm))
> +       for (tree parm = REQUIRES_EXPR_PARMS (t); parm; parm = DECL_CHAIN (parm))
>           /* Walk the types of each parameter, but not the parameter itself.
>              Doing so would cause false positives in the unexpanded parameter
>              pack checker since an introduced parameter pack looks bare.  */
>           WALK_SUBTREE (TREE_TYPE (parm));
> -       WALK_SUBTREE (REQUIRES_EXPR_REQS (*tp));
> +       WALK_SUBTREE (REQUIRES_EXPR_REQS (t));
>         *walk_subtrees_p = 0;
>         break;
>        }
> @@ -5621,12 +5622,12 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
>          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))
> +      if (VAR_P (TREE_OPERAND (t, 0))
>           && (processing_template_decl
> -             || (DECL_ARTIFICIAL (TREE_OPERAND (*tp, 0))
> -                 && !TREE_STATIC (TREE_OPERAND (*tp, 0)))))
> +             || (DECL_ARTIFICIAL (TREE_OPERAND (t, 0))
> +                 && !TREE_STATIC (TREE_OPERAND (t, 0)))))
>         {
> -         tree decl = TREE_OPERAND (*tp, 0);
> +         tree decl = TREE_OPERAND (t, 0);
>           WALK_SUBTREE (DECL_INITIAL (decl));
>           WALK_SUBTREE (DECL_SIZE (decl));
>           WALK_SUBTREE (DECL_SIZE_UNIT (decl));
> @@ -5636,45 +5637,45 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
>      case LAMBDA_EXPR:
>        /* Don't walk into the body of the lambda, but the capture initializers
>          are part of the enclosing context.  */
> -      for (tree cap = LAMBDA_EXPR_CAPTURE_LIST (*tp); cap;
> +      for (tree cap = LAMBDA_EXPR_CAPTURE_LIST (t); cap;
>            cap = TREE_CHAIN (cap))
>         WALK_SUBTREE (TREE_VALUE (cap));
>        break;
>
>      case CO_YIELD_EXPR:
> -      if (TREE_OPERAND (*tp, 1))
> +      if (TREE_OPERAND (t, 1))
>         /* Operand 1 is the tree for the relevant co_await which has any
>            interesting sub-trees.  */
> -       WALK_SUBTREE (TREE_OPERAND (*tp, 1));
> +       WALK_SUBTREE (TREE_OPERAND (t, 1));
>        break;
>
>      case CO_AWAIT_EXPR:
> -      if (TREE_OPERAND (*tp, 1))
> +      if (TREE_OPERAND (t, 1))
>         /* Operand 1 is frame variable.  */
> -       WALK_SUBTREE (TREE_OPERAND (*tp, 1));
> -      if (TREE_OPERAND (*tp, 2))
> +       WALK_SUBTREE (TREE_OPERAND (t, 1));
> +      if (TREE_OPERAND (t, 2))
>         /* Operand 2 has the initialiser, and we need to walk any subtrees
>            there.  */
> -       WALK_SUBTREE (TREE_OPERAND (*tp, 2));
> +       WALK_SUBTREE (TREE_OPERAND (t, 2));
>        break;
>
>      case CO_RETURN_EXPR:
> -      if (TREE_OPERAND (*tp, 0))
> +      if (TREE_OPERAND (t, 0))
>         {
> -         if (VOID_TYPE_P (TREE_OPERAND (*tp, 0)))
> +         if (VOID_TYPE_P (TREE_OPERAND (t, 0)))
>             /* For void expressions, operand 1 is a trivial call, and any
>                interesting subtrees will be part of operand 0.  */
> -           WALK_SUBTREE (TREE_OPERAND (*tp, 0));
> -         else if (TREE_OPERAND (*tp, 1))
> +           WALK_SUBTREE (TREE_OPERAND (t, 0));
> +         else if (TREE_OPERAND (t, 1))
>             /* Interesting sub-trees will be in the return_value () call
>                arguments.  */
> -           WALK_SUBTREE (TREE_OPERAND (*tp, 1));
> +           WALK_SUBTREE (TREE_OPERAND (t, 1));
>         }
>        break;
>
>      case STATIC_ASSERT:
> -      WALK_SUBTREE (STATIC_ASSERT_CONDITION (*tp));
> -      WALK_SUBTREE (STATIC_ASSERT_MESSAGE (*tp));
> +      WALK_SUBTREE (STATIC_ASSERT_CONDITION (t));
> +      WALK_SUBTREE (STATIC_ASSERT_MESSAGE (t));
>        break;
>
>      default:
> diff --git a/gcc/tree.cc b/gcc/tree.cc
> index 5eb6a49da31..dfada652570 100644
> --- a/gcc/tree.cc
> +++ b/gcc/tree.cc
> @@ -11218,10 +11218,6 @@ tree
>  walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
>              hash_set<tree> *pset, walk_tree_lh lh)
>  {
> -  enum tree_code code;
> -  int walk_subtrees;
> -  tree result;
> -
>  #define WALK_SUBTREE_TAIL(NODE)                                \
>    do                                                   \
>      {                                                  \
> @@ -11241,14 +11237,15 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
>      return NULL_TREE;
>
>    /* Call the function.  */
> -  walk_subtrees = 1;
> -  result = (*func) (tp, &walk_subtrees, data);
> +  int walk_subtrees = 1;
> +  tree result = (*func) (tp, &walk_subtrees, data);
>
>    /* If we found something, return it.  */
>    if (result)
>      return result;
>
> -  code = TREE_CODE (*tp);
> +  tree t = *tp;
> +  tree_code code = TREE_CODE (t);
>
>    /* Even if we didn't, FUNC may have decided that there was nothing
>       interesting below this point in the tree.  */
> @@ -11256,9 +11253,9 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
>      {
>        /* But we still need to check our siblings.  */
>        if (code == TREE_LIST)
> -       WALK_SUBTREE_TAIL (TREE_CHAIN (*tp));
> +       WALK_SUBTREE_TAIL (TREE_CHAIN (t));
>        else if (code == OMP_CLAUSE)
> -       WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp));
> +       WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (t));
>        else
>         return NULL_TREE;
>      }
> @@ -11288,58 +11285,58 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
>        break;
>
>      case TREE_LIST:
> -      WALK_SUBTREE (TREE_VALUE (*tp));
> -      WALK_SUBTREE_TAIL (TREE_CHAIN (*tp));
> +      WALK_SUBTREE (TREE_VALUE (t));
> +      WALK_SUBTREE_TAIL (TREE_CHAIN (t));
>
>      case TREE_VEC:
>        {
> -       int len = TREE_VEC_LENGTH (*tp);
> +       int len = TREE_VEC_LENGTH (t);
>
>         if (len == 0)
>           break;
>
>         /* Walk all elements but the first.  */
>         while (--len)
> -         WALK_SUBTREE (TREE_VEC_ELT (*tp, len));
> +         WALK_SUBTREE (TREE_VEC_ELT (t, len));
>
>         /* Now walk the first one as a tail call.  */
> -       WALK_SUBTREE_TAIL (TREE_VEC_ELT (*tp, 0));
> +       WALK_SUBTREE_TAIL (TREE_VEC_ELT (t, 0));
>        }
>
>      case VECTOR_CST:
>        {
> -       unsigned len = vector_cst_encoded_nelts (*tp);
> +       unsigned len = vector_cst_encoded_nelts (t);
>         if (len == 0)
>           break;
>         /* Walk all elements but the first.  */
>         while (--len)
> -         WALK_SUBTREE (VECTOR_CST_ENCODED_ELT (*tp, len));
> +         WALK_SUBTREE (VECTOR_CST_ENCODED_ELT (t, len));
>         /* Now walk the first one as a tail call.  */
> -       WALK_SUBTREE_TAIL (VECTOR_CST_ENCODED_ELT (*tp, 0));
> +       WALK_SUBTREE_TAIL (VECTOR_CST_ENCODED_ELT (t, 0));
>        }
>
>      case COMPLEX_CST:
> -      WALK_SUBTREE (TREE_REALPART (*tp));
> -      WALK_SUBTREE_TAIL (TREE_IMAGPART (*tp));
> +      WALK_SUBTREE (TREE_REALPART (t));
> +      WALK_SUBTREE_TAIL (TREE_IMAGPART (t));
>
>      case CONSTRUCTOR:
>        {
>         unsigned HOST_WIDE_INT idx;
>         constructor_elt *ce;
>
> -       for (idx = 0; vec_safe_iterate (CONSTRUCTOR_ELTS (*tp), idx, &ce);
> +       for (idx = 0; vec_safe_iterate (CONSTRUCTOR_ELTS (t), idx, &ce);
>              idx++)
>           WALK_SUBTREE (ce->value);
>        }
>        break;
>
>      case SAVE_EXPR:
> -      WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, 0));
> +      WALK_SUBTREE_TAIL (TREE_OPERAND (t, 0));
>
>      case BIND_EXPR:
>        {
>         tree decl;
> -       for (decl = BIND_EXPR_VARS (*tp); decl; decl = DECL_CHAIN (decl))
> +       for (decl = BIND_EXPR_VARS (t); decl; decl = DECL_CHAIN (decl))
>           {
>             /* Walk the DECL_INITIAL and DECL_SIZE.  We don't want to walk
>                into declarations that are just mentioned, rather than
> @@ -11350,23 +11347,23 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
>             WALK_SUBTREE (DECL_SIZE (decl));
>             WALK_SUBTREE (DECL_SIZE_UNIT (decl));
>           }
> -       WALK_SUBTREE_TAIL (BIND_EXPR_BODY (*tp));
> +       WALK_SUBTREE_TAIL (BIND_EXPR_BODY (t));
>        }
>
>      case STATEMENT_LIST:
>        {
>         tree_stmt_iterator i;
> -       for (i = tsi_start (*tp); !tsi_end_p (i); tsi_next (&i))
> +       for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
>           WALK_SUBTREE (*tsi_stmt_ptr (i));
>        }
>        break;
>
>      case OMP_CLAUSE:
>        {
> -       int len = omp_clause_num_ops[OMP_CLAUSE_CODE (*tp)];
> +       int len = omp_clause_num_ops[OMP_CLAUSE_CODE (t)];
>         for (int i = 0; i < len; i++)
> -         WALK_SUBTREE (OMP_CLAUSE_OPERAND (*tp, i));
> -       WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp));
> +         WALK_SUBTREE (OMP_CLAUSE_OPERAND (t, i));
> +       WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (t));
>        }
>
>      case TARGET_EXPR:
> @@ -11375,10 +11372,10 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
>
>         /* TARGET_EXPRs are peculiar: operands 1 and 3 can be the same.
>            But, we only want to walk once.  */
> -       len = (TREE_OPERAND (*tp, 3) == TREE_OPERAND (*tp, 1)) ? 2 : 3;
> +       len = (TREE_OPERAND (t, 3) == TREE_OPERAND (t, 1)) ? 2 : 3;
>         for (i = 0; i < len; ++i)
> -         WALK_SUBTREE (TREE_OPERAND (*tp, i));
> -       WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, len));
> +         WALK_SUBTREE (TREE_OPERAND (t, i));
> +       WALK_SUBTREE_TAIL (TREE_OPERAND (t, len));
>        }
>
>      case DECL_EXPR:
> @@ -11393,15 +11390,15 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
>          variable-sized types.
>
>          Note that DECLs get walked as part of processing the BIND_EXPR.  */
> -      if (TREE_CODE (DECL_EXPR_DECL (*tp)) == TYPE_DECL)
> +      if (TREE_CODE (DECL_EXPR_DECL (t)) == TYPE_DECL)
>         {
>           /* Call the function for the decl so e.g. copy_tree_body_r can
>              replace it with the remapped one.  */
> -         result = (*func) (&DECL_EXPR_DECL (*tp), &walk_subtrees, data);
> +         result = (*func) (&DECL_EXPR_DECL (t), &walk_subtrees, data);
>           if (result || !walk_subtrees)
>             return result;
>
> -         tree *type_p = &TREE_TYPE (DECL_EXPR_DECL (*tp));
> +         tree *type_p = &TREE_TYPE (DECL_EXPR_DECL (t));
>           if (TREE_CODE (*type_p) == ERROR_MARK)
>             return NULL_TREE;
>
> @@ -11412,21 +11409,23 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
>           if (result || !walk_subtrees)
>             return result;
>
> +         tree type = *type_p;
> +
>           /* But do not walk a pointed-to type since it may itself need to
>              be walked in the declaration case if it isn't anonymous.  */
> -         if (!POINTER_TYPE_P (*type_p))
> +         if (!POINTER_TYPE_P (type))
>             {
> -             result = walk_type_fields (*type_p, func, data, pset, lh);
> +             result = walk_type_fields (type, func, data, pset, lh);
>               if (result)
>                 return result;
>             }
>
>           /* If this is a record type, also walk the fields.  */
> -         if (RECORD_OR_UNION_TYPE_P (*type_p))
> +         if (RECORD_OR_UNION_TYPE_P (type))
>             {
>               tree field;
>
> -             for (field = TYPE_FIELDS (*type_p); field;
> +             for (field = TYPE_FIELDS (type); field;
>                    field = DECL_CHAIN (field))
>                 {
>                   /* We'd like to look at the type of the field, but we can
> @@ -11439,24 +11438,24 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
>                   WALK_SUBTREE (DECL_FIELD_OFFSET (field));
>                   WALK_SUBTREE (DECL_SIZE (field));
>                   WALK_SUBTREE (DECL_SIZE_UNIT (field));
> -                 if (TREE_CODE (*type_p) == QUAL_UNION_TYPE)
> +                 if (TREE_CODE (type) == QUAL_UNION_TYPE)
>                     WALK_SUBTREE (DECL_QUALIFIER (field));
>                 }
>             }
>
>           /* Same for scalar types.  */
> -         else if (TREE_CODE (*type_p) == BOOLEAN_TYPE
> -                  || TREE_CODE (*type_p) == ENUMERAL_TYPE
> -                  || TREE_CODE (*type_p) == INTEGER_TYPE
> -                  || TREE_CODE (*type_p) == FIXED_POINT_TYPE
> -                  || TREE_CODE (*type_p) == REAL_TYPE)
> +         else if (TREE_CODE (type) == BOOLEAN_TYPE
> +                  || TREE_CODE (type) == ENUMERAL_TYPE
> +                  || TREE_CODE (type) == INTEGER_TYPE
> +                  || TREE_CODE (type) == FIXED_POINT_TYPE
> +                  || TREE_CODE (type) == REAL_TYPE)
>             {
> -             WALK_SUBTREE (TYPE_MIN_VALUE (*type_p));
> -             WALK_SUBTREE (TYPE_MAX_VALUE (*type_p));
> +             WALK_SUBTREE (TYPE_MIN_VALUE (type));
> +             WALK_SUBTREE (TYPE_MAX_VALUE (type));
>             }
>
> -         WALK_SUBTREE (TYPE_SIZE (*type_p));
> -         WALK_SUBTREE_TAIL (TYPE_SIZE_UNIT (*type_p));
> +         WALK_SUBTREE (TYPE_SIZE (type));
> +         WALK_SUBTREE_TAIL (TYPE_SIZE_UNIT (type));
>         }
>        /* FALLTHRU */
>
> @@ -11466,20 +11465,20 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
>           int i, len;
>
>           /* Walk over all the sub-trees of this operand.  */
> -         len = TREE_OPERAND_LENGTH (*tp);
> +         len = TREE_OPERAND_LENGTH (t);
>
>           /* Go through the subtrees.  We need to do this in forward order so
>              that the scope of a FOR_EXPR is handled properly.  */
>           if (len)
>             {
>               for (i = 0; i < len - 1; ++i)
> -               WALK_SUBTREE (TREE_OPERAND (*tp, i));
> -             WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, len - 1));
> +               WALK_SUBTREE (TREE_OPERAND (t, i));
> +             WALK_SUBTREE_TAIL (TREE_OPERAND (t, len - 1));
>             }
>         }
>        /* If this is a type, walk the needed fields in the type.  */
> -      else if (TYPE_P (*tp))
> -       return walk_type_fields (*tp, func, data, pset, lh);
> +      else if (TYPE_P (t))
> +       return walk_type_fields (t, func, data, pset, lh);
>        break;
>      }
>
> --
> 2.39.0.rc0.49.g083e01275b
>
  
Patrick Palka Dec. 5, 2022, 2:35 p.m. UTC | #2
On Mon, 5 Dec 2022, Prathamesh Kulkarni wrote:

> On Mon, 5 Dec 2022 at 09:51, Patrick Palka via Gcc-patches
> <gcc-patches@gcc.gnu.org> wrote:
> >
> > These functions currently repeatedly dereference tp during the subtree
> > walk, dereferences which the compiler can't CSE because it can't
> > guarantee that the subtree walking doesn't modify *tp.
> >
> > But we already implicitly require that TREE_CODE (*tp) remains the same
> > throughout the subtree walks, so it doesn't seem to be a huge leap to
> > strengthen that to requiring *tp remains the same.
> Hi Patrick,
> Just wondering in that case, if marking tp with const_tree *, instead
> of tree *, would perhaps help the compiler
> for CSEing some of the dereferences to *tp ?

IIUC I don't think using const_tree will help optimization-wise since the
main issue is CSEing across calls to the callback fn, and the callback
can still potentially modify *tp through some other, non-const pointer
to it since it's global memory.

> 
> Thanks,
> Prathamesh
> >
> > So this patch manually CSEs the dereferences of *tp.  This means that
> > the callback function can no longer replace *tp with another tree (of
> > the same TREE_CODE) when walking one of its subtrees, but that doesn't
> > sound like a useful feature anyway.  This speeds up the C++ frontend by
> > about ~1.5% according to my experiments.
> >
> > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
> > trunk stage3 or perhaps for stage1?
> >
> > gcc/cp/ChangeLog:
> >
> >         * tree.cc (cp_walk_subtrees): Avoid repeatedly dereferencing tp.
> >
> > gcc/ChangeLog:
> >
> >         * tree.cc (walk_tree_1): Avoid repeatedly dereferencing tp
> >         and type_p.
> > ---
> >  gcc/cp/tree.cc | 113 +++++++++++++++++++++++++------------------------
> >  gcc/tree.cc    | 103 ++++++++++++++++++++++----------------------
> >  2 files changed, 108 insertions(+), 108 deletions(-)
> >
> > diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
> > index 4066b014f6e..ceb0c75f559 100644
> > --- a/gcc/cp/tree.cc
> > +++ b/gcc/cp/tree.cc
> > @@ -5441,7 +5441,8 @@ tree
> >  cp_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 t = *tp;
> > +  enum tree_code code = TREE_CODE (t);
> >    tree result;
> >
> >  #define WALK_SUBTREE(NODE)                             \
> > @@ -5452,7 +5453,7 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
> >      }                                                  \
> >    while (0)
> >
> > -  if (TYPE_P (*tp))
> > +  if (TYPE_P (t))
> >      {
> >        /* 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
> > @@ -5464,15 +5465,15 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
> >
> >          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))
> > +      if (*walk_subtrees_p == 1 && typedef_variant_p (t))
> >         {
> > -         if (tree ti = TYPE_ALIAS_TEMPLATE_INFO (*tp))
> > +         if (tree ti = TYPE_ALIAS_TEMPLATE_INFO (t))
> >             WALK_SUBTREE (TI_ARGS (ti));
> >           *walk_subtrees_p = 0;
> >           return NULL_TREE;
> >         }
> >
> > -      if (tree ti = TYPE_TEMPLATE_INFO (*tp))
> > +      if (tree ti = TYPE_TEMPLATE_INFO (t))
> >         WALK_SUBTREE (TI_ARGS (ti));
> >      }
> >
> > @@ -5482,8 +5483,8 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
> >    switch (code)
> >      {
> >      case TEMPLATE_TYPE_PARM:
> > -      if (template_placeholder_p (*tp))
> > -       WALK_SUBTREE (CLASS_PLACEHOLDER_TEMPLATE (*tp));
> > +      if (template_placeholder_p (t))
> > +       WALK_SUBTREE (CLASS_PLACEHOLDER_TEMPLATE (t));
> >        /* Fall through.  */
> >      case DEFERRED_PARSE:
> >      case TEMPLATE_TEMPLATE_PARM:
> > @@ -5497,63 +5498,63 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
> >        break;
> >
> >      case TYPENAME_TYPE:
> > -      WALK_SUBTREE (TYPE_CONTEXT (*tp));
> > -      WALK_SUBTREE (TYPENAME_TYPE_FULLNAME (*tp));
> > +      WALK_SUBTREE (TYPE_CONTEXT (t));
> > +      WALK_SUBTREE (TYPENAME_TYPE_FULLNAME (t));
> >        *walk_subtrees_p = 0;
> >        break;
> >
> >      case BASELINK:
> > -      if (BASELINK_QUALIFIED_P (*tp))
> > -       WALK_SUBTREE (BINFO_TYPE (BASELINK_ACCESS_BINFO (*tp)));
> > -      WALK_SUBTREE (BASELINK_FUNCTIONS (*tp));
> > +      if (BASELINK_QUALIFIED_P (t))
> > +       WALK_SUBTREE (BINFO_TYPE (BASELINK_ACCESS_BINFO (t)));
> > +      WALK_SUBTREE (BASELINK_FUNCTIONS (t));
> >        *walk_subtrees_p = 0;
> >        break;
> >
> >      case PTRMEM_CST:
> > -      WALK_SUBTREE (TREE_TYPE (*tp));
> > +      WALK_SUBTREE (TREE_TYPE (t));
> >        *walk_subtrees_p = 0;
> >        break;
> >
> >      case TREE_LIST:
> > -      WALK_SUBTREE (TREE_PURPOSE (*tp));
> > +      WALK_SUBTREE (TREE_PURPOSE (t));
> >        break;
> >
> >      case OVERLOAD:
> > -      WALK_SUBTREE (OVL_FUNCTION (*tp));
> > -      WALK_SUBTREE (OVL_CHAIN (*tp));
> > +      WALK_SUBTREE (OVL_FUNCTION (t));
> > +      WALK_SUBTREE (OVL_CHAIN (t));
> >        *walk_subtrees_p = 0;
> >        break;
> >
> >      case USING_DECL:
> > -      WALK_SUBTREE (DECL_NAME (*tp));
> > -      WALK_SUBTREE (USING_DECL_SCOPE (*tp));
> > -      WALK_SUBTREE (USING_DECL_DECLS (*tp));
> > +      WALK_SUBTREE (DECL_NAME (t));
> > +      WALK_SUBTREE (USING_DECL_SCOPE (t));
> > +      WALK_SUBTREE (USING_DECL_DECLS (t));
> >        *walk_subtrees_p = 0;
> >        break;
> >
> >      case RECORD_TYPE:
> > -      if (TYPE_PTRMEMFUNC_P (*tp))
> > -       WALK_SUBTREE (TYPE_PTRMEMFUNC_FN_TYPE_RAW (*tp));
> > +      if (TYPE_PTRMEMFUNC_P (t))
> > +       WALK_SUBTREE (TYPE_PTRMEMFUNC_FN_TYPE_RAW (t));
> >        break;
> >
> >      case TYPE_ARGUMENT_PACK:
> >      case NONTYPE_ARGUMENT_PACK:
> >        {
> > -        tree args = ARGUMENT_PACK_ARGS (*tp);
> > +       tree args = ARGUMENT_PACK_ARGS (t);
> >         for (tree arg : tree_vec_range (args))
> >           WALK_SUBTREE (arg);
> >        }
> >        break;
> >
> >      case TYPE_PACK_EXPANSION:
> > -      WALK_SUBTREE (TREE_TYPE (*tp));
> > -      WALK_SUBTREE (PACK_EXPANSION_EXTRA_ARGS (*tp));
> > +      WALK_SUBTREE (TREE_TYPE (t));
> > +      WALK_SUBTREE (PACK_EXPANSION_EXTRA_ARGS (t));
> >        *walk_subtrees_p = 0;
> >        break;
> >
> >      case EXPR_PACK_EXPANSION:
> > -      WALK_SUBTREE (TREE_OPERAND (*tp, 0));
> > -      WALK_SUBTREE (PACK_EXPANSION_EXTRA_ARGS (*tp));
> > +      WALK_SUBTREE (TREE_OPERAND (t, 0));
> > +      WALK_SUBTREE (PACK_EXPANSION_EXTRA_ARGS (t));
> >        *walk_subtrees_p = 0;
> >        break;
> >
> > @@ -5564,31 +5565,31 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
> >      case DYNAMIC_CAST_EXPR:
> >      case IMPLICIT_CONV_EXPR:
> >      case BIT_CAST_EXPR:
> > -      if (TREE_TYPE (*tp))
> > -       WALK_SUBTREE (TREE_TYPE (*tp));
> > +      if (TREE_TYPE (t))
> > +       WALK_SUBTREE (TREE_TYPE (t));
> >        break;
> >
> >      case CONSTRUCTOR:
> > -      if (COMPOUND_LITERAL_P (*tp))
> > -       WALK_SUBTREE (TREE_TYPE (*tp));
> > +      if (COMPOUND_LITERAL_P (t))
> > +       WALK_SUBTREE (TREE_TYPE (t));
> >        break;
> >
> >      case TRAIT_EXPR:
> > -      WALK_SUBTREE (TRAIT_EXPR_TYPE1 (*tp));
> > -      WALK_SUBTREE (TRAIT_EXPR_TYPE2 (*tp));
> > +      WALK_SUBTREE (TRAIT_EXPR_TYPE1 (t));
> > +      WALK_SUBTREE (TRAIT_EXPR_TYPE2 (t));
> >        *walk_subtrees_p = 0;
> >        break;
> >
> >      case TRAIT_TYPE:
> > -      WALK_SUBTREE (TRAIT_TYPE_TYPE1 (*tp));
> > -      WALK_SUBTREE (TRAIT_TYPE_TYPE2 (*tp));
> > +      WALK_SUBTREE (TRAIT_TYPE_TYPE1 (t));
> > +      WALK_SUBTREE (TRAIT_TYPE_TYPE2 (t));
> >        *walk_subtrees_p = 0;
> >        break;
> >
> >      case DECLTYPE_TYPE:
> >        ++cp_unevaluated_operand;
> >        /* We can't use WALK_SUBTREE here because of the goto.  */
> > -      result = cp_walk_tree (&DECLTYPE_TYPE_EXPR (*tp), func, data, pset);
> > +      result = cp_walk_tree (&DECLTYPE_TYPE_EXPR (t), func, data, pset);
> >        --cp_unevaluated_operand;
> >        *walk_subtrees_p = 0;
> >        break;
> > @@ -5597,7 +5598,7 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
> >      case SIZEOF_EXPR:
> >      case NOEXCEPT_EXPR:
> >        ++cp_unevaluated_operand;
> > -      result = cp_walk_tree (&TREE_OPERAND (*tp, 0), func, data, pset);
> > +      result = cp_walk_tree (&TREE_OPERAND (t, 0), func, data, pset);
> >        --cp_unevaluated_operand;
> >        *walk_subtrees_p = 0;
> >        break;
> > @@ -5605,12 +5606,12 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
> >      case REQUIRES_EXPR:
> >        {
> >         cp_unevaluated u;
> > -       for (tree parm = REQUIRES_EXPR_PARMS (*tp); parm; parm = DECL_CHAIN (parm))
> > +       for (tree parm = REQUIRES_EXPR_PARMS (t); parm; parm = DECL_CHAIN (parm))
> >           /* Walk the types of each parameter, but not the parameter itself.
> >              Doing so would cause false positives in the unexpanded parameter
> >              pack checker since an introduced parameter pack looks bare.  */
> >           WALK_SUBTREE (TREE_TYPE (parm));
> > -       WALK_SUBTREE (REQUIRES_EXPR_REQS (*tp));
> > +       WALK_SUBTREE (REQUIRES_EXPR_REQS (t));
> >         *walk_subtrees_p = 0;
> >         break;
> >        }
> > @@ -5621,12 +5622,12 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
> >          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))
> > +      if (VAR_P (TREE_OPERAND (t, 0))
> >           && (processing_template_decl
> > -             || (DECL_ARTIFICIAL (TREE_OPERAND (*tp, 0))
> > -                 && !TREE_STATIC (TREE_OPERAND (*tp, 0)))))
> > +             || (DECL_ARTIFICIAL (TREE_OPERAND (t, 0))
> > +                 && !TREE_STATIC (TREE_OPERAND (t, 0)))))
> >         {
> > -         tree decl = TREE_OPERAND (*tp, 0);
> > +         tree decl = TREE_OPERAND (t, 0);
> >           WALK_SUBTREE (DECL_INITIAL (decl));
> >           WALK_SUBTREE (DECL_SIZE (decl));
> >           WALK_SUBTREE (DECL_SIZE_UNIT (decl));
> > @@ -5636,45 +5637,45 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
> >      case LAMBDA_EXPR:
> >        /* Don't walk into the body of the lambda, but the capture initializers
> >          are part of the enclosing context.  */
> > -      for (tree cap = LAMBDA_EXPR_CAPTURE_LIST (*tp); cap;
> > +      for (tree cap = LAMBDA_EXPR_CAPTURE_LIST (t); cap;
> >            cap = TREE_CHAIN (cap))
> >         WALK_SUBTREE (TREE_VALUE (cap));
> >        break;
> >
> >      case CO_YIELD_EXPR:
> > -      if (TREE_OPERAND (*tp, 1))
> > +      if (TREE_OPERAND (t, 1))
> >         /* Operand 1 is the tree for the relevant co_await which has any
> >            interesting sub-trees.  */
> > -       WALK_SUBTREE (TREE_OPERAND (*tp, 1));
> > +       WALK_SUBTREE (TREE_OPERAND (t, 1));
> >        break;
> >
> >      case CO_AWAIT_EXPR:
> > -      if (TREE_OPERAND (*tp, 1))
> > +      if (TREE_OPERAND (t, 1))
> >         /* Operand 1 is frame variable.  */
> > -       WALK_SUBTREE (TREE_OPERAND (*tp, 1));
> > -      if (TREE_OPERAND (*tp, 2))
> > +       WALK_SUBTREE (TREE_OPERAND (t, 1));
> > +      if (TREE_OPERAND (t, 2))
> >         /* Operand 2 has the initialiser, and we need to walk any subtrees
> >            there.  */
> > -       WALK_SUBTREE (TREE_OPERAND (*tp, 2));
> > +       WALK_SUBTREE (TREE_OPERAND (t, 2));
> >        break;
> >
> >      case CO_RETURN_EXPR:
> > -      if (TREE_OPERAND (*tp, 0))
> > +      if (TREE_OPERAND (t, 0))
> >         {
> > -         if (VOID_TYPE_P (TREE_OPERAND (*tp, 0)))
> > +         if (VOID_TYPE_P (TREE_OPERAND (t, 0)))
> >             /* For void expressions, operand 1 is a trivial call, and any
> >                interesting subtrees will be part of operand 0.  */
> > -           WALK_SUBTREE (TREE_OPERAND (*tp, 0));
> > -         else if (TREE_OPERAND (*tp, 1))
> > +           WALK_SUBTREE (TREE_OPERAND (t, 0));
> > +         else if (TREE_OPERAND (t, 1))
> >             /* Interesting sub-trees will be in the return_value () call
> >                arguments.  */
> > -           WALK_SUBTREE (TREE_OPERAND (*tp, 1));
> > +           WALK_SUBTREE (TREE_OPERAND (t, 1));
> >         }
> >        break;
> >
> >      case STATIC_ASSERT:
> > -      WALK_SUBTREE (STATIC_ASSERT_CONDITION (*tp));
> > -      WALK_SUBTREE (STATIC_ASSERT_MESSAGE (*tp));
> > +      WALK_SUBTREE (STATIC_ASSERT_CONDITION (t));
> > +      WALK_SUBTREE (STATIC_ASSERT_MESSAGE (t));
> >        break;
> >
> >      default:
> > diff --git a/gcc/tree.cc b/gcc/tree.cc
> > index 5eb6a49da31..dfada652570 100644
> > --- a/gcc/tree.cc
> > +++ b/gcc/tree.cc
> > @@ -11218,10 +11218,6 @@ tree
> >  walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
> >              hash_set<tree> *pset, walk_tree_lh lh)
> >  {
> > -  enum tree_code code;
> > -  int walk_subtrees;
> > -  tree result;
> > -
> >  #define WALK_SUBTREE_TAIL(NODE)                                \
> >    do                                                   \
> >      {                                                  \
> > @@ -11241,14 +11237,15 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
> >      return NULL_TREE;
> >
> >    /* Call the function.  */
> > -  walk_subtrees = 1;
> > -  result = (*func) (tp, &walk_subtrees, data);
> > +  int walk_subtrees = 1;
> > +  tree result = (*func) (tp, &walk_subtrees, data);
> >
> >    /* If we found something, return it.  */
> >    if (result)
> >      return result;
> >
> > -  code = TREE_CODE (*tp);
> > +  tree t = *tp;
> > +  tree_code code = TREE_CODE (t);
> >
> >    /* Even if we didn't, FUNC may have decided that there was nothing
> >       interesting below this point in the tree.  */
> > @@ -11256,9 +11253,9 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
> >      {
> >        /* But we still need to check our siblings.  */
> >        if (code == TREE_LIST)
> > -       WALK_SUBTREE_TAIL (TREE_CHAIN (*tp));
> > +       WALK_SUBTREE_TAIL (TREE_CHAIN (t));
> >        else if (code == OMP_CLAUSE)
> > -       WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp));
> > +       WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (t));
> >        else
> >         return NULL_TREE;
> >      }
> > @@ -11288,58 +11285,58 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
> >        break;
> >
> >      case TREE_LIST:
> > -      WALK_SUBTREE (TREE_VALUE (*tp));
> > -      WALK_SUBTREE_TAIL (TREE_CHAIN (*tp));
> > +      WALK_SUBTREE (TREE_VALUE (t));
> > +      WALK_SUBTREE_TAIL (TREE_CHAIN (t));
> >
> >      case TREE_VEC:
> >        {
> > -       int len = TREE_VEC_LENGTH (*tp);
> > +       int len = TREE_VEC_LENGTH (t);
> >
> >         if (len == 0)
> >           break;
> >
> >         /* Walk all elements but the first.  */
> >         while (--len)
> > -         WALK_SUBTREE (TREE_VEC_ELT (*tp, len));
> > +         WALK_SUBTREE (TREE_VEC_ELT (t, len));
> >
> >         /* Now walk the first one as a tail call.  */
> > -       WALK_SUBTREE_TAIL (TREE_VEC_ELT (*tp, 0));
> > +       WALK_SUBTREE_TAIL (TREE_VEC_ELT (t, 0));
> >        }
> >
> >      case VECTOR_CST:
> >        {
> > -       unsigned len = vector_cst_encoded_nelts (*tp);
> > +       unsigned len = vector_cst_encoded_nelts (t);
> >         if (len == 0)
> >           break;
> >         /* Walk all elements but the first.  */
> >         while (--len)
> > -         WALK_SUBTREE (VECTOR_CST_ENCODED_ELT (*tp, len));
> > +         WALK_SUBTREE (VECTOR_CST_ENCODED_ELT (t, len));
> >         /* Now walk the first one as a tail call.  */
> > -       WALK_SUBTREE_TAIL (VECTOR_CST_ENCODED_ELT (*tp, 0));
> > +       WALK_SUBTREE_TAIL (VECTOR_CST_ENCODED_ELT (t, 0));
> >        }
> >
> >      case COMPLEX_CST:
> > -      WALK_SUBTREE (TREE_REALPART (*tp));
> > -      WALK_SUBTREE_TAIL (TREE_IMAGPART (*tp));
> > +      WALK_SUBTREE (TREE_REALPART (t));
> > +      WALK_SUBTREE_TAIL (TREE_IMAGPART (t));
> >
> >      case CONSTRUCTOR:
> >        {
> >         unsigned HOST_WIDE_INT idx;
> >         constructor_elt *ce;
> >
> > -       for (idx = 0; vec_safe_iterate (CONSTRUCTOR_ELTS (*tp), idx, &ce);
> > +       for (idx = 0; vec_safe_iterate (CONSTRUCTOR_ELTS (t), idx, &ce);
> >              idx++)
> >           WALK_SUBTREE (ce->value);
> >        }
> >        break;
> >
> >      case SAVE_EXPR:
> > -      WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, 0));
> > +      WALK_SUBTREE_TAIL (TREE_OPERAND (t, 0));
> >
> >      case BIND_EXPR:
> >        {
> >         tree decl;
> > -       for (decl = BIND_EXPR_VARS (*tp); decl; decl = DECL_CHAIN (decl))
> > +       for (decl = BIND_EXPR_VARS (t); decl; decl = DECL_CHAIN (decl))
> >           {
> >             /* Walk the DECL_INITIAL and DECL_SIZE.  We don't want to walk
> >                into declarations that are just mentioned, rather than
> > @@ -11350,23 +11347,23 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
> >             WALK_SUBTREE (DECL_SIZE (decl));
> >             WALK_SUBTREE (DECL_SIZE_UNIT (decl));
> >           }
> > -       WALK_SUBTREE_TAIL (BIND_EXPR_BODY (*tp));
> > +       WALK_SUBTREE_TAIL (BIND_EXPR_BODY (t));
> >        }
> >
> >      case STATEMENT_LIST:
> >        {
> >         tree_stmt_iterator i;
> > -       for (i = tsi_start (*tp); !tsi_end_p (i); tsi_next (&i))
> > +       for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
> >           WALK_SUBTREE (*tsi_stmt_ptr (i));
> >        }
> >        break;
> >
> >      case OMP_CLAUSE:
> >        {
> > -       int len = omp_clause_num_ops[OMP_CLAUSE_CODE (*tp)];
> > +       int len = omp_clause_num_ops[OMP_CLAUSE_CODE (t)];
> >         for (int i = 0; i < len; i++)
> > -         WALK_SUBTREE (OMP_CLAUSE_OPERAND (*tp, i));
> > -       WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp));
> > +         WALK_SUBTREE (OMP_CLAUSE_OPERAND (t, i));
> > +       WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (t));
> >        }
> >
> >      case TARGET_EXPR:
> > @@ -11375,10 +11372,10 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
> >
> >         /* TARGET_EXPRs are peculiar: operands 1 and 3 can be the same.
> >            But, we only want to walk once.  */
> > -       len = (TREE_OPERAND (*tp, 3) == TREE_OPERAND (*tp, 1)) ? 2 : 3;
> > +       len = (TREE_OPERAND (t, 3) == TREE_OPERAND (t, 1)) ? 2 : 3;
> >         for (i = 0; i < len; ++i)
> > -         WALK_SUBTREE (TREE_OPERAND (*tp, i));
> > -       WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, len));
> > +         WALK_SUBTREE (TREE_OPERAND (t, i));
> > +       WALK_SUBTREE_TAIL (TREE_OPERAND (t, len));
> >        }
> >
> >      case DECL_EXPR:
> > @@ -11393,15 +11390,15 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
> >          variable-sized types.
> >
> >          Note that DECLs get walked as part of processing the BIND_EXPR.  */
> > -      if (TREE_CODE (DECL_EXPR_DECL (*tp)) == TYPE_DECL)
> > +      if (TREE_CODE (DECL_EXPR_DECL (t)) == TYPE_DECL)
> >         {
> >           /* Call the function for the decl so e.g. copy_tree_body_r can
> >              replace it with the remapped one.  */
> > -         result = (*func) (&DECL_EXPR_DECL (*tp), &walk_subtrees, data);
> > +         result = (*func) (&DECL_EXPR_DECL (t), &walk_subtrees, data);
> >           if (result || !walk_subtrees)
> >             return result;
> >
> > -         tree *type_p = &TREE_TYPE (DECL_EXPR_DECL (*tp));
> > +         tree *type_p = &TREE_TYPE (DECL_EXPR_DECL (t));
> >           if (TREE_CODE (*type_p) == ERROR_MARK)
> >             return NULL_TREE;
> >
> > @@ -11412,21 +11409,23 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
> >           if (result || !walk_subtrees)
> >             return result;
> >
> > +         tree type = *type_p;
> > +
> >           /* But do not walk a pointed-to type since it may itself need to
> >              be walked in the declaration case if it isn't anonymous.  */
> > -         if (!POINTER_TYPE_P (*type_p))
> > +         if (!POINTER_TYPE_P (type))
> >             {
> > -             result = walk_type_fields (*type_p, func, data, pset, lh);
> > +             result = walk_type_fields (type, func, data, pset, lh);
> >               if (result)
> >                 return result;
> >             }
> >
> >           /* If this is a record type, also walk the fields.  */
> > -         if (RECORD_OR_UNION_TYPE_P (*type_p))
> > +         if (RECORD_OR_UNION_TYPE_P (type))
> >             {
> >               tree field;
> >
> > -             for (field = TYPE_FIELDS (*type_p); field;
> > +             for (field = TYPE_FIELDS (type); field;
> >                    field = DECL_CHAIN (field))
> >                 {
> >                   /* We'd like to look at the type of the field, but we can
> > @@ -11439,24 +11438,24 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
> >                   WALK_SUBTREE (DECL_FIELD_OFFSET (field));
> >                   WALK_SUBTREE (DECL_SIZE (field));
> >                   WALK_SUBTREE (DECL_SIZE_UNIT (field));
> > -                 if (TREE_CODE (*type_p) == QUAL_UNION_TYPE)
> > +                 if (TREE_CODE (type) == QUAL_UNION_TYPE)
> >                     WALK_SUBTREE (DECL_QUALIFIER (field));
> >                 }
> >             }
> >
> >           /* Same for scalar types.  */
> > -         else if (TREE_CODE (*type_p) == BOOLEAN_TYPE
> > -                  || TREE_CODE (*type_p) == ENUMERAL_TYPE
> > -                  || TREE_CODE (*type_p) == INTEGER_TYPE
> > -                  || TREE_CODE (*type_p) == FIXED_POINT_TYPE
> > -                  || TREE_CODE (*type_p) == REAL_TYPE)
> > +         else if (TREE_CODE (type) == BOOLEAN_TYPE
> > +                  || TREE_CODE (type) == ENUMERAL_TYPE
> > +                  || TREE_CODE (type) == INTEGER_TYPE
> > +                  || TREE_CODE (type) == FIXED_POINT_TYPE
> > +                  || TREE_CODE (type) == REAL_TYPE)
> >             {
> > -             WALK_SUBTREE (TYPE_MIN_VALUE (*type_p));
> > -             WALK_SUBTREE (TYPE_MAX_VALUE (*type_p));
> > +             WALK_SUBTREE (TYPE_MIN_VALUE (type));
> > +             WALK_SUBTREE (TYPE_MAX_VALUE (type));
> >             }
> >
> > -         WALK_SUBTREE (TYPE_SIZE (*type_p));
> > -         WALK_SUBTREE_TAIL (TYPE_SIZE_UNIT (*type_p));
> > +         WALK_SUBTREE (TYPE_SIZE (type));
> > +         WALK_SUBTREE_TAIL (TYPE_SIZE_UNIT (type));
> >         }
> >        /* FALLTHRU */
> >
> > @@ -11466,20 +11465,20 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
> >           int i, len;
> >
> >           /* Walk over all the sub-trees of this operand.  */
> > -         len = TREE_OPERAND_LENGTH (*tp);
> > +         len = TREE_OPERAND_LENGTH (t);
> >
> >           /* Go through the subtrees.  We need to do this in forward order so
> >              that the scope of a FOR_EXPR is handled properly.  */
> >           if (len)
> >             {
> >               for (i = 0; i < len - 1; ++i)
> > -               WALK_SUBTREE (TREE_OPERAND (*tp, i));
> > -             WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, len - 1));
> > +               WALK_SUBTREE (TREE_OPERAND (t, i));
> > +             WALK_SUBTREE_TAIL (TREE_OPERAND (t, len - 1));
> >             }
> >         }
> >        /* If this is a type, walk the needed fields in the type.  */
> > -      else if (TYPE_P (*tp))
> > -       return walk_type_fields (*tp, func, data, pset, lh);
> > +      else if (TYPE_P (t))
> > +       return walk_type_fields (t, func, data, pset, lh);
> >        break;
> >      }
> >
> > --
> > 2.39.0.rc0.49.g083e01275b
> >
> 
>
  
Jason Merrill Dec. 5, 2022, 9:09 p.m. UTC | #3
On 12/5/22 06:09, Prathamesh Kulkarni wrote:
> On Mon, 5 Dec 2022 at 09:51, Patrick Palka via Gcc-patches
> <gcc-patches@gcc.gnu.org> wrote:
>>
>> These functions currently repeatedly dereference tp during the subtree
>> walk, dereferences which the compiler can't CSE because it can't
>> guarantee that the subtree walking doesn't modify *tp.
>>
>> But we already implicitly require that TREE_CODE (*tp) remains the same
>> throughout the subtree walks, so it doesn't seem to be a huge leap to
>> strengthen that to requiring *tp remains the same.
> Hi Patrick,
> Just wondering in that case, if marking tp with const_tree *, instead
> of tree *, would perhaps help the compiler
> for CSEing some of the dereferences to *tp ?

That wouldn't make a difference; even if *tp is const, the compiler 
can't be sure that a call won't change it.  And const_tree * doesn't 
even make *tp const, it makes **tp const.

>> So this patch manually CSEs the dereferences of *tp.  This means that
>> the callback function can no longer replace *tp with another tree (of
>> the same TREE_CODE) when walking one of its subtrees, but that doesn't
>> sound like a useful feature anyway.  This speeds up the C++ frontend by
>> about ~1.5% according to my experiments.
>>
>> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
>> trunk stage3 or perhaps for stage1?

OK for stage 1.

>> gcc/cp/ChangeLog:
>>
>>          * tree.cc (cp_walk_subtrees): Avoid repeatedly dereferencing tp.
>>
>> gcc/ChangeLog:
>>
>>          * tree.cc (walk_tree_1): Avoid repeatedly dereferencing tp
>>          and type_p.
>> ---
>>   gcc/cp/tree.cc | 113 +++++++++++++++++++++++++------------------------
>>   gcc/tree.cc    | 103 ++++++++++++++++++++++----------------------
>>   2 files changed, 108 insertions(+), 108 deletions(-)
>>
>> diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
>> index 4066b014f6e..ceb0c75f559 100644
>> --- a/gcc/cp/tree.cc
>> +++ b/gcc/cp/tree.cc
>> @@ -5441,7 +5441,8 @@ tree
>>   cp_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 t = *tp;
>> +  enum tree_code code = TREE_CODE (t);
>>     tree result;
>>
>>   #define WALK_SUBTREE(NODE)                             \
>> @@ -5452,7 +5453,7 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
>>       }                                                  \
>>     while (0)
>>
>> -  if (TYPE_P (*tp))
>> +  if (TYPE_P (t))
>>       {
>>         /* 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
>> @@ -5464,15 +5465,15 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
>>
>>           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))
>> +      if (*walk_subtrees_p == 1 && typedef_variant_p (t))
>>          {
>> -         if (tree ti = TYPE_ALIAS_TEMPLATE_INFO (*tp))
>> +         if (tree ti = TYPE_ALIAS_TEMPLATE_INFO (t))
>>              WALK_SUBTREE (TI_ARGS (ti));
>>            *walk_subtrees_p = 0;
>>            return NULL_TREE;
>>          }
>>
>> -      if (tree ti = TYPE_TEMPLATE_INFO (*tp))
>> +      if (tree ti = TYPE_TEMPLATE_INFO (t))
>>          WALK_SUBTREE (TI_ARGS (ti));
>>       }
>>
>> @@ -5482,8 +5483,8 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
>>     switch (code)
>>       {
>>       case TEMPLATE_TYPE_PARM:
>> -      if (template_placeholder_p (*tp))
>> -       WALK_SUBTREE (CLASS_PLACEHOLDER_TEMPLATE (*tp));
>> +      if (template_placeholder_p (t))
>> +       WALK_SUBTREE (CLASS_PLACEHOLDER_TEMPLATE (t));
>>         /* Fall through.  */
>>       case DEFERRED_PARSE:
>>       case TEMPLATE_TEMPLATE_PARM:
>> @@ -5497,63 +5498,63 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
>>         break;
>>
>>       case TYPENAME_TYPE:
>> -      WALK_SUBTREE (TYPE_CONTEXT (*tp));
>> -      WALK_SUBTREE (TYPENAME_TYPE_FULLNAME (*tp));
>> +      WALK_SUBTREE (TYPE_CONTEXT (t));
>> +      WALK_SUBTREE (TYPENAME_TYPE_FULLNAME (t));
>>         *walk_subtrees_p = 0;
>>         break;
>>
>>       case BASELINK:
>> -      if (BASELINK_QUALIFIED_P (*tp))
>> -       WALK_SUBTREE (BINFO_TYPE (BASELINK_ACCESS_BINFO (*tp)));
>> -      WALK_SUBTREE (BASELINK_FUNCTIONS (*tp));
>> +      if (BASELINK_QUALIFIED_P (t))
>> +       WALK_SUBTREE (BINFO_TYPE (BASELINK_ACCESS_BINFO (t)));
>> +      WALK_SUBTREE (BASELINK_FUNCTIONS (t));
>>         *walk_subtrees_p = 0;
>>         break;
>>
>>       case PTRMEM_CST:
>> -      WALK_SUBTREE (TREE_TYPE (*tp));
>> +      WALK_SUBTREE (TREE_TYPE (t));
>>         *walk_subtrees_p = 0;
>>         break;
>>
>>       case TREE_LIST:
>> -      WALK_SUBTREE (TREE_PURPOSE (*tp));
>> +      WALK_SUBTREE (TREE_PURPOSE (t));
>>         break;
>>
>>       case OVERLOAD:
>> -      WALK_SUBTREE (OVL_FUNCTION (*tp));
>> -      WALK_SUBTREE (OVL_CHAIN (*tp));
>> +      WALK_SUBTREE (OVL_FUNCTION (t));
>> +      WALK_SUBTREE (OVL_CHAIN (t));
>>         *walk_subtrees_p = 0;
>>         break;
>>
>>       case USING_DECL:
>> -      WALK_SUBTREE (DECL_NAME (*tp));
>> -      WALK_SUBTREE (USING_DECL_SCOPE (*tp));
>> -      WALK_SUBTREE (USING_DECL_DECLS (*tp));
>> +      WALK_SUBTREE (DECL_NAME (t));
>> +      WALK_SUBTREE (USING_DECL_SCOPE (t));
>> +      WALK_SUBTREE (USING_DECL_DECLS (t));
>>         *walk_subtrees_p = 0;
>>         break;
>>
>>       case RECORD_TYPE:
>> -      if (TYPE_PTRMEMFUNC_P (*tp))
>> -       WALK_SUBTREE (TYPE_PTRMEMFUNC_FN_TYPE_RAW (*tp));
>> +      if (TYPE_PTRMEMFUNC_P (t))
>> +       WALK_SUBTREE (TYPE_PTRMEMFUNC_FN_TYPE_RAW (t));
>>         break;
>>
>>       case TYPE_ARGUMENT_PACK:
>>       case NONTYPE_ARGUMENT_PACK:
>>         {
>> -        tree args = ARGUMENT_PACK_ARGS (*tp);
>> +       tree args = ARGUMENT_PACK_ARGS (t);
>>          for (tree arg : tree_vec_range (args))
>>            WALK_SUBTREE (arg);
>>         }
>>         break;
>>
>>       case TYPE_PACK_EXPANSION:
>> -      WALK_SUBTREE (TREE_TYPE (*tp));
>> -      WALK_SUBTREE (PACK_EXPANSION_EXTRA_ARGS (*tp));
>> +      WALK_SUBTREE (TREE_TYPE (t));
>> +      WALK_SUBTREE (PACK_EXPANSION_EXTRA_ARGS (t));
>>         *walk_subtrees_p = 0;
>>         break;
>>
>>       case EXPR_PACK_EXPANSION:
>> -      WALK_SUBTREE (TREE_OPERAND (*tp, 0));
>> -      WALK_SUBTREE (PACK_EXPANSION_EXTRA_ARGS (*tp));
>> +      WALK_SUBTREE (TREE_OPERAND (t, 0));
>> +      WALK_SUBTREE (PACK_EXPANSION_EXTRA_ARGS (t));
>>         *walk_subtrees_p = 0;
>>         break;
>>
>> @@ -5564,31 +5565,31 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
>>       case DYNAMIC_CAST_EXPR:
>>       case IMPLICIT_CONV_EXPR:
>>       case BIT_CAST_EXPR:
>> -      if (TREE_TYPE (*tp))
>> -       WALK_SUBTREE (TREE_TYPE (*tp));
>> +      if (TREE_TYPE (t))
>> +       WALK_SUBTREE (TREE_TYPE (t));
>>         break;
>>
>>       case CONSTRUCTOR:
>> -      if (COMPOUND_LITERAL_P (*tp))
>> -       WALK_SUBTREE (TREE_TYPE (*tp));
>> +      if (COMPOUND_LITERAL_P (t))
>> +       WALK_SUBTREE (TREE_TYPE (t));
>>         break;
>>
>>       case TRAIT_EXPR:
>> -      WALK_SUBTREE (TRAIT_EXPR_TYPE1 (*tp));
>> -      WALK_SUBTREE (TRAIT_EXPR_TYPE2 (*tp));
>> +      WALK_SUBTREE (TRAIT_EXPR_TYPE1 (t));
>> +      WALK_SUBTREE (TRAIT_EXPR_TYPE2 (t));
>>         *walk_subtrees_p = 0;
>>         break;
>>
>>       case TRAIT_TYPE:
>> -      WALK_SUBTREE (TRAIT_TYPE_TYPE1 (*tp));
>> -      WALK_SUBTREE (TRAIT_TYPE_TYPE2 (*tp));
>> +      WALK_SUBTREE (TRAIT_TYPE_TYPE1 (t));
>> +      WALK_SUBTREE (TRAIT_TYPE_TYPE2 (t));
>>         *walk_subtrees_p = 0;
>>         break;
>>
>>       case DECLTYPE_TYPE:
>>         ++cp_unevaluated_operand;
>>         /* We can't use WALK_SUBTREE here because of the goto.  */
>> -      result = cp_walk_tree (&DECLTYPE_TYPE_EXPR (*tp), func, data, pset);
>> +      result = cp_walk_tree (&DECLTYPE_TYPE_EXPR (t), func, data, pset);
>>         --cp_unevaluated_operand;
>>         *walk_subtrees_p = 0;
>>         break;
>> @@ -5597,7 +5598,7 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
>>       case SIZEOF_EXPR:
>>       case NOEXCEPT_EXPR:
>>         ++cp_unevaluated_operand;
>> -      result = cp_walk_tree (&TREE_OPERAND (*tp, 0), func, data, pset);
>> +      result = cp_walk_tree (&TREE_OPERAND (t, 0), func, data, pset);
>>         --cp_unevaluated_operand;
>>         *walk_subtrees_p = 0;
>>         break;
>> @@ -5605,12 +5606,12 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
>>       case REQUIRES_EXPR:
>>         {
>>          cp_unevaluated u;
>> -       for (tree parm = REQUIRES_EXPR_PARMS (*tp); parm; parm = DECL_CHAIN (parm))
>> +       for (tree parm = REQUIRES_EXPR_PARMS (t); parm; parm = DECL_CHAIN (parm))
>>            /* Walk the types of each parameter, but not the parameter itself.
>>               Doing so would cause false positives in the unexpanded parameter
>>               pack checker since an introduced parameter pack looks bare.  */
>>            WALK_SUBTREE (TREE_TYPE (parm));
>> -       WALK_SUBTREE (REQUIRES_EXPR_REQS (*tp));
>> +       WALK_SUBTREE (REQUIRES_EXPR_REQS (t));
>>          *walk_subtrees_p = 0;
>>          break;
>>         }
>> @@ -5621,12 +5622,12 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
>>           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))
>> +      if (VAR_P (TREE_OPERAND (t, 0))
>>            && (processing_template_decl
>> -             || (DECL_ARTIFICIAL (TREE_OPERAND (*tp, 0))
>> -                 && !TREE_STATIC (TREE_OPERAND (*tp, 0)))))
>> +             || (DECL_ARTIFICIAL (TREE_OPERAND (t, 0))
>> +                 && !TREE_STATIC (TREE_OPERAND (t, 0)))))
>>          {
>> -         tree decl = TREE_OPERAND (*tp, 0);
>> +         tree decl = TREE_OPERAND (t, 0);
>>            WALK_SUBTREE (DECL_INITIAL (decl));
>>            WALK_SUBTREE (DECL_SIZE (decl));
>>            WALK_SUBTREE (DECL_SIZE_UNIT (decl));
>> @@ -5636,45 +5637,45 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
>>       case LAMBDA_EXPR:
>>         /* Don't walk into the body of the lambda, but the capture initializers
>>           are part of the enclosing context.  */
>> -      for (tree cap = LAMBDA_EXPR_CAPTURE_LIST (*tp); cap;
>> +      for (tree cap = LAMBDA_EXPR_CAPTURE_LIST (t); cap;
>>             cap = TREE_CHAIN (cap))
>>          WALK_SUBTREE (TREE_VALUE (cap));
>>         break;
>>
>>       case CO_YIELD_EXPR:
>> -      if (TREE_OPERAND (*tp, 1))
>> +      if (TREE_OPERAND (t, 1))
>>          /* Operand 1 is the tree for the relevant co_await which has any
>>             interesting sub-trees.  */
>> -       WALK_SUBTREE (TREE_OPERAND (*tp, 1));
>> +       WALK_SUBTREE (TREE_OPERAND (t, 1));
>>         break;
>>
>>       case CO_AWAIT_EXPR:
>> -      if (TREE_OPERAND (*tp, 1))
>> +      if (TREE_OPERAND (t, 1))
>>          /* Operand 1 is frame variable.  */
>> -       WALK_SUBTREE (TREE_OPERAND (*tp, 1));
>> -      if (TREE_OPERAND (*tp, 2))
>> +       WALK_SUBTREE (TREE_OPERAND (t, 1));
>> +      if (TREE_OPERAND (t, 2))
>>          /* Operand 2 has the initialiser, and we need to walk any subtrees
>>             there.  */
>> -       WALK_SUBTREE (TREE_OPERAND (*tp, 2));
>> +       WALK_SUBTREE (TREE_OPERAND (t, 2));
>>         break;
>>
>>       case CO_RETURN_EXPR:
>> -      if (TREE_OPERAND (*tp, 0))
>> +      if (TREE_OPERAND (t, 0))
>>          {
>> -         if (VOID_TYPE_P (TREE_OPERAND (*tp, 0)))
>> +         if (VOID_TYPE_P (TREE_OPERAND (t, 0)))
>>              /* For void expressions, operand 1 is a trivial call, and any
>>                 interesting subtrees will be part of operand 0.  */
>> -           WALK_SUBTREE (TREE_OPERAND (*tp, 0));
>> -         else if (TREE_OPERAND (*tp, 1))
>> +           WALK_SUBTREE (TREE_OPERAND (t, 0));
>> +         else if (TREE_OPERAND (t, 1))
>>              /* Interesting sub-trees will be in the return_value () call
>>                 arguments.  */
>> -           WALK_SUBTREE (TREE_OPERAND (*tp, 1));
>> +           WALK_SUBTREE (TREE_OPERAND (t, 1));
>>          }
>>         break;
>>
>>       case STATIC_ASSERT:
>> -      WALK_SUBTREE (STATIC_ASSERT_CONDITION (*tp));
>> -      WALK_SUBTREE (STATIC_ASSERT_MESSAGE (*tp));
>> +      WALK_SUBTREE (STATIC_ASSERT_CONDITION (t));
>> +      WALK_SUBTREE (STATIC_ASSERT_MESSAGE (t));
>>         break;
>>
>>       default:
>> diff --git a/gcc/tree.cc b/gcc/tree.cc
>> index 5eb6a49da31..dfada652570 100644
>> --- a/gcc/tree.cc
>> +++ b/gcc/tree.cc
>> @@ -11218,10 +11218,6 @@ tree
>>   walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
>>               hash_set<tree> *pset, walk_tree_lh lh)
>>   {
>> -  enum tree_code code;
>> -  int walk_subtrees;
>> -  tree result;
>> -
>>   #define WALK_SUBTREE_TAIL(NODE)                                \
>>     do                                                   \
>>       {                                                  \
>> @@ -11241,14 +11237,15 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
>>       return NULL_TREE;
>>
>>     /* Call the function.  */
>> -  walk_subtrees = 1;
>> -  result = (*func) (tp, &walk_subtrees, data);
>> +  int walk_subtrees = 1;
>> +  tree result = (*func) (tp, &walk_subtrees, data);
>>
>>     /* If we found something, return it.  */
>>     if (result)
>>       return result;
>>
>> -  code = TREE_CODE (*tp);
>> +  tree t = *tp;
>> +  tree_code code = TREE_CODE (t);
>>
>>     /* Even if we didn't, FUNC may have decided that there was nothing
>>        interesting below this point in the tree.  */
>> @@ -11256,9 +11253,9 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
>>       {
>>         /* But we still need to check our siblings.  */
>>         if (code == TREE_LIST)
>> -       WALK_SUBTREE_TAIL (TREE_CHAIN (*tp));
>> +       WALK_SUBTREE_TAIL (TREE_CHAIN (t));
>>         else if (code == OMP_CLAUSE)
>> -       WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp));
>> +       WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (t));
>>         else
>>          return NULL_TREE;
>>       }
>> @@ -11288,58 +11285,58 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
>>         break;
>>
>>       case TREE_LIST:
>> -      WALK_SUBTREE (TREE_VALUE (*tp));
>> -      WALK_SUBTREE_TAIL (TREE_CHAIN (*tp));
>> +      WALK_SUBTREE (TREE_VALUE (t));
>> +      WALK_SUBTREE_TAIL (TREE_CHAIN (t));
>>
>>       case TREE_VEC:
>>         {
>> -       int len = TREE_VEC_LENGTH (*tp);
>> +       int len = TREE_VEC_LENGTH (t);
>>
>>          if (len == 0)
>>            break;
>>
>>          /* Walk all elements but the first.  */
>>          while (--len)
>> -         WALK_SUBTREE (TREE_VEC_ELT (*tp, len));
>> +         WALK_SUBTREE (TREE_VEC_ELT (t, len));
>>
>>          /* Now walk the first one as a tail call.  */
>> -       WALK_SUBTREE_TAIL (TREE_VEC_ELT (*tp, 0));
>> +       WALK_SUBTREE_TAIL (TREE_VEC_ELT (t, 0));
>>         }
>>
>>       case VECTOR_CST:
>>         {
>> -       unsigned len = vector_cst_encoded_nelts (*tp);
>> +       unsigned len = vector_cst_encoded_nelts (t);
>>          if (len == 0)
>>            break;
>>          /* Walk all elements but the first.  */
>>          while (--len)
>> -         WALK_SUBTREE (VECTOR_CST_ENCODED_ELT (*tp, len));
>> +         WALK_SUBTREE (VECTOR_CST_ENCODED_ELT (t, len));
>>          /* Now walk the first one as a tail call.  */
>> -       WALK_SUBTREE_TAIL (VECTOR_CST_ENCODED_ELT (*tp, 0));
>> +       WALK_SUBTREE_TAIL (VECTOR_CST_ENCODED_ELT (t, 0));
>>         }
>>
>>       case COMPLEX_CST:
>> -      WALK_SUBTREE (TREE_REALPART (*tp));
>> -      WALK_SUBTREE_TAIL (TREE_IMAGPART (*tp));
>> +      WALK_SUBTREE (TREE_REALPART (t));
>> +      WALK_SUBTREE_TAIL (TREE_IMAGPART (t));
>>
>>       case CONSTRUCTOR:
>>         {
>>          unsigned HOST_WIDE_INT idx;
>>          constructor_elt *ce;
>>
>> -       for (idx = 0; vec_safe_iterate (CONSTRUCTOR_ELTS (*tp), idx, &ce);
>> +       for (idx = 0; vec_safe_iterate (CONSTRUCTOR_ELTS (t), idx, &ce);
>>               idx++)
>>            WALK_SUBTREE (ce->value);
>>         }
>>         break;
>>
>>       case SAVE_EXPR:
>> -      WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, 0));
>> +      WALK_SUBTREE_TAIL (TREE_OPERAND (t, 0));
>>
>>       case BIND_EXPR:
>>         {
>>          tree decl;
>> -       for (decl = BIND_EXPR_VARS (*tp); decl; decl = DECL_CHAIN (decl))
>> +       for (decl = BIND_EXPR_VARS (t); decl; decl = DECL_CHAIN (decl))
>>            {
>>              /* Walk the DECL_INITIAL and DECL_SIZE.  We don't want to walk
>>                 into declarations that are just mentioned, rather than
>> @@ -11350,23 +11347,23 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
>>              WALK_SUBTREE (DECL_SIZE (decl));
>>              WALK_SUBTREE (DECL_SIZE_UNIT (decl));
>>            }
>> -       WALK_SUBTREE_TAIL (BIND_EXPR_BODY (*tp));
>> +       WALK_SUBTREE_TAIL (BIND_EXPR_BODY (t));
>>         }
>>
>>       case STATEMENT_LIST:
>>         {
>>          tree_stmt_iterator i;
>> -       for (i = tsi_start (*tp); !tsi_end_p (i); tsi_next (&i))
>> +       for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
>>            WALK_SUBTREE (*tsi_stmt_ptr (i));
>>         }
>>         break;
>>
>>       case OMP_CLAUSE:
>>         {
>> -       int len = omp_clause_num_ops[OMP_CLAUSE_CODE (*tp)];
>> +       int len = omp_clause_num_ops[OMP_CLAUSE_CODE (t)];
>>          for (int i = 0; i < len; i++)
>> -         WALK_SUBTREE (OMP_CLAUSE_OPERAND (*tp, i));
>> -       WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp));
>> +         WALK_SUBTREE (OMP_CLAUSE_OPERAND (t, i));
>> +       WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (t));
>>         }
>>
>>       case TARGET_EXPR:
>> @@ -11375,10 +11372,10 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
>>
>>          /* TARGET_EXPRs are peculiar: operands 1 and 3 can be the same.
>>             But, we only want to walk once.  */
>> -       len = (TREE_OPERAND (*tp, 3) == TREE_OPERAND (*tp, 1)) ? 2 : 3;
>> +       len = (TREE_OPERAND (t, 3) == TREE_OPERAND (t, 1)) ? 2 : 3;
>>          for (i = 0; i < len; ++i)
>> -         WALK_SUBTREE (TREE_OPERAND (*tp, i));
>> -       WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, len));
>> +         WALK_SUBTREE (TREE_OPERAND (t, i));
>> +       WALK_SUBTREE_TAIL (TREE_OPERAND (t, len));
>>         }
>>
>>       case DECL_EXPR:
>> @@ -11393,15 +11390,15 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
>>           variable-sized types.
>>
>>           Note that DECLs get walked as part of processing the BIND_EXPR.  */
>> -      if (TREE_CODE (DECL_EXPR_DECL (*tp)) == TYPE_DECL)
>> +      if (TREE_CODE (DECL_EXPR_DECL (t)) == TYPE_DECL)
>>          {
>>            /* Call the function for the decl so e.g. copy_tree_body_r can
>>               replace it with the remapped one.  */
>> -         result = (*func) (&DECL_EXPR_DECL (*tp), &walk_subtrees, data);
>> +         result = (*func) (&DECL_EXPR_DECL (t), &walk_subtrees, data);
>>            if (result || !walk_subtrees)
>>              return result;
>>
>> -         tree *type_p = &TREE_TYPE (DECL_EXPR_DECL (*tp));
>> +         tree *type_p = &TREE_TYPE (DECL_EXPR_DECL (t));
>>            if (TREE_CODE (*type_p) == ERROR_MARK)
>>              return NULL_TREE;
>>
>> @@ -11412,21 +11409,23 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
>>            if (result || !walk_subtrees)
>>              return result;
>>
>> +         tree type = *type_p;
>> +
>>            /* But do not walk a pointed-to type since it may itself need to
>>               be walked in the declaration case if it isn't anonymous.  */
>> -         if (!POINTER_TYPE_P (*type_p))
>> +         if (!POINTER_TYPE_P (type))
>>              {
>> -             result = walk_type_fields (*type_p, func, data, pset, lh);
>> +             result = walk_type_fields (type, func, data, pset, lh);
>>                if (result)
>>                  return result;
>>              }
>>
>>            /* If this is a record type, also walk the fields.  */
>> -         if (RECORD_OR_UNION_TYPE_P (*type_p))
>> +         if (RECORD_OR_UNION_TYPE_P (type))
>>              {
>>                tree field;
>>
>> -             for (field = TYPE_FIELDS (*type_p); field;
>> +             for (field = TYPE_FIELDS (type); field;
>>                     field = DECL_CHAIN (field))
>>                  {
>>                    /* We'd like to look at the type of the field, but we can
>> @@ -11439,24 +11438,24 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
>>                    WALK_SUBTREE (DECL_FIELD_OFFSET (field));
>>                    WALK_SUBTREE (DECL_SIZE (field));
>>                    WALK_SUBTREE (DECL_SIZE_UNIT (field));
>> -                 if (TREE_CODE (*type_p) == QUAL_UNION_TYPE)
>> +                 if (TREE_CODE (type) == QUAL_UNION_TYPE)
>>                      WALK_SUBTREE (DECL_QUALIFIER (field));
>>                  }
>>              }
>>
>>            /* Same for scalar types.  */
>> -         else if (TREE_CODE (*type_p) == BOOLEAN_TYPE
>> -                  || TREE_CODE (*type_p) == ENUMERAL_TYPE
>> -                  || TREE_CODE (*type_p) == INTEGER_TYPE
>> -                  || TREE_CODE (*type_p) == FIXED_POINT_TYPE
>> -                  || TREE_CODE (*type_p) == REAL_TYPE)
>> +         else if (TREE_CODE (type) == BOOLEAN_TYPE
>> +                  || TREE_CODE (type) == ENUMERAL_TYPE
>> +                  || TREE_CODE (type) == INTEGER_TYPE
>> +                  || TREE_CODE (type) == FIXED_POINT_TYPE
>> +                  || TREE_CODE (type) == REAL_TYPE)
>>              {
>> -             WALK_SUBTREE (TYPE_MIN_VALUE (*type_p));
>> -             WALK_SUBTREE (TYPE_MAX_VALUE (*type_p));
>> +             WALK_SUBTREE (TYPE_MIN_VALUE (type));
>> +             WALK_SUBTREE (TYPE_MAX_VALUE (type));
>>              }
>>
>> -         WALK_SUBTREE (TYPE_SIZE (*type_p));
>> -         WALK_SUBTREE_TAIL (TYPE_SIZE_UNIT (*type_p));
>> +         WALK_SUBTREE (TYPE_SIZE (type));
>> +         WALK_SUBTREE_TAIL (TYPE_SIZE_UNIT (type));
>>          }
>>         /* FALLTHRU */
>>
>> @@ -11466,20 +11465,20 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
>>            int i, len;
>>
>>            /* Walk over all the sub-trees of this operand.  */
>> -         len = TREE_OPERAND_LENGTH (*tp);
>> +         len = TREE_OPERAND_LENGTH (t);
>>
>>            /* Go through the subtrees.  We need to do this in forward order so
>>               that the scope of a FOR_EXPR is handled properly.  */
>>            if (len)
>>              {
>>                for (i = 0; i < len - 1; ++i)
>> -               WALK_SUBTREE (TREE_OPERAND (*tp, i));
>> -             WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, len - 1));
>> +               WALK_SUBTREE (TREE_OPERAND (t, i));
>> +             WALK_SUBTREE_TAIL (TREE_OPERAND (t, len - 1));
>>              }
>>          }
>>         /* If this is a type, walk the needed fields in the type.  */
>> -      else if (TYPE_P (*tp))
>> -       return walk_type_fields (*tp, func, data, pset, lh);
>> +      else if (TYPE_P (t))
>> +       return walk_type_fields (t, func, data, pset, lh);
>>         break;
>>       }
>>
>> --
>> 2.39.0.rc0.49.g083e01275b
>>
>
  
Patrick Palka April 21, 2023, 5:03 p.m. UTC | #4
On Mon, 5 Dec 2022, Jason Merrill wrote:

> On 12/5/22 06:09, Prathamesh Kulkarni wrote:
> > On Mon, 5 Dec 2022 at 09:51, Patrick Palka via Gcc-patches
> > <gcc-patches@gcc.gnu.org> wrote:
> > > 
> > > These functions currently repeatedly dereference tp during the subtree
> > > walk, dereferences which the compiler can't CSE because it can't
> > > guarantee that the subtree walking doesn't modify *tp.
> > > 
> > > But we already implicitly require that TREE_CODE (*tp) remains the same
> > > throughout the subtree walks, so it doesn't seem to be a huge leap to
> > > strengthen that to requiring *tp remains the same.
> > Hi Patrick,
> > Just wondering in that case, if marking tp with const_tree *, instead
> > of tree *, would perhaps help the compiler
> > for CSEing some of the dereferences to *tp ?
> 
> That wouldn't make a difference; even if *tp is const, the compiler can't be
> sure that a call won't change it.  And const_tree * doesn't even make *tp
> const, it makes **tp const.
> 
> > > So this patch manually CSEs the dereferences of *tp.  This means that
> > > the callback function can no longer replace *tp with another tree (of
> > > the same TREE_CODE) when walking one of its subtrees, but that doesn't
> > > sound like a useful feature anyway.  This speeds up the C++ frontend by
> > > about ~1.5% according to my experiments.
> > > 
> > > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
> > > trunk stage3 or perhaps for stage1?
> 
> OK for stage 1.

Thanks, I just pushed this along with a drive-by change to
cp_walk_subtrees <case DECLTYPE_TYPE etc> to use cp_unevaluated instead
of incrementing cp_unevaluated_operand directly, which allows us to
safely use WALK_SUBTREE in those cases:

-- >8 --

Subject: [PATCH] c++, tree: optimize walk_tree_1 and cp_walk_subtrees

gcc/cp/ChangeLog:

	* tree.cc (cp_walk_subtrees): Avoid repeatedly dereferencing tp.
	<case DECLTYPE_TYPE>: Use cp_unevaluated and WALK_SUBTREE.
	<case ALIGNOF_EXPR etc>: Likewise.

gcc/ChangeLog:

	* tree.cc (walk_tree_1): Avoid repeatedly dereferencing tp
	and type_p.
---
 gcc/cp/tree.cc | 134 +++++++++++++++++++++++++------------------------
 gcc/tree.cc    | 103 +++++++++++++++++++------------------
 2 files changed, 119 insertions(+), 118 deletions(-)

diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
index 69852538894..d35e30faf28 100644
--- a/gcc/cp/tree.cc
+++ b/gcc/cp/tree.cc
@@ -5445,7 +5445,8 @@ tree
 cp_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 t = *tp;
+  enum tree_code code = TREE_CODE (t);
   tree result;
 
 #define WALK_SUBTREE(NODE)				\
@@ -5456,7 +5457,7 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
     }							\
   while (0)
 
-  if (TYPE_P (*tp))
+  if (TYPE_P (t))
     {
       /* 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
@@ -5468,15 +5469,15 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
 
 	 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))
+      if (*walk_subtrees_p == 1 && typedef_variant_p (t))
 	{
-	  if (tree ti = TYPE_ALIAS_TEMPLATE_INFO (*tp))
+	  if (tree ti = TYPE_ALIAS_TEMPLATE_INFO (t))
 	    WALK_SUBTREE (TI_ARGS (ti));
 	  *walk_subtrees_p = 0;
 	  return NULL_TREE;
 	}
 
-      if (tree ti = TYPE_TEMPLATE_INFO (*tp))
+      if (tree ti = TYPE_TEMPLATE_INFO (t))
 	WALK_SUBTREE (TI_ARGS (ti));
     }
 
@@ -5486,8 +5487,8 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
   switch (code)
     {
     case TEMPLATE_TYPE_PARM:
-      if (template_placeholder_p (*tp))
-	WALK_SUBTREE (CLASS_PLACEHOLDER_TEMPLATE (*tp));
+      if (template_placeholder_p (t))
+	WALK_SUBTREE (CLASS_PLACEHOLDER_TEMPLATE (t));
       /* Fall through.  */
     case DEFERRED_PARSE:
     case TEMPLATE_TEMPLATE_PARM:
@@ -5501,63 +5502,63 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
       break;
 
     case TYPENAME_TYPE:
-      WALK_SUBTREE (TYPE_CONTEXT (*tp));
-      WALK_SUBTREE (TYPENAME_TYPE_FULLNAME (*tp));
+      WALK_SUBTREE (TYPE_CONTEXT (t));
+      WALK_SUBTREE (TYPENAME_TYPE_FULLNAME (t));
       *walk_subtrees_p = 0;
       break;
 
     case BASELINK:
-      if (BASELINK_QUALIFIED_P (*tp))
-	WALK_SUBTREE (BINFO_TYPE (BASELINK_ACCESS_BINFO (*tp)));
-      WALK_SUBTREE (BASELINK_FUNCTIONS (*tp));
+      if (BASELINK_QUALIFIED_P (t))
+	WALK_SUBTREE (BINFO_TYPE (BASELINK_ACCESS_BINFO (t)));
+      WALK_SUBTREE (BASELINK_FUNCTIONS (t));
       *walk_subtrees_p = 0;
       break;
 
     case PTRMEM_CST:
-      WALK_SUBTREE (TREE_TYPE (*tp));
+      WALK_SUBTREE (TREE_TYPE (t));
       *walk_subtrees_p = 0;
       break;
 
     case TREE_LIST:
-      WALK_SUBTREE (TREE_PURPOSE (*tp));
+      WALK_SUBTREE (TREE_PURPOSE (t));
       break;
 
     case OVERLOAD:
-      WALK_SUBTREE (OVL_FUNCTION (*tp));
-      WALK_SUBTREE (OVL_CHAIN (*tp));
+      WALK_SUBTREE (OVL_FUNCTION (t));
+      WALK_SUBTREE (OVL_CHAIN (t));
       *walk_subtrees_p = 0;
       break;
 
     case USING_DECL:
-      WALK_SUBTREE (DECL_NAME (*tp));
-      WALK_SUBTREE (USING_DECL_SCOPE (*tp));
-      WALK_SUBTREE (USING_DECL_DECLS (*tp));
+      WALK_SUBTREE (DECL_NAME (t));
+      WALK_SUBTREE (USING_DECL_SCOPE (t));
+      WALK_SUBTREE (USING_DECL_DECLS (t));
       *walk_subtrees_p = 0;
       break;
 
     case RECORD_TYPE:
-      if (TYPE_PTRMEMFUNC_P (*tp))
-	WALK_SUBTREE (TYPE_PTRMEMFUNC_FN_TYPE_RAW (*tp));
+      if (TYPE_PTRMEMFUNC_P (t))
+	WALK_SUBTREE (TYPE_PTRMEMFUNC_FN_TYPE_RAW (t));
       break;
 
     case TYPE_ARGUMENT_PACK:
     case NONTYPE_ARGUMENT_PACK:
       {
-        tree args = ARGUMENT_PACK_ARGS (*tp);
+	tree args = ARGUMENT_PACK_ARGS (t);
 	for (tree arg : tree_vec_range (args))
 	  WALK_SUBTREE (arg);
       }
       break;
 
     case TYPE_PACK_EXPANSION:
-      WALK_SUBTREE (TREE_TYPE (*tp));
-      WALK_SUBTREE (PACK_EXPANSION_EXTRA_ARGS (*tp));
+      WALK_SUBTREE (TREE_TYPE (t));
+      WALK_SUBTREE (PACK_EXPANSION_EXTRA_ARGS (t));
       *walk_subtrees_p = 0;
       break;
       
     case EXPR_PACK_EXPANSION:
-      WALK_SUBTREE (TREE_OPERAND (*tp, 0));
-      WALK_SUBTREE (PACK_EXPANSION_EXTRA_ARGS (*tp));
+      WALK_SUBTREE (TREE_OPERAND (t, 0));
+      WALK_SUBTREE (PACK_EXPANSION_EXTRA_ARGS (t));
       *walk_subtrees_p = 0;
       break;
 
@@ -5568,54 +5569,55 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
     case DYNAMIC_CAST_EXPR:
     case IMPLICIT_CONV_EXPR:
     case BIT_CAST_EXPR:
-      if (TREE_TYPE (*tp))
-	WALK_SUBTREE (TREE_TYPE (*tp));
+      if (TREE_TYPE (t))
+	WALK_SUBTREE (TREE_TYPE (t));
       break;
 
     case CONSTRUCTOR:
-      if (COMPOUND_LITERAL_P (*tp))
-	WALK_SUBTREE (TREE_TYPE (*tp));
+      if (COMPOUND_LITERAL_P (t))
+	WALK_SUBTREE (TREE_TYPE (t));
       break;
 
     case TRAIT_EXPR:
-      WALK_SUBTREE (TRAIT_EXPR_TYPE1 (*tp));
-      WALK_SUBTREE (TRAIT_EXPR_TYPE2 (*tp));
+      WALK_SUBTREE (TRAIT_EXPR_TYPE1 (t));
+      WALK_SUBTREE (TRAIT_EXPR_TYPE2 (t));
       *walk_subtrees_p = 0;
       break;
 
     case TRAIT_TYPE:
-      WALK_SUBTREE (TRAIT_TYPE_TYPE1 (*tp));
-      WALK_SUBTREE (TRAIT_TYPE_TYPE2 (*tp));
+      WALK_SUBTREE (TRAIT_TYPE_TYPE1 (t));
+      WALK_SUBTREE (TRAIT_TYPE_TYPE2 (t));
       *walk_subtrees_p = 0;
       break;
 
     case DECLTYPE_TYPE:
-      ++cp_unevaluated_operand;
-      /* We can't use WALK_SUBTREE here because of the goto.  */
-      result = cp_walk_tree (&DECLTYPE_TYPE_EXPR (*tp), func, data, pset);
-      --cp_unevaluated_operand;
-      *walk_subtrees_p = 0;
-      break;
+      {
+	cp_unevaluated u;
+	WALK_SUBTREE (DECLTYPE_TYPE_EXPR (t));
+	*walk_subtrees_p = 0;
+	break;
+      }
 
     case ALIGNOF_EXPR:
     case SIZEOF_EXPR:
     case NOEXCEPT_EXPR:
-      ++cp_unevaluated_operand;
-      result = cp_walk_tree (&TREE_OPERAND (*tp, 0), func, data, pset);
-      --cp_unevaluated_operand;
-      *walk_subtrees_p = 0;
-      break;
- 
+      {
+	cp_unevaluated u;
+	WALK_SUBTREE (TREE_OPERAND (t, 0));
+	*walk_subtrees_p = 0;
+	break;
+      }
+
     case REQUIRES_EXPR:
       {
 	cp_unevaluated u;
-	for (tree parm = REQUIRES_EXPR_PARMS (*tp); parm; parm = DECL_CHAIN (parm))
+	for (tree parm = REQUIRES_EXPR_PARMS (t); parm; parm = DECL_CHAIN (parm))
 	  /* Walk the types of each parameter, but not the parameter itself,
 	     since doing so would cause false positives in the unexpanded pack
 	     checker if the requires-expr introduces a function parameter pack,
 	     e.g. requires (Ts... ts) { }.   */
 	  WALK_SUBTREE (TREE_TYPE (parm));
-	WALK_SUBTREE (REQUIRES_EXPR_REQS (*tp));
+	WALK_SUBTREE (REQUIRES_EXPR_REQS (t));
 	*walk_subtrees_p = 0;
 	break;
       }
@@ -5626,12 +5628,12 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
 	 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))
+      if (VAR_P (TREE_OPERAND (t, 0))
 	  && (processing_template_decl
-	      || (DECL_ARTIFICIAL (TREE_OPERAND (*tp, 0))
-		  && !TREE_STATIC (TREE_OPERAND (*tp, 0)))))
+	      || (DECL_ARTIFICIAL (TREE_OPERAND (t, 0))
+		  && !TREE_STATIC (TREE_OPERAND (t, 0)))))
 	{
-	  tree decl = TREE_OPERAND (*tp, 0);
+	  tree decl = TREE_OPERAND (t, 0);
 	  WALK_SUBTREE (DECL_INITIAL (decl));
 	  WALK_SUBTREE (DECL_SIZE (decl));
 	  WALK_SUBTREE (DECL_SIZE_UNIT (decl));
@@ -5641,45 +5643,45 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
     case LAMBDA_EXPR:
       /* Don't walk into the body of the lambda, but the capture initializers
 	 are part of the enclosing context.  */
-      for (tree cap = LAMBDA_EXPR_CAPTURE_LIST (*tp); cap;
+      for (tree cap = LAMBDA_EXPR_CAPTURE_LIST (t); cap;
 	   cap = TREE_CHAIN (cap))
 	WALK_SUBTREE (TREE_VALUE (cap));
       break;
 
     case CO_YIELD_EXPR:
-      if (TREE_OPERAND (*tp, 1))
+      if (TREE_OPERAND (t, 1))
 	/* Operand 1 is the tree for the relevant co_await which has any
 	   interesting sub-trees.  */
-	WALK_SUBTREE (TREE_OPERAND (*tp, 1));
+	WALK_SUBTREE (TREE_OPERAND (t, 1));
       break;
 
     case CO_AWAIT_EXPR:
-      if (TREE_OPERAND (*tp, 1))
+      if (TREE_OPERAND (t, 1))
 	/* Operand 1 is frame variable.  */
-	WALK_SUBTREE (TREE_OPERAND (*tp, 1));
-      if (TREE_OPERAND (*tp, 2))
+	WALK_SUBTREE (TREE_OPERAND (t, 1));
+      if (TREE_OPERAND (t, 2))
 	/* Operand 2 has the initialiser, and we need to walk any subtrees
 	   there.  */
-	WALK_SUBTREE (TREE_OPERAND (*tp, 2));
+	WALK_SUBTREE (TREE_OPERAND (t, 2));
       break;
 
     case CO_RETURN_EXPR:
-      if (TREE_OPERAND (*tp, 0))
+      if (TREE_OPERAND (t, 0))
 	{
-	  if (VOID_TYPE_P (TREE_OPERAND (*tp, 0)))
+	  if (VOID_TYPE_P (TREE_OPERAND (t, 0)))
 	    /* For void expressions, operand 1 is a trivial call, and any
 	       interesting subtrees will be part of operand 0.  */
-	    WALK_SUBTREE (TREE_OPERAND (*tp, 0));
-	  else if (TREE_OPERAND (*tp, 1))
+	    WALK_SUBTREE (TREE_OPERAND (t, 0));
+	  else if (TREE_OPERAND (t, 1))
 	    /* Interesting sub-trees will be in the return_value () call
 	       arguments.  */
-	    WALK_SUBTREE (TREE_OPERAND (*tp, 1));
+	    WALK_SUBTREE (TREE_OPERAND (t, 1));
 	}
       break;
 
     case STATIC_ASSERT:
-      WALK_SUBTREE (STATIC_ASSERT_CONDITION (*tp));
-      WALK_SUBTREE (STATIC_ASSERT_MESSAGE (*tp));
+      WALK_SUBTREE (STATIC_ASSERT_CONDITION (t));
+      WALK_SUBTREE (STATIC_ASSERT_MESSAGE (t));
       break;
 
     default:
diff --git a/gcc/tree.cc b/gcc/tree.cc
index 207293c48cb..5f2af073af9 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -11300,10 +11300,6 @@ tree
 walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
 	     hash_set<tree> *pset, walk_tree_lh lh)
 {
-  enum tree_code code;
-  int walk_subtrees;
-  tree result;
-
 #define WALK_SUBTREE_TAIL(NODE)				\
   do							\
     {							\
@@ -11323,14 +11319,15 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
     return NULL_TREE;
 
   /* Call the function.  */
-  walk_subtrees = 1;
-  result = (*func) (tp, &walk_subtrees, data);
+  int walk_subtrees = 1;
+  tree result = (*func) (tp, &walk_subtrees, data);
 
   /* If we found something, return it.  */
   if (result)
     return result;
 
-  code = TREE_CODE (*tp);
+  tree t = *tp;
+  tree_code code = TREE_CODE (t);
 
   /* Even if we didn't, FUNC may have decided that there was nothing
      interesting below this point in the tree.  */
@@ -11338,9 +11335,9 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
     {
       /* But we still need to check our siblings.  */
       if (code == TREE_LIST)
-	WALK_SUBTREE_TAIL (TREE_CHAIN (*tp));
+	WALK_SUBTREE_TAIL (TREE_CHAIN (t));
       else if (code == OMP_CLAUSE)
-	WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp));
+	WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (t));
       else
 	return NULL_TREE;
     }
@@ -11370,58 +11367,58 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
       break;
 
     case TREE_LIST:
-      WALK_SUBTREE (TREE_VALUE (*tp));
-      WALK_SUBTREE_TAIL (TREE_CHAIN (*tp));
+      WALK_SUBTREE (TREE_VALUE (t));
+      WALK_SUBTREE_TAIL (TREE_CHAIN (t));
 
     case TREE_VEC:
       {
-	int len = TREE_VEC_LENGTH (*tp);
+	int len = TREE_VEC_LENGTH (t);
 
 	if (len == 0)
 	  break;
 
 	/* Walk all elements but the last.  */
 	for (int i = 0; i < len - 1; ++i)
-	  WALK_SUBTREE (TREE_VEC_ELT (*tp, i));
+	  WALK_SUBTREE (TREE_VEC_ELT (t, i));
 
 	/* Now walk the last one as a tail call.  */
-	WALK_SUBTREE_TAIL (TREE_VEC_ELT (*tp, len - 1));
+	WALK_SUBTREE_TAIL (TREE_VEC_ELT (t, len - 1));
       }
 
     case VECTOR_CST:
       {
-	unsigned len = vector_cst_encoded_nelts (*tp);
+	unsigned len = vector_cst_encoded_nelts (t);
 	if (len == 0)
 	  break;
 	/* Walk all elements but the last.  */
 	for (unsigned i = 0; i < len - 1; ++i)
-	  WALK_SUBTREE (VECTOR_CST_ENCODED_ELT (*tp, i));
+	  WALK_SUBTREE (VECTOR_CST_ENCODED_ELT (t, i));
 	/* Now walk the last one as a tail call.  */
-	WALK_SUBTREE_TAIL (VECTOR_CST_ENCODED_ELT (*tp, len - 1));
+	WALK_SUBTREE_TAIL (VECTOR_CST_ENCODED_ELT (t, len - 1));
       }
 
     case COMPLEX_CST:
-      WALK_SUBTREE (TREE_REALPART (*tp));
-      WALK_SUBTREE_TAIL (TREE_IMAGPART (*tp));
+      WALK_SUBTREE (TREE_REALPART (t));
+      WALK_SUBTREE_TAIL (TREE_IMAGPART (t));
 
     case CONSTRUCTOR:
       {
 	unsigned HOST_WIDE_INT idx;
 	constructor_elt *ce;
 
-	for (idx = 0; vec_safe_iterate (CONSTRUCTOR_ELTS (*tp), idx, &ce);
+	for (idx = 0; vec_safe_iterate (CONSTRUCTOR_ELTS (t), idx, &ce);
 	     idx++)
 	  WALK_SUBTREE (ce->value);
       }
       break;
 
     case SAVE_EXPR:
-      WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, 0));
+      WALK_SUBTREE_TAIL (TREE_OPERAND (t, 0));
 
     case BIND_EXPR:
       {
 	tree decl;
-	for (decl = BIND_EXPR_VARS (*tp); decl; decl = DECL_CHAIN (decl))
+	for (decl = BIND_EXPR_VARS (t); decl; decl = DECL_CHAIN (decl))
 	  {
 	    /* Walk the DECL_INITIAL and DECL_SIZE.  We don't want to walk
 	       into declarations that are just mentioned, rather than
@@ -11432,23 +11429,23 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
 	    WALK_SUBTREE (DECL_SIZE (decl));
 	    WALK_SUBTREE (DECL_SIZE_UNIT (decl));
 	  }
-	WALK_SUBTREE_TAIL (BIND_EXPR_BODY (*tp));
+	WALK_SUBTREE_TAIL (BIND_EXPR_BODY (t));
       }
 
     case STATEMENT_LIST:
       {
 	tree_stmt_iterator i;
-	for (i = tsi_start (*tp); !tsi_end_p (i); tsi_next (&i))
+	for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
 	  WALK_SUBTREE (*tsi_stmt_ptr (i));
       }
       break;
 
     case OMP_CLAUSE:
       {
-	int len = omp_clause_num_ops[OMP_CLAUSE_CODE (*tp)];
+	int len = omp_clause_num_ops[OMP_CLAUSE_CODE (t)];
 	for (int i = 0; i < len; i++)
-	  WALK_SUBTREE (OMP_CLAUSE_OPERAND (*tp, i));
-	WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp));
+	  WALK_SUBTREE (OMP_CLAUSE_OPERAND (t, i));
+	WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (t));
       }
 
     case TARGET_EXPR:
@@ -11457,10 +11454,10 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
 
 	/* TARGET_EXPRs are peculiar: operands 1 and 3 can be the same.
 	   But, we only want to walk once.  */
-	len = (TREE_OPERAND (*tp, 3) == TREE_OPERAND (*tp, 1)) ? 2 : 3;
+	len = (TREE_OPERAND (t, 3) == TREE_OPERAND (t, 1)) ? 2 : 3;
 	for (i = 0; i < len; ++i)
-	  WALK_SUBTREE (TREE_OPERAND (*tp, i));
-	WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, len));
+	  WALK_SUBTREE (TREE_OPERAND (t, i));
+	WALK_SUBTREE_TAIL (TREE_OPERAND (t, len));
       }
 
     case DECL_EXPR:
@@ -11475,15 +11472,15 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
 	 variable-sized types.
 
 	 Note that DECLs get walked as part of processing the BIND_EXPR.  */
-      if (TREE_CODE (DECL_EXPR_DECL (*tp)) == TYPE_DECL)
+      if (TREE_CODE (DECL_EXPR_DECL (t)) == TYPE_DECL)
 	{
 	  /* Call the function for the decl so e.g. copy_tree_body_r can
 	     replace it with the remapped one.  */
-	  result = (*func) (&DECL_EXPR_DECL (*tp), &walk_subtrees, data);
+	  result = (*func) (&DECL_EXPR_DECL (t), &walk_subtrees, data);
 	  if (result || !walk_subtrees)
 	    return result;
 
-	  tree *type_p = &TREE_TYPE (DECL_EXPR_DECL (*tp));
+	  tree *type_p = &TREE_TYPE (DECL_EXPR_DECL (t));
 	  if (TREE_CODE (*type_p) == ERROR_MARK)
 	    return NULL_TREE;
 
@@ -11494,21 +11491,23 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
 	  if (result || !walk_subtrees)
 	    return result;
 
+	  tree type = *type_p;
+
 	  /* But do not walk a pointed-to type since it may itself need to
 	     be walked in the declaration case if it isn't anonymous.  */
-	  if (!POINTER_TYPE_P (*type_p))
+	  if (!POINTER_TYPE_P (type))
 	    {
-	      result = walk_type_fields (*type_p, func, data, pset, lh);
+	      result = walk_type_fields (type, func, data, pset, lh);
 	      if (result)
 		return result;
 	    }
 
 	  /* If this is a record type, also walk the fields.  */
-	  if (RECORD_OR_UNION_TYPE_P (*type_p))
+	  if (RECORD_OR_UNION_TYPE_P (type))
 	    {
 	      tree field;
 
-	      for (field = TYPE_FIELDS (*type_p); field;
+	      for (field = TYPE_FIELDS (type); field;
 		   field = DECL_CHAIN (field))
 		{
 		  /* We'd like to look at the type of the field, but we can
@@ -11521,24 +11520,24 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
 		  WALK_SUBTREE (DECL_FIELD_OFFSET (field));
 		  WALK_SUBTREE (DECL_SIZE (field));
 		  WALK_SUBTREE (DECL_SIZE_UNIT (field));
-		  if (TREE_CODE (*type_p) == QUAL_UNION_TYPE)
+		  if (TREE_CODE (type) == QUAL_UNION_TYPE)
 		    WALK_SUBTREE (DECL_QUALIFIER (field));
 		}
 	    }
 
 	  /* Same for scalar types.  */
-	  else if (TREE_CODE (*type_p) == BOOLEAN_TYPE
-		   || TREE_CODE (*type_p) == ENUMERAL_TYPE
-		   || TREE_CODE (*type_p) == INTEGER_TYPE
-		   || TREE_CODE (*type_p) == FIXED_POINT_TYPE
-		   || TREE_CODE (*type_p) == REAL_TYPE)
+	  else if (TREE_CODE (type) == BOOLEAN_TYPE
+		   || TREE_CODE (type) == ENUMERAL_TYPE
+		   || TREE_CODE (type) == INTEGER_TYPE
+		   || TREE_CODE (type) == FIXED_POINT_TYPE
+		   || TREE_CODE (type) == REAL_TYPE)
 	    {
-	      WALK_SUBTREE (TYPE_MIN_VALUE (*type_p));
-	      WALK_SUBTREE (TYPE_MAX_VALUE (*type_p));
+	      WALK_SUBTREE (TYPE_MIN_VALUE (type));
+	      WALK_SUBTREE (TYPE_MAX_VALUE (type));
 	    }
 
-	  WALK_SUBTREE (TYPE_SIZE (*type_p));
-	  WALK_SUBTREE_TAIL (TYPE_SIZE_UNIT (*type_p));
+	  WALK_SUBTREE (TYPE_SIZE (type));
+	  WALK_SUBTREE_TAIL (TYPE_SIZE_UNIT (type));
 	}
       /* FALLTHRU */
 
@@ -11548,20 +11547,20 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
 	  int i, len;
 
 	  /* Walk over all the sub-trees of this operand.  */
-	  len = TREE_OPERAND_LENGTH (*tp);
+	  len = TREE_OPERAND_LENGTH (t);
 
 	  /* Go through the subtrees.  We need to do this in forward order so
 	     that the scope of a FOR_EXPR is handled properly.  */
 	  if (len)
 	    {
 	      for (i = 0; i < len - 1; ++i)
-		WALK_SUBTREE (TREE_OPERAND (*tp, i));
-	      WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, len - 1));
+		WALK_SUBTREE (TREE_OPERAND (t, i));
+	      WALK_SUBTREE_TAIL (TREE_OPERAND (t, len - 1));
 	    }
 	}
       /* If this is a type, walk the needed fields in the type.  */
-      else if (TYPE_P (*tp))
-	return walk_type_fields (*tp, func, data, pset, lh);
+      else if (TYPE_P (t))
+	return walk_type_fields (t, func, data, pset, lh);
       break;
     }
  

Patch

diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
index 4066b014f6e..ceb0c75f559 100644
--- a/gcc/cp/tree.cc
+++ b/gcc/cp/tree.cc
@@ -5441,7 +5441,8 @@  tree
 cp_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 t = *tp;
+  enum tree_code code = TREE_CODE (t);
   tree result;
 
 #define WALK_SUBTREE(NODE)				\
@@ -5452,7 +5453,7 @@  cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
     }							\
   while (0)
 
-  if (TYPE_P (*tp))
+  if (TYPE_P (t))
     {
       /* 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
@@ -5464,15 +5465,15 @@  cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
 
 	 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))
+      if (*walk_subtrees_p == 1 && typedef_variant_p (t))
 	{
-	  if (tree ti = TYPE_ALIAS_TEMPLATE_INFO (*tp))
+	  if (tree ti = TYPE_ALIAS_TEMPLATE_INFO (t))
 	    WALK_SUBTREE (TI_ARGS (ti));
 	  *walk_subtrees_p = 0;
 	  return NULL_TREE;
 	}
 
-      if (tree ti = TYPE_TEMPLATE_INFO (*tp))
+      if (tree ti = TYPE_TEMPLATE_INFO (t))
 	WALK_SUBTREE (TI_ARGS (ti));
     }
 
@@ -5482,8 +5483,8 @@  cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
   switch (code)
     {
     case TEMPLATE_TYPE_PARM:
-      if (template_placeholder_p (*tp))
-	WALK_SUBTREE (CLASS_PLACEHOLDER_TEMPLATE (*tp));
+      if (template_placeholder_p (t))
+	WALK_SUBTREE (CLASS_PLACEHOLDER_TEMPLATE (t));
       /* Fall through.  */
     case DEFERRED_PARSE:
     case TEMPLATE_TEMPLATE_PARM:
@@ -5497,63 +5498,63 @@  cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
       break;
 
     case TYPENAME_TYPE:
-      WALK_SUBTREE (TYPE_CONTEXT (*tp));
-      WALK_SUBTREE (TYPENAME_TYPE_FULLNAME (*tp));
+      WALK_SUBTREE (TYPE_CONTEXT (t));
+      WALK_SUBTREE (TYPENAME_TYPE_FULLNAME (t));
       *walk_subtrees_p = 0;
       break;
 
     case BASELINK:
-      if (BASELINK_QUALIFIED_P (*tp))
-	WALK_SUBTREE (BINFO_TYPE (BASELINK_ACCESS_BINFO (*tp)));
-      WALK_SUBTREE (BASELINK_FUNCTIONS (*tp));
+      if (BASELINK_QUALIFIED_P (t))
+	WALK_SUBTREE (BINFO_TYPE (BASELINK_ACCESS_BINFO (t)));
+      WALK_SUBTREE (BASELINK_FUNCTIONS (t));
       *walk_subtrees_p = 0;
       break;
 
     case PTRMEM_CST:
-      WALK_SUBTREE (TREE_TYPE (*tp));
+      WALK_SUBTREE (TREE_TYPE (t));
       *walk_subtrees_p = 0;
       break;
 
     case TREE_LIST:
-      WALK_SUBTREE (TREE_PURPOSE (*tp));
+      WALK_SUBTREE (TREE_PURPOSE (t));
       break;
 
     case OVERLOAD:
-      WALK_SUBTREE (OVL_FUNCTION (*tp));
-      WALK_SUBTREE (OVL_CHAIN (*tp));
+      WALK_SUBTREE (OVL_FUNCTION (t));
+      WALK_SUBTREE (OVL_CHAIN (t));
       *walk_subtrees_p = 0;
       break;
 
     case USING_DECL:
-      WALK_SUBTREE (DECL_NAME (*tp));
-      WALK_SUBTREE (USING_DECL_SCOPE (*tp));
-      WALK_SUBTREE (USING_DECL_DECLS (*tp));
+      WALK_SUBTREE (DECL_NAME (t));
+      WALK_SUBTREE (USING_DECL_SCOPE (t));
+      WALK_SUBTREE (USING_DECL_DECLS (t));
       *walk_subtrees_p = 0;
       break;
 
     case RECORD_TYPE:
-      if (TYPE_PTRMEMFUNC_P (*tp))
-	WALK_SUBTREE (TYPE_PTRMEMFUNC_FN_TYPE_RAW (*tp));
+      if (TYPE_PTRMEMFUNC_P (t))
+	WALK_SUBTREE (TYPE_PTRMEMFUNC_FN_TYPE_RAW (t));
       break;
 
     case TYPE_ARGUMENT_PACK:
     case NONTYPE_ARGUMENT_PACK:
       {
-        tree args = ARGUMENT_PACK_ARGS (*tp);
+	tree args = ARGUMENT_PACK_ARGS (t);
 	for (tree arg : tree_vec_range (args))
 	  WALK_SUBTREE (arg);
       }
       break;
 
     case TYPE_PACK_EXPANSION:
-      WALK_SUBTREE (TREE_TYPE (*tp));
-      WALK_SUBTREE (PACK_EXPANSION_EXTRA_ARGS (*tp));
+      WALK_SUBTREE (TREE_TYPE (t));
+      WALK_SUBTREE (PACK_EXPANSION_EXTRA_ARGS (t));
       *walk_subtrees_p = 0;
       break;
       
     case EXPR_PACK_EXPANSION:
-      WALK_SUBTREE (TREE_OPERAND (*tp, 0));
-      WALK_SUBTREE (PACK_EXPANSION_EXTRA_ARGS (*tp));
+      WALK_SUBTREE (TREE_OPERAND (t, 0));
+      WALK_SUBTREE (PACK_EXPANSION_EXTRA_ARGS (t));
       *walk_subtrees_p = 0;
       break;
 
@@ -5564,31 +5565,31 @@  cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
     case DYNAMIC_CAST_EXPR:
     case IMPLICIT_CONV_EXPR:
     case BIT_CAST_EXPR:
-      if (TREE_TYPE (*tp))
-	WALK_SUBTREE (TREE_TYPE (*tp));
+      if (TREE_TYPE (t))
+	WALK_SUBTREE (TREE_TYPE (t));
       break;
 
     case CONSTRUCTOR:
-      if (COMPOUND_LITERAL_P (*tp))
-	WALK_SUBTREE (TREE_TYPE (*tp));
+      if (COMPOUND_LITERAL_P (t))
+	WALK_SUBTREE (TREE_TYPE (t));
       break;
 
     case TRAIT_EXPR:
-      WALK_SUBTREE (TRAIT_EXPR_TYPE1 (*tp));
-      WALK_SUBTREE (TRAIT_EXPR_TYPE2 (*tp));
+      WALK_SUBTREE (TRAIT_EXPR_TYPE1 (t));
+      WALK_SUBTREE (TRAIT_EXPR_TYPE2 (t));
       *walk_subtrees_p = 0;
       break;
 
     case TRAIT_TYPE:
-      WALK_SUBTREE (TRAIT_TYPE_TYPE1 (*tp));
-      WALK_SUBTREE (TRAIT_TYPE_TYPE2 (*tp));
+      WALK_SUBTREE (TRAIT_TYPE_TYPE1 (t));
+      WALK_SUBTREE (TRAIT_TYPE_TYPE2 (t));
       *walk_subtrees_p = 0;
       break;
 
     case DECLTYPE_TYPE:
       ++cp_unevaluated_operand;
       /* We can't use WALK_SUBTREE here because of the goto.  */
-      result = cp_walk_tree (&DECLTYPE_TYPE_EXPR (*tp), func, data, pset);
+      result = cp_walk_tree (&DECLTYPE_TYPE_EXPR (t), func, data, pset);
       --cp_unevaluated_operand;
       *walk_subtrees_p = 0;
       break;
@@ -5597,7 +5598,7 @@  cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
     case SIZEOF_EXPR:
     case NOEXCEPT_EXPR:
       ++cp_unevaluated_operand;
-      result = cp_walk_tree (&TREE_OPERAND (*tp, 0), func, data, pset);
+      result = cp_walk_tree (&TREE_OPERAND (t, 0), func, data, pset);
       --cp_unevaluated_operand;
       *walk_subtrees_p = 0;
       break;
@@ -5605,12 +5606,12 @@  cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
     case REQUIRES_EXPR:
       {
 	cp_unevaluated u;
-	for (tree parm = REQUIRES_EXPR_PARMS (*tp); parm; parm = DECL_CHAIN (parm))
+	for (tree parm = REQUIRES_EXPR_PARMS (t); parm; parm = DECL_CHAIN (parm))
 	  /* Walk the types of each parameter, but not the parameter itself.
 	     Doing so would cause false positives in the unexpanded parameter
 	     pack checker since an introduced parameter pack looks bare.  */
 	  WALK_SUBTREE (TREE_TYPE (parm));
-	WALK_SUBTREE (REQUIRES_EXPR_REQS (*tp));
+	WALK_SUBTREE (REQUIRES_EXPR_REQS (t));
 	*walk_subtrees_p = 0;
 	break;
       }
@@ -5621,12 +5622,12 @@  cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
 	 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))
+      if (VAR_P (TREE_OPERAND (t, 0))
 	  && (processing_template_decl
-	      || (DECL_ARTIFICIAL (TREE_OPERAND (*tp, 0))
-		  && !TREE_STATIC (TREE_OPERAND (*tp, 0)))))
+	      || (DECL_ARTIFICIAL (TREE_OPERAND (t, 0))
+		  && !TREE_STATIC (TREE_OPERAND (t, 0)))))
 	{
-	  tree decl = TREE_OPERAND (*tp, 0);
+	  tree decl = TREE_OPERAND (t, 0);
 	  WALK_SUBTREE (DECL_INITIAL (decl));
 	  WALK_SUBTREE (DECL_SIZE (decl));
 	  WALK_SUBTREE (DECL_SIZE_UNIT (decl));
@@ -5636,45 +5637,45 @@  cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
     case LAMBDA_EXPR:
       /* Don't walk into the body of the lambda, but the capture initializers
 	 are part of the enclosing context.  */
-      for (tree cap = LAMBDA_EXPR_CAPTURE_LIST (*tp); cap;
+      for (tree cap = LAMBDA_EXPR_CAPTURE_LIST (t); cap;
 	   cap = TREE_CHAIN (cap))
 	WALK_SUBTREE (TREE_VALUE (cap));
       break;
 
     case CO_YIELD_EXPR:
-      if (TREE_OPERAND (*tp, 1))
+      if (TREE_OPERAND (t, 1))
 	/* Operand 1 is the tree for the relevant co_await which has any
 	   interesting sub-trees.  */
-	WALK_SUBTREE (TREE_OPERAND (*tp, 1));
+	WALK_SUBTREE (TREE_OPERAND (t, 1));
       break;
 
     case CO_AWAIT_EXPR:
-      if (TREE_OPERAND (*tp, 1))
+      if (TREE_OPERAND (t, 1))
 	/* Operand 1 is frame variable.  */
-	WALK_SUBTREE (TREE_OPERAND (*tp, 1));
-      if (TREE_OPERAND (*tp, 2))
+	WALK_SUBTREE (TREE_OPERAND (t, 1));
+      if (TREE_OPERAND (t, 2))
 	/* Operand 2 has the initialiser, and we need to walk any subtrees
 	   there.  */
-	WALK_SUBTREE (TREE_OPERAND (*tp, 2));
+	WALK_SUBTREE (TREE_OPERAND (t, 2));
       break;
 
     case CO_RETURN_EXPR:
-      if (TREE_OPERAND (*tp, 0))
+      if (TREE_OPERAND (t, 0))
 	{
-	  if (VOID_TYPE_P (TREE_OPERAND (*tp, 0)))
+	  if (VOID_TYPE_P (TREE_OPERAND (t, 0)))
 	    /* For void expressions, operand 1 is a trivial call, and any
 	       interesting subtrees will be part of operand 0.  */
-	    WALK_SUBTREE (TREE_OPERAND (*tp, 0));
-	  else if (TREE_OPERAND (*tp, 1))
+	    WALK_SUBTREE (TREE_OPERAND (t, 0));
+	  else if (TREE_OPERAND (t, 1))
 	    /* Interesting sub-trees will be in the return_value () call
 	       arguments.  */
-	    WALK_SUBTREE (TREE_OPERAND (*tp, 1));
+	    WALK_SUBTREE (TREE_OPERAND (t, 1));
 	}
       break;
 
     case STATIC_ASSERT:
-      WALK_SUBTREE (STATIC_ASSERT_CONDITION (*tp));
-      WALK_SUBTREE (STATIC_ASSERT_MESSAGE (*tp));
+      WALK_SUBTREE (STATIC_ASSERT_CONDITION (t));
+      WALK_SUBTREE (STATIC_ASSERT_MESSAGE (t));
       break;
 
     default:
diff --git a/gcc/tree.cc b/gcc/tree.cc
index 5eb6a49da31..dfada652570 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -11218,10 +11218,6 @@  tree
 walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
 	     hash_set<tree> *pset, walk_tree_lh lh)
 {
-  enum tree_code code;
-  int walk_subtrees;
-  tree result;
-
 #define WALK_SUBTREE_TAIL(NODE)				\
   do							\
     {							\
@@ -11241,14 +11237,15 @@  walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
     return NULL_TREE;
 
   /* Call the function.  */
-  walk_subtrees = 1;
-  result = (*func) (tp, &walk_subtrees, data);
+  int walk_subtrees = 1;
+  tree result = (*func) (tp, &walk_subtrees, data);
 
   /* If we found something, return it.  */
   if (result)
     return result;
 
-  code = TREE_CODE (*tp);
+  tree t = *tp;
+  tree_code code = TREE_CODE (t);
 
   /* Even if we didn't, FUNC may have decided that there was nothing
      interesting below this point in the tree.  */
@@ -11256,9 +11253,9 @@  walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
     {
       /* But we still need to check our siblings.  */
       if (code == TREE_LIST)
-	WALK_SUBTREE_TAIL (TREE_CHAIN (*tp));
+	WALK_SUBTREE_TAIL (TREE_CHAIN (t));
       else if (code == OMP_CLAUSE)
-	WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp));
+	WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (t));
       else
 	return NULL_TREE;
     }
@@ -11288,58 +11285,58 @@  walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
       break;
 
     case TREE_LIST:
-      WALK_SUBTREE (TREE_VALUE (*tp));
-      WALK_SUBTREE_TAIL (TREE_CHAIN (*tp));
+      WALK_SUBTREE (TREE_VALUE (t));
+      WALK_SUBTREE_TAIL (TREE_CHAIN (t));
 
     case TREE_VEC:
       {
-	int len = TREE_VEC_LENGTH (*tp);
+	int len = TREE_VEC_LENGTH (t);
 
 	if (len == 0)
 	  break;
 
 	/* Walk all elements but the first.  */
 	while (--len)
-	  WALK_SUBTREE (TREE_VEC_ELT (*tp, len));
+	  WALK_SUBTREE (TREE_VEC_ELT (t, len));
 
 	/* Now walk the first one as a tail call.  */
-	WALK_SUBTREE_TAIL (TREE_VEC_ELT (*tp, 0));
+	WALK_SUBTREE_TAIL (TREE_VEC_ELT (t, 0));
       }
 
     case VECTOR_CST:
       {
-	unsigned len = vector_cst_encoded_nelts (*tp);
+	unsigned len = vector_cst_encoded_nelts (t);
 	if (len == 0)
 	  break;
 	/* Walk all elements but the first.  */
 	while (--len)
-	  WALK_SUBTREE (VECTOR_CST_ENCODED_ELT (*tp, len));
+	  WALK_SUBTREE (VECTOR_CST_ENCODED_ELT (t, len));
 	/* Now walk the first one as a tail call.  */
-	WALK_SUBTREE_TAIL (VECTOR_CST_ENCODED_ELT (*tp, 0));
+	WALK_SUBTREE_TAIL (VECTOR_CST_ENCODED_ELT (t, 0));
       }
 
     case COMPLEX_CST:
-      WALK_SUBTREE (TREE_REALPART (*tp));
-      WALK_SUBTREE_TAIL (TREE_IMAGPART (*tp));
+      WALK_SUBTREE (TREE_REALPART (t));
+      WALK_SUBTREE_TAIL (TREE_IMAGPART (t));
 
     case CONSTRUCTOR:
       {
 	unsigned HOST_WIDE_INT idx;
 	constructor_elt *ce;
 
-	for (idx = 0; vec_safe_iterate (CONSTRUCTOR_ELTS (*tp), idx, &ce);
+	for (idx = 0; vec_safe_iterate (CONSTRUCTOR_ELTS (t), idx, &ce);
 	     idx++)
 	  WALK_SUBTREE (ce->value);
       }
       break;
 
     case SAVE_EXPR:
-      WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, 0));
+      WALK_SUBTREE_TAIL (TREE_OPERAND (t, 0));
 
     case BIND_EXPR:
       {
 	tree decl;
-	for (decl = BIND_EXPR_VARS (*tp); decl; decl = DECL_CHAIN (decl))
+	for (decl = BIND_EXPR_VARS (t); decl; decl = DECL_CHAIN (decl))
 	  {
 	    /* Walk the DECL_INITIAL and DECL_SIZE.  We don't want to walk
 	       into declarations that are just mentioned, rather than
@@ -11350,23 +11347,23 @@  walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
 	    WALK_SUBTREE (DECL_SIZE (decl));
 	    WALK_SUBTREE (DECL_SIZE_UNIT (decl));
 	  }
-	WALK_SUBTREE_TAIL (BIND_EXPR_BODY (*tp));
+	WALK_SUBTREE_TAIL (BIND_EXPR_BODY (t));
       }
 
     case STATEMENT_LIST:
       {
 	tree_stmt_iterator i;
-	for (i = tsi_start (*tp); !tsi_end_p (i); tsi_next (&i))
+	for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
 	  WALK_SUBTREE (*tsi_stmt_ptr (i));
       }
       break;
 
     case OMP_CLAUSE:
       {
-	int len = omp_clause_num_ops[OMP_CLAUSE_CODE (*tp)];
+	int len = omp_clause_num_ops[OMP_CLAUSE_CODE (t)];
 	for (int i = 0; i < len; i++)
-	  WALK_SUBTREE (OMP_CLAUSE_OPERAND (*tp, i));
-	WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp));
+	  WALK_SUBTREE (OMP_CLAUSE_OPERAND (t, i));
+	WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (t));
       }
 
     case TARGET_EXPR:
@@ -11375,10 +11372,10 @@  walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
 
 	/* TARGET_EXPRs are peculiar: operands 1 and 3 can be the same.
 	   But, we only want to walk once.  */
-	len = (TREE_OPERAND (*tp, 3) == TREE_OPERAND (*tp, 1)) ? 2 : 3;
+	len = (TREE_OPERAND (t, 3) == TREE_OPERAND (t, 1)) ? 2 : 3;
 	for (i = 0; i < len; ++i)
-	  WALK_SUBTREE (TREE_OPERAND (*tp, i));
-	WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, len));
+	  WALK_SUBTREE (TREE_OPERAND (t, i));
+	WALK_SUBTREE_TAIL (TREE_OPERAND (t, len));
       }
 
     case DECL_EXPR:
@@ -11393,15 +11390,15 @@  walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
 	 variable-sized types.
 
 	 Note that DECLs get walked as part of processing the BIND_EXPR.  */
-      if (TREE_CODE (DECL_EXPR_DECL (*tp)) == TYPE_DECL)
+      if (TREE_CODE (DECL_EXPR_DECL (t)) == TYPE_DECL)
 	{
 	  /* Call the function for the decl so e.g. copy_tree_body_r can
 	     replace it with the remapped one.  */
-	  result = (*func) (&DECL_EXPR_DECL (*tp), &walk_subtrees, data);
+	  result = (*func) (&DECL_EXPR_DECL (t), &walk_subtrees, data);
 	  if (result || !walk_subtrees)
 	    return result;
 
-	  tree *type_p = &TREE_TYPE (DECL_EXPR_DECL (*tp));
+	  tree *type_p = &TREE_TYPE (DECL_EXPR_DECL (t));
 	  if (TREE_CODE (*type_p) == ERROR_MARK)
 	    return NULL_TREE;
 
@@ -11412,21 +11409,23 @@  walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
 	  if (result || !walk_subtrees)
 	    return result;
 
+	  tree type = *type_p;
+
 	  /* But do not walk a pointed-to type since it may itself need to
 	     be walked in the declaration case if it isn't anonymous.  */
-	  if (!POINTER_TYPE_P (*type_p))
+	  if (!POINTER_TYPE_P (type))
 	    {
-	      result = walk_type_fields (*type_p, func, data, pset, lh);
+	      result = walk_type_fields (type, func, data, pset, lh);
 	      if (result)
 		return result;
 	    }
 
 	  /* If this is a record type, also walk the fields.  */
-	  if (RECORD_OR_UNION_TYPE_P (*type_p))
+	  if (RECORD_OR_UNION_TYPE_P (type))
 	    {
 	      tree field;
 
-	      for (field = TYPE_FIELDS (*type_p); field;
+	      for (field = TYPE_FIELDS (type); field;
 		   field = DECL_CHAIN (field))
 		{
 		  /* We'd like to look at the type of the field, but we can
@@ -11439,24 +11438,24 @@  walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
 		  WALK_SUBTREE (DECL_FIELD_OFFSET (field));
 		  WALK_SUBTREE (DECL_SIZE (field));
 		  WALK_SUBTREE (DECL_SIZE_UNIT (field));
-		  if (TREE_CODE (*type_p) == QUAL_UNION_TYPE)
+		  if (TREE_CODE (type) == QUAL_UNION_TYPE)
 		    WALK_SUBTREE (DECL_QUALIFIER (field));
 		}
 	    }
 
 	  /* Same for scalar types.  */
-	  else if (TREE_CODE (*type_p) == BOOLEAN_TYPE
-		   || TREE_CODE (*type_p) == ENUMERAL_TYPE
-		   || TREE_CODE (*type_p) == INTEGER_TYPE
-		   || TREE_CODE (*type_p) == FIXED_POINT_TYPE
-		   || TREE_CODE (*type_p) == REAL_TYPE)
+	  else if (TREE_CODE (type) == BOOLEAN_TYPE
+		   || TREE_CODE (type) == ENUMERAL_TYPE
+		   || TREE_CODE (type) == INTEGER_TYPE
+		   || TREE_CODE (type) == FIXED_POINT_TYPE
+		   || TREE_CODE (type) == REAL_TYPE)
 	    {
-	      WALK_SUBTREE (TYPE_MIN_VALUE (*type_p));
-	      WALK_SUBTREE (TYPE_MAX_VALUE (*type_p));
+	      WALK_SUBTREE (TYPE_MIN_VALUE (type));
+	      WALK_SUBTREE (TYPE_MAX_VALUE (type));
 	    }
 
-	  WALK_SUBTREE (TYPE_SIZE (*type_p));
-	  WALK_SUBTREE_TAIL (TYPE_SIZE_UNIT (*type_p));
+	  WALK_SUBTREE (TYPE_SIZE (type));
+	  WALK_SUBTREE_TAIL (TYPE_SIZE_UNIT (type));
 	}
       /* FALLTHRU */
 
@@ -11466,20 +11465,20 @@  walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
 	  int i, len;
 
 	  /* Walk over all the sub-trees of this operand.  */
-	  len = TREE_OPERAND_LENGTH (*tp);
+	  len = TREE_OPERAND_LENGTH (t);
 
 	  /* Go through the subtrees.  We need to do this in forward order so
 	     that the scope of a FOR_EXPR is handled properly.  */
 	  if (len)
 	    {
 	      for (i = 0; i < len - 1; ++i)
-		WALK_SUBTREE (TREE_OPERAND (*tp, i));
-	      WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, len - 1));
+		WALK_SUBTREE (TREE_OPERAND (t, i));
+	      WALK_SUBTREE_TAIL (TREE_OPERAND (t, len - 1));
 	    }
 	}
       /* If this is a type, walk the needed fields in the type.  */
-      else if (TYPE_P (*tp))
-	return walk_type_fields (*tp, func, data, pset, lh);
+      else if (TYPE_P (t))
+	return walk_type_fields (t, func, data, pset, lh);
       break;
     }