On Mon, May 18, 2026 at 5:56 PM Andrew Pinski <[email protected]> wrote: > > We use unshare_expr in many places now outside of gimple > even. So it makes sense to move the decl to tree.h. > A few sources can now even not need to include gimplify.h; > I have not checked all of them just a few which seemed > like including gimplify.h didn't make sense. > > This also moves the implementations of unshare_expr, > unshare_expr_without_location and copy_if_shared from gimplify.cc > to tree.cc to keep the headers "clean". > > Bootstrapped and tested on x86_64-linux-gnu.
OK > Changes since v1: > * v2: Move implementation too. > > gcc/ChangeLog: > > * cfgrtl.cc: Don't include gimplify.h or gimplify-me.h. > * cgraphbuild.cc: Likewise. > * emit-rtl.cc: Likewie. > * tree-ssa-dom.cc: Likewise. > * tree-ssa-dse.cc: Likewise. > * tree-ssa-loop-im.cc: Likewise. > * tree-ssa-loop-niter.cc: Likewise. > * tree-ssa-loop-unswitch.cc: Likewise. > * tree-ssa-math-opts.cc: Likewise. > * tree-ssa-phiopt.cc: Likewise. > * tree-ssa-phiprop.cc: Likewise. > * tree-ssa-pre.cc: Likewise. > * tree-ssa-propagate.cc: Likewise. > * tree-ssa-sccvn.cc: Likewise. > * gimplify.h (unshare_expr): Remove. > (unshare_expr_without_location): Remove. > (copy_if_shared): Remove. > * tree.h (unshare_expr): New decl. > (unshare_expr_without_location): Likewise. > (copy_if_shared): Likewise. > * gimplify.cc (mostly_copy_tree_r): Moved to tree.cc. > (copy_if_shared_r): Likewise. > (copy_if_shared): Likewise. > (unshare_expr): Likewise. > (prune_expr_location): Likewise. > (unshare_expr_without_location): Likewise. > * tree.cc (mostly_copy_tree_r): Moved from gimplify.cc > (copy_if_shared_r): Likewise. > (copy_if_shared): Likewise. > (unshare_expr): Likewise. > (prune_expr_location): Likewise. > (unshare_expr_without_location): Likewise. > > Signed-off-by: Andrew Pinski <[email protected]> > --- > gcc/cfgrtl.cc | 1 - > gcc/cgraphbuild.cc | 1 - > gcc/emit-rtl.cc | 1 - > gcc/gimplify.cc | 160 ---------------------------------- > gcc/gimplify.h | 3 - > gcc/tree-ssa-dom.cc | 1 - > gcc/tree-ssa-dse.cc | 1 - > gcc/tree-ssa-loop-im.cc | 1 - > gcc/tree-ssa-loop-niter.cc | 1 - > gcc/tree-ssa-loop-unswitch.cc | 1 - > gcc/tree-ssa-math-opts.cc | 2 - > gcc/tree-ssa-phiopt.cc | 2 - > gcc/tree-ssa-phiprop.cc | 1 - > gcc/tree-ssa-pre.cc | 1 - > gcc/tree-ssa-propagate.cc | 1 - > gcc/tree-ssa-sccvn.cc | 1 - > gcc/tree.cc | 159 +++++++++++++++++++++++++++++++++ > gcc/tree.h | 9 ++ > 18 files changed, 168 insertions(+), 179 deletions(-) > > diff --git a/gcc/cfgrtl.cc b/gcc/cfgrtl.cc > index 7714e5548c2..0ec72f08fa8 100644 > --- a/gcc/cfgrtl.cc > +++ b/gcc/cfgrtl.cc > @@ -62,7 +62,6 @@ along with GCC; see the file COPYING3. If not see > #include "tree-pass.h" > #include "print-rtl.h" > #include "rtl-iter.h" > -#include "gimplify.h" > #include "profile.h" > #include "sreal.h" > > diff --git a/gcc/cgraphbuild.cc b/gcc/cgraphbuild.cc > index e33a414310b..3faf8395db5 100644 > --- a/gcc/cgraphbuild.cc > +++ b/gcc/cgraphbuild.cc > @@ -31,7 +31,6 @@ along with GCC; see the file COPYING3. If not see > #include "gimple-walk.h" > #include "ipa-utils.h" > #include "except.h" > -#include "gimplify.h" > > /* Context of record_reference. */ > struct record_reference_ctx > diff --git a/gcc/emit-rtl.cc b/gcc/emit-rtl.cc > index e41ec2283b8..7f5d267341a 100644 > --- a/gcc/emit-rtl.cc > +++ b/gcc/emit-rtl.cc > @@ -63,7 +63,6 @@ along with GCC; see the file COPYING3. If not see > #include "rtx-vector-builder.h" > #include "gimple.h" > #include "gimple-ssa.h" > -#include "gimplify.h" > #include "bbitmap.h" > > struct target_rtl default_target_rtl; > diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc > index e4db4b1d9bd..cdd039eb2bd 100644 > --- a/gcc/gimplify.cc > +++ b/gcc/gimplify.cc > @@ -896,131 +896,6 @@ gimple_add_tmp_var (tree tmp) > } > } > > - > - > -/* This page contains routines to unshare tree nodes, i.e. to duplicate tree > - nodes that are referenced more than once in GENERIC functions. This is > - necessary because gimplification (translation into GIMPLE) is performed > - by modifying tree nodes in-place, so gimplification of a shared node in a > - first context could generate an invalid GIMPLE form in a second context. > - > - This is achieved with a simple mark/copy/unmark algorithm that walks the > - GENERIC representation top-down, marks nodes with TREE_VISITED the first > - time it encounters them, duplicates them if they already have TREE_VISITED > - set, and finally removes the TREE_VISITED marks it has set. > - > - The algorithm works only at the function level, i.e. it generates a > GENERIC > - representation of a function with no nodes shared within the function when > - passed a GENERIC function (except for nodes that are allowed to be > shared). > - > - At the global level, it is also necessary to unshare tree nodes that are > - referenced in more than one function, for the same aforementioned reason. > - This requires some cooperation from the front-end. There are 2 > strategies: > - > - 1. Manual unsharing. The front-end needs to call unshare_expr on every > - expression that might end up being shared across functions. > - > - 2. Deep unsharing. This is an extension of regular unsharing. Instead > - of calling unshare_expr on expressions that might be shared across > - functions, the front-end pre-marks them with TREE_VISITED. This will > - ensure that they are unshared on the first reference within functions > - when the regular unsharing algorithm runs. The counterpart is that > - this algorithm must look deeper than for manual unsharing, which is > - specified by LANG_HOOKS_DEEP_UNSHARING. > - > - If there are only few specific cases of node sharing across functions, it > is > - probably easier for a front-end to unshare the expressions manually. On > the > - contrary, if the expressions generated at the global level are as > widespread > - as expressions generated within functions, deep unsharing is very likely > the > - way to go. */ > - > -/* Similar to copy_tree_r but do not copy SAVE_EXPR or TARGET_EXPR nodes. > - These nodes model computations that must be done once. If we were to > - unshare something like SAVE_EXPR(i++), the gimplification process would > - create wrong code. However, if DATA is non-null, it must hold a pointer > - set that is used to unshare the subtrees of these nodes. */ > - > -static tree > -mostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data) > -{ > - tree t = *tp; > - enum tree_code code = TREE_CODE (t); > - > - /* Do not copy SAVE_EXPR, TARGET_EXPR or BIND_EXPR nodes themselves, but > - copy their subtrees if we can make sure to do it only once. */ > - if (code == SAVE_EXPR || code == TARGET_EXPR || code == BIND_EXPR) > - { > - if (data && !((hash_set<tree> *)data)->add (t)) > - ; > - else > - *walk_subtrees = 0; > - } > - > - /* Stop at types, decls, constants like copy_tree_r. */ > - else if (TREE_CODE_CLASS (code) == tcc_type > - || TREE_CODE_CLASS (code) == tcc_declaration > - || TREE_CODE_CLASS (code) == tcc_constant) > - *walk_subtrees = 0; > - > - /* Cope with the statement expression extension. */ > - else if (code == STATEMENT_LIST) > - ; > - > - /* Leave the bulk of the work to copy_tree_r itself. */ > - else > - copy_tree_r (tp, walk_subtrees, NULL); > - > - return NULL_TREE; > -} > - > -/* Callback for walk_tree to unshare most of the shared trees rooted at *TP. > - If *TP has been visited already, then *TP is deeply copied by calling > - mostly_copy_tree_r. DATA is passed to mostly_copy_tree_r unmodified. */ > - > -static tree > -copy_if_shared_r (tree *tp, int *walk_subtrees, void *data) > -{ > - tree t = *tp; > - enum tree_code code = TREE_CODE (t); > - > - /* Skip types, decls, and constants. But we do want to look at their > - types and the bounds of types. Mark them as visited so we properly > - unmark their subtrees on the unmark pass. If we've already seen them, > - don't look down further. */ > - if (TREE_CODE_CLASS (code) == tcc_type > - || TREE_CODE_CLASS (code) == tcc_declaration > - || TREE_CODE_CLASS (code) == tcc_constant) > - { > - if (TREE_VISITED (t)) > - *walk_subtrees = 0; > - else > - TREE_VISITED (t) = 1; > - } > - > - /* If this node has been visited already, unshare it and don't look > - any deeper. */ > - else if (TREE_VISITED (t)) > - { > - walk_tree (tp, mostly_copy_tree_r, data, NULL); > - *walk_subtrees = 0; > - } > - > - /* Otherwise, mark the node as visited and keep looking. */ > - else > - TREE_VISITED (t) = 1; > - > - return NULL_TREE; > -} > - > -/* Unshare most of the shared trees rooted at *TP. DATA is passed to the > - copy_if_shared_r callback unmodified. */ > - > -void > -copy_if_shared (tree *tp, void *data) > -{ > - walk_tree (tp, copy_if_shared_r, data, NULL); > -} > - > /* Unshare all the trees in the body of FNDECL, as well as in the bodies of > any nested functions. */ > > @@ -1089,41 +964,6 @@ unvisit_body (tree fndecl) > unvisit_body (cgn->decl); > } > > -/* Unconditionally make an unshared copy of EXPR. This is used when using > - stored expressions which span multiple functions, such as BINFO_VTABLE, > - as the normal unsharing process can't tell that they're shared. */ > - > -tree > -unshare_expr (tree expr) > -{ > - walk_tree (&expr, mostly_copy_tree_r, NULL, NULL); > - return expr; > -} > - > -/* Worker for unshare_expr_without_location. */ > - > -static tree > -prune_expr_location (tree *tp, int *walk_subtrees, void *) > -{ > - if (EXPR_P (*tp)) > - SET_EXPR_LOCATION (*tp, UNKNOWN_LOCATION); > - else > - *walk_subtrees = 0; > - return NULL_TREE; > -} > - > -/* Similar to unshare_expr but also prune all expression locations > - from EXPR. */ > - > -tree > -unshare_expr_without_location (tree expr) > -{ > - walk_tree (&expr, mostly_copy_tree_r, NULL, NULL); > - if (EXPR_P (expr)) > - walk_tree (&expr, prune_expr_location, NULL, NULL); > - return expr; > -} > - > /* Return the EXPR_LOCATION of EXPR, if it (maybe recursively) has > one, OR_ELSE otherwise. The location of a STATEMENT_LISTs > comprising at least one DEBUG_BEGIN_STMT followed by exactly one > diff --git a/gcc/gimplify.h b/gcc/gimplify.h > index caa35b426bd..18c7514c9a3 100644 > --- a/gcc/gimplify.h > +++ b/gcc/gimplify.h > @@ -62,9 +62,6 @@ extern tree get_initialized_tmp_var (tree, gimple_seq *, > gimple_seq * = NULL, > extern void declare_vars (tree, gimple *, bool); > extern void gimple_add_tmp_var (tree); > extern void gimple_add_tmp_var_fn (struct function *, tree); > -extern void copy_if_shared (tree *, void * = NULL); > -extern tree unshare_expr (tree); > -extern tree unshare_expr_without_location (tree); > extern tree voidify_wrapper_expr (tree, tree); > extern tree build_and_jump (tree *); > extern enum gimplify_status gimplify_self_mod_expr (tree *, gimple_seq *, > diff --git a/gcc/tree-ssa-dom.cc b/gcc/tree-ssa-dom.cc > index 3be7979f528..37a29697319 100644 > --- a/gcc/tree-ssa-dom.cc > +++ b/gcc/tree-ssa-dom.cc > @@ -42,7 +42,6 @@ along with GCC; see the file COPYING3. If not see > #include "tree-ssa-scopedtables.h" > #include "tree-ssa-threadedge.h" > #include "tree-ssa-dom.h" > -#include "gimplify.h" > #include "tree-cfgcleanup.h" > #include "dbgcnt.h" > #include "alloc-pool.h" > diff --git a/gcc/tree-ssa-dse.cc b/gcc/tree-ssa-dse.cc > index 58cfa9ec129..2f97d6d1a1a 100644 > --- a/gcc/tree-ssa-dse.cc > +++ b/gcc/tree-ssa-dse.cc > @@ -37,7 +37,6 @@ along with GCC; see the file COPYING3. If not see > #include "tree-ssa-dse.h" > #include "builtins.h" > #include "gimple-fold.h" > -#include "gimplify.h" > #include "tree-eh.h" > #include "cfganal.h" > #include "cgraph.h" > diff --git a/gcc/tree-ssa-loop-im.cc b/gcc/tree-ssa-loop-im.cc > index 4f7401e2d5d..2651e3919e3 100644 > --- a/gcc/tree-ssa-loop-im.cc > +++ b/gcc/tree-ssa-loop-im.cc > @@ -30,7 +30,6 @@ along with GCC; see the file COPYING3. If not see > #include "fold-const.h" > #include "cfganal.h" > #include "tree-eh.h" > -#include "gimplify.h" > #include "gimple-iterator.h" > #include "tree-cfg.h" > #include "tree-ssa-loop-manip.h" > diff --git a/gcc/tree-ssa-loop-niter.cc b/gcc/tree-ssa-loop-niter.cc > index c39401147ae..f179be1ffc7 100644 > --- a/gcc/tree-ssa-loop-niter.cc > +++ b/gcc/tree-ssa-loop-niter.cc > @@ -32,7 +32,6 @@ along with GCC; see the file COPYING3. If not see > #include "fold-const.h" > #include "calls.h" > #include "intl.h" > -#include "gimplify.h" > #include "gimple-iterator.h" > #include "tree-cfg.h" > #include "tree-ssa-loop-ivopts.h" > diff --git a/gcc/tree-ssa-loop-unswitch.cc b/gcc/tree-ssa-loop-unswitch.cc > index 96680bc64ea..a18c9ccfffa 100644 > --- a/gcc/tree-ssa-loop-unswitch.cc > +++ b/gcc/tree-ssa-loop-unswitch.cc > @@ -26,7 +26,6 @@ along with GCC; see the file COPYING3. If not see > #include "tree-pass.h" > #include "ssa.h" > #include "fold-const.h" > -#include "gimplify.h" > #include "tree-cfg.h" > #include "tree-ssa.h" > #include "tree-ssa-loop-niter.h" > diff --git a/gcc/tree-ssa-math-opts.cc b/gcc/tree-ssa-math-opts.cc > index cd3fd2fc8fb..72f6dbd1a99 100644 > --- a/gcc/tree-ssa-math-opts.cc > +++ b/gcc/tree-ssa-math-opts.cc > @@ -102,8 +102,6 @@ along with GCC; see the file COPYING3. If not see > #include "fold-const.h" > #include "gimple-iterator.h" > #include "gimple-fold.h" > -#include "gimplify.h" > -#include "gimplify-me.h" > #include "stor-layout.h" > #include "tree-cfg.h" > #include "tree-dfa.h" > diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc > index e654e823636..18b5f284eee 100644 > --- a/gcc/tree-ssa-phiopt.cc > +++ b/gcc/tree-ssa-phiopt.cc > @@ -35,9 +35,7 @@ along with GCC; see the file COPYING3. If not see > #include "fold-const.h" > #include "stor-layout.h" > #include "cfganal.h" > -#include "gimplify.h" > #include "gimple-iterator.h" > -#include "gimplify-me.h" > #include "tree-cfg.h" > #include "tree-dfa.h" > #include "domwalk.h" > diff --git a/gcc/tree-ssa-phiprop.cc b/gcc/tree-ssa-phiprop.cc > index 54f3ad8d9f8..7e7a4534eb2 100644 > --- a/gcc/tree-ssa-phiprop.cc > +++ b/gcc/tree-ssa-phiprop.cc > @@ -29,7 +29,6 @@ along with GCC; see the file COPYING3. If not see > #include "gimple-pretty-print.h" > #include "fold-const.h" > #include "tree-eh.h" > -#include "gimplify.h" > #include "gimple-iterator.h" > #include "stor-layout.h" > #include "tree-ssa-loop.h" > diff --git a/gcc/tree-ssa-pre.cc b/gcc/tree-ssa-pre.cc > index 0e5eaf86bc7..5ded68443dd 100644 > --- a/gcc/tree-ssa-pre.cc > +++ b/gcc/tree-ssa-pre.cc > @@ -37,7 +37,6 @@ along with GCC; see the file COPYING3. If not see > #include "gimple-iterator.h" > #include "gimple-fold.h" > #include "tree-eh.h" > -#include "gimplify.h" > #include "tree-cfg.h" > #include "tree-into-ssa.h" > #include "tree-dfa.h" > diff --git a/gcc/tree-ssa-propagate.cc b/gcc/tree-ssa-propagate.cc > index a87c45d3a12..992b4243670 100644 > --- a/gcc/tree-ssa-propagate.cc > +++ b/gcc/tree-ssa-propagate.cc > @@ -30,7 +30,6 @@ > #include "gimple-iterator.h" > #include "gimple-fold.h" > #include "tree-eh.h" > -#include "gimplify.h" > #include "tree-cfg.h" > #include "tree-ssa.h" > #include "tree-ssa-propagate.h" > diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc > index e19beb439d2..79b6b465294 100644 > --- a/gcc/tree-ssa-sccvn.cc > +++ b/gcc/tree-ssa-sccvn.cc > @@ -42,7 +42,6 @@ along with GCC; see the file COPYING3. If not see > #include "gimple-iterator.h" > #include "gimple-fold.h" > #include "tree-eh.h" > -#include "gimplify.h" > #include "flags.h" > #include "dojump.h" > #include "explow.h" > diff --git a/gcc/tree.cc b/gcc/tree.cc > index 8479ffab584..e3df004be97 100644 > --- a/gcc/tree.cc > +++ b/gcc/tree.cc > @@ -15847,6 +15847,165 @@ diagnose_versioned_decls (tree old_decl, tree > new_decl) > (old_target_attr, old_decl, new_target_attr, new_decl); > } > > + > +/* This page contains routines to unshare tree nodes, i.e. to duplicate tree > + nodes that are referenced more than once in GENERIC functions. This is > + necessary because gimplification (translation into GIMPLE) is performed > + by modifying tree nodes in-place, so gimplification of a shared node in a > + first context could generate an invalid GIMPLE form in a second context. > + > + This is achieved with a simple mark/copy/unmark algorithm that walks the > + GENERIC representation top-down, marks nodes with TREE_VISITED the first > + time it encounters them, duplicates them if they already have TREE_VISITED > + set, and finally removes the TREE_VISITED marks it has set. > + > + The algorithm works only at the function level, i.e. it generates a > GENERIC > + representation of a function with no nodes shared within the function when > + passed a GENERIC function (except for nodes that are allowed to be > shared). > + > + At the global level, it is also necessary to unshare tree nodes that are > + referenced in more than one function, for the same aforementioned reason. > + This requires some cooperation from the front-end. There are 2 > strategies: > + > + 1. Manual unsharing. The front-end needs to call unshare_expr on every > + expression that might end up being shared across functions. > + > + 2. Deep unsharing. This is an extension of regular unsharing. Instead > + of calling unshare_expr on expressions that might be shared across > + functions, the front-end pre-marks them with TREE_VISITED. This will > + ensure that they are unshared on the first reference within functions > + when the regular unsharing algorithm runs. The counterpart is that > + this algorithm must look deeper than for manual unsharing, which is > + specified by LANG_HOOKS_DEEP_UNSHARING. > + > + If there are only few specific cases of node sharing across functions, it > is > + probably easier for a front-end to unshare the expressions manually. On > the > + contrary, if the expressions generated at the global level are as > widespread > + as expressions generated within functions, deep unsharing is very likely > the > + way to go. */ > + > +/* Similar to copy_tree_r but do not copy SAVE_EXPR or TARGET_EXPR nodes. > + These nodes model computations that must be done once. If we were to > + unshare something like SAVE_EXPR(i++), the gimplification process would > + create wrong code. However, if DATA is non-null, it must hold a pointer > + set that is used to unshare the subtrees of these nodes. */ > + > +static tree > +mostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data) > +{ > + tree t = *tp; > + enum tree_code code = TREE_CODE (t); > + > + /* Do not copy SAVE_EXPR, TARGET_EXPR or BIND_EXPR nodes themselves, but > + copy their subtrees if we can make sure to do it only once. */ > + if (code == SAVE_EXPR || code == TARGET_EXPR || code == BIND_EXPR) > + { > + if (data && !((hash_set<tree> *)data)->add (t)) > + ; > + else > + *walk_subtrees = 0; > + } > + > + /* Stop at types, decls, constants like copy_tree_r. */ > + else if (TREE_CODE_CLASS (code) == tcc_type > + || TREE_CODE_CLASS (code) == tcc_declaration > + || TREE_CODE_CLASS (code) == tcc_constant) > + *walk_subtrees = 0; > + > + /* Cope with the statement expression extension. */ > + else if (code == STATEMENT_LIST) > + ; > + > + /* Leave the bulk of the work to copy_tree_r itself. */ > + else > + copy_tree_r (tp, walk_subtrees, NULL); > + > + return NULL_TREE; > +} > + > +/* Callback for walk_tree to unshare most of the shared trees rooted at *TP. > + If *TP has been visited already, then *TP is deeply copied by calling > + mostly_copy_tree_r. DATA is passed to mostly_copy_tree_r unmodified. */ > + > +static tree > +copy_if_shared_r (tree *tp, int *walk_subtrees, void *data) > +{ > + tree t = *tp; > + enum tree_code code = TREE_CODE (t); > + > + /* Skip types, decls, and constants. But we do want to look at their > + types and the bounds of types. Mark them as visited so we properly > + unmark their subtrees on the unmark pass. If we've already seen them, > + don't look down further. */ > + if (TREE_CODE_CLASS (code) == tcc_type > + || TREE_CODE_CLASS (code) == tcc_declaration > + || TREE_CODE_CLASS (code) == tcc_constant) > + { > + if (TREE_VISITED (t)) > + *walk_subtrees = 0; > + else > + TREE_VISITED (t) = 1; > + } > + > + /* If this node has been visited already, unshare it and don't look > + any deeper. */ > + else if (TREE_VISITED (t)) > + { > + walk_tree (tp, mostly_copy_tree_r, data, NULL); > + *walk_subtrees = 0; > + } > + > + /* Otherwise, mark the node as visited and keep looking. */ > + else > + TREE_VISITED (t) = 1; > + > + return NULL_TREE; > +} > + > +/* Unshare most of the shared trees rooted at *TP. DATA is passed to the > + copy_if_shared_r callback unmodified. */ > + > +void > +copy_if_shared (tree *tp, void *data) > +{ > + walk_tree (tp, copy_if_shared_r, data, NULL); > +} > + > +/* Unconditionally make an unshared copy of EXPR. This is used when using > + stored expressions which span multiple functions, such as BINFO_VTABLE, > + as the normal unsharing process can't tell that they're shared. */ > + > +tree > +unshare_expr (tree expr) > +{ > + walk_tree (&expr, mostly_copy_tree_r, NULL, NULL); > + return expr; > +} > + > +/* Worker for unshare_expr_without_location. */ > + > +static tree > +prune_expr_location (tree *tp, int *walk_subtrees, void *) > +{ > + if (EXPR_P (*tp)) > + SET_EXPR_LOCATION (*tp, UNKNOWN_LOCATION); > + else > + *walk_subtrees = 0; > + return NULL_TREE; > +} > + > +/* Similar to unshare_expr but also prune all expression locations > + from EXPR. */ > + > +tree > +unshare_expr_without_location (tree expr) > +{ > + walk_tree (&expr, mostly_copy_tree_r, NULL, NULL); > + if (EXPR_P (expr)) > + walk_tree (&expr, prune_expr_location, NULL, NULL); > + return expr; > +} > + > void > tree_cc_finalize (void) > { > diff --git a/gcc/tree.h b/gcc/tree.h > index 3b012d0fd6a..05400ada20b 100644 > --- a/gcc/tree.h > +++ b/gcc/tree.h > @@ -7204,4 +7204,13 @@ extern bool disjoint_version_decls (tree, tree); > /* Checks if two overlapping decls are not mergeable. */ > extern bool diagnose_versioned_decls (tree, tree); > > +/* Unshare tree if needed. */ > +extern tree unshare_expr (tree); > + > +/* Unshare tree if needed. > + Removing the locations if an expr. */ > +extern tree unshare_expr_without_location (tree); > + > +extern void copy_if_shared (tree *, void * = NULL); > + > #endif /* GCC_TREE_H */ > -- > 2.43.0 >
