LCOV - code coverage report
Current view: top level - gcc - tree-nested.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 89.4 % 1991 1780
Test Date: 2026-06-20 15:32:29 Functions: 95.2 % 63 60
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Nested function decomposition for GIMPLE.
       2              :    Copyright (C) 2004-2026 Free Software Foundation, Inc.
       3              : 
       4              :    This file is part of GCC.
       5              : 
       6              :    GCC is free software; you can redistribute it and/or modify
       7              :    it under the terms of the GNU General Public License as published by
       8              :    the Free Software Foundation; either version 3, or (at your option)
       9              :    any later version.
      10              : 
      11              :    GCC is distributed in the hope that it will be useful,
      12              :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      13              :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14              :    GNU General Public License for more details.
      15              : 
      16              :    You should have received a copy of the GNU General Public License
      17              :    along with GCC; see the file COPYING3.  If not see
      18              :    <http://www.gnu.org/licenses/>.  */
      19              : 
      20              : #include "config.h"
      21              : #include "system.h"
      22              : #include "coretypes.h"
      23              : #include "backend.h"
      24              : #include "target.h"
      25              : #include "rtl.h"
      26              : #include "tree.h"
      27              : #include "gimple.h"
      28              : #include "memmodel.h"
      29              : #include "tm_p.h"
      30              : #include "stringpool.h"
      31              : #include "cgraph.h"
      32              : #include "fold-const.h"
      33              : #include "stor-layout.h"
      34              : #include "dumpfile.h"
      35              : #include "tree-inline.h"
      36              : #include "gimplify.h"
      37              : #include "gimple-iterator.h"
      38              : #include "gimple-walk.h"
      39              : #include "tree-cfg.h"
      40              : #include "explow.h"
      41              : #include "langhooks.h"
      42              : #include "gimple-low.h"
      43              : #include "gomp-constants.h"
      44              : #include "diagnostic.h"
      45              : #include "alloc-pool.h"
      46              : #include "tree-nested.h"
      47              : #include "symbol-summary.h"
      48              : #include "symtab-thunks.h"
      49              : #include "attribs.h"
      50              : 
      51              : /* Summary of nested functions.  */
      52              : static function_summary <nested_function_info *>
      53              :    *nested_function_sum = NULL;
      54              : 
      55              : /* Return nested_function_info, if available.  */
      56              : nested_function_info *
      57    146362337 : nested_function_info::get (cgraph_node *node)
      58              : {
      59    146362337 :   if (!nested_function_sum)
      60              :     return NULL;
      61       709735 :   return nested_function_sum->get (node);
      62              : }
      63              : 
      64              : /* Return nested_function_info possibly creating new one.  */
      65              : nested_function_info *
      66        51968 : nested_function_info::get_create (cgraph_node *node)
      67              : {
      68        51968 :   if (!nested_function_sum)
      69              :     {
      70        18214 :       nested_function_sum = new function_summary <nested_function_info *>
      71         9107 :                                    (symtab);
      72         9107 :       nested_function_sum->disable_insertion_hook ();
      73              :     }
      74        51968 :   return nested_function_sum->get_create (node);
      75              : }
      76              : 
      77              : /* cgraph_node is no longer nested function; update cgraph accordingly.  */
      78              : void
      79        25734 : unnest_function (cgraph_node *node)
      80              : {
      81        25734 :   nested_function_info *info = nested_function_info::get (node);
      82        25734 :   cgraph_node **node2 = &nested_function_info::get
      83        25734 :                 (nested_function_origin (node))->nested;
      84              : 
      85        25734 :   gcc_checking_assert (info->origin);
      86       132292 :   while (*node2 != node)
      87       106558 :     node2 = &nested_function_info::get (*node2)->next_nested;
      88        25734 :   *node2 = info->next_nested;
      89        25734 :   info->next_nested = NULL;
      90        25734 :   info->origin = NULL;
      91        25734 :   nested_function_sum->remove (node);
      92        25734 : }
      93              : 
      94              : /* Destructor: unlink function from nested function lists.  */
      95        35693 : nested_function_info::~nested_function_info ()
      96              : {
      97        35693 :   cgraph_node *next;
      98        35796 :   for (cgraph_node *n = nested; n; n = next)
      99              :     {
     100          103 :       nested_function_info *info = nested_function_info::get (n);
     101          103 :       next = info->next_nested;
     102          103 :       info->origin = NULL;
     103          103 :       info->next_nested = NULL;
     104              :     }
     105        35693 :   nested = NULL;
     106        35693 :   if (origin)
     107              :     {
     108          147 :       cgraph_node **node2
     109          147 :              = &nested_function_info::get (origin)->nested;
     110              : 
     111          147 :       nested_function_info *info;
     112          147 :       while ((info = nested_function_info::get (*node2)) != this && info)
     113            0 :         node2 = &info->next_nested;
     114          147 :       *node2 = next_nested;
     115              :     }
     116        35693 : }
     117              : 
     118              : /* Free nested function info summaries.  */
     119              : void
     120       533965 : nested_function_info::release ()
     121              : {
     122       533965 :   if (nested_function_sum)
     123         9103 :     delete (nested_function_sum);
     124       533965 :   nested_function_sum = NULL;
     125       533965 : }
     126              : 
     127              : /* If NODE is nested function, record it.  */
     128              : void
     129    104650900 : maybe_record_nested_function (cgraph_node *node)
     130              : {
     131              :   /* All nested functions gets lowered during the construction of symtab.  */
     132    104650900 :   if (symtab->state > CONSTRUCTION)
     133              :     return;
     134    104532345 :   if (DECL_CONTEXT (node->decl)
     135    104532345 :       && TREE_CODE (DECL_CONTEXT (node->decl)) == FUNCTION_DECL)
     136              :     {
     137        25984 :       cgraph_node *origin = cgraph_node::get_create (DECL_CONTEXT (node->decl));
     138        25984 :       nested_function_info *info = nested_function_info::get_create (node);
     139        25984 :       nested_function_info *origin_info
     140        25984 :                  = nested_function_info::get_create (origin);
     141              : 
     142        25984 :       info->origin = origin;
     143        25984 :       info->next_nested = origin_info->nested;
     144        25984 :       origin_info->nested = node;
     145              :     }
     146              : }
     147              : 
     148              : /* The object of this pass is to lower the representation of a set of nested
     149              :    functions in order to expose all of the gory details of the various
     150              :    nonlocal references.  We want to do this sooner rather than later, in
     151              :    order to give us more freedom in emitting all of the functions in question.
     152              : 
     153              :    Back in olden times, when gcc was young, we developed an insanely
     154              :    complicated scheme whereby variables which were referenced nonlocally
     155              :    were forced to live in the stack of the declaring function, and then
     156              :    the nested functions magically discovered where these variables were
     157              :    placed.  In order for this scheme to function properly, it required
     158              :    that the outer function be partially expanded, then we switch to
     159              :    compiling the inner function, and once done with those we switch back
     160              :    to compiling the outer function.  Such delicate ordering requirements
     161              :    makes it difficult to do whole translation unit optimizations
     162              :    involving such functions.
     163              : 
     164              :    The implementation here is much more direct.  Everything that can be
     165              :    referenced by an inner function is a member of an explicitly created
     166              :    structure herein called the "nonlocal frame struct".  The incoming
     167              :    static chain for a nested function is a pointer to this struct in
     168              :    the parent.  In this way, we settle on known offsets from a known
     169              :    base, and so are decoupled from the logic that places objects in the
     170              :    function's stack frame.  More importantly, we don't have to wait for
     171              :    that to happen -- since the compilation of the inner function is no
     172              :    longer tied to a real stack frame, the nonlocal frame struct can be
     173              :    allocated anywhere.  Which means that the outer function is now
     174              :    inlinable.
     175              : 
     176              :    Theory of operation here is very simple.  Iterate over all the
     177              :    statements in all the functions (depth first) several times,
     178              :    allocating structures and fields on demand.  In general we want to
     179              :    examine inner functions first, so that we can avoid making changes
     180              :    to outer functions which are unnecessary.
     181              : 
     182              :    The order of the passes matters a bit, in that later passes will be
     183              :    skipped if it is discovered that the functions don't actually interact
     184              :    at all.  That is, they're nested in the lexical sense but could have
     185              :    been written as independent functions without change.  */
     186              : 
     187              : 
     188              : struct nesting_info
     189              : {
     190              :   struct nesting_info *outer;
     191              :   struct nesting_info *inner;
     192              :   struct nesting_info *next;
     193              : 
     194              :   hash_map<tree, tree> *field_map;
     195              :   hash_map<tree, tree> *var_map;
     196              :   hash_set<tree *> *mem_refs;
     197              :   bitmap suppress_expansion;
     198              : 
     199              :   tree context;
     200              :   tree new_local_var_chain;
     201              :   tree debug_var_chain;
     202              :   tree frame_type;
     203              :   tree frame_decl;
     204              :   tree chain_field;
     205              :   tree chain_decl;
     206              :   tree nl_goto_field;
     207              : 
     208              :   bool thunk_p;
     209              :   bool any_parm_remapped;
     210              :   bool any_tramp_created;
     211              :   bool any_descr_created;
     212              :   char static_chain_added;
     213              : };
     214              : 
     215              : 
     216              : /* Iterate over the nesting tree, starting with ROOT, depth first.  */
     217              : 
     218              : static inline struct nesting_info *
     219        86726 : iter_nestinfo_start (struct nesting_info *root)
     220              : {
     221       389542 :   while (root->inner)
     222              :     root = root->inner;
     223              :   return root;
     224              : }
     225              : 
     226              : static inline struct nesting_info *
     227       389542 : iter_nestinfo_next (struct nesting_info *node)
     228              : {
     229       389542 :   if (node->next)
     230              :     return iter_nestinfo_start (node->next);
     231       215649 :   return node->outer;
     232              : }
     233              : 
     234              : #define FOR_EACH_NEST_INFO(I, ROOT) \
     235              :   for ((I) = iter_nestinfo_start (ROOT); (I); (I) = iter_nestinfo_next (I))
     236              : 
     237              : /* Obstack used for the bitmaps in the struct above.  */
     238              : static struct bitmap_obstack nesting_info_bitmap_obstack;
     239              : 
     240              : 
     241              : /* We're working in so many different function contexts simultaneously,
     242              :    that create_tmp_var is dangerous.  Prevent mishap.  */
     243              : #define create_tmp_var cant_use_create_tmp_var_here_dummy
     244              : 
     245              : /* Like create_tmp_var, except record the variable for registration at
     246              :    the given nesting level.  */
     247              : 
     248              : static tree
     249        20823 : create_tmp_var_for (struct nesting_info *info, tree type, const char *prefix)
     250              : {
     251        20823 :   tree tmp_var;
     252              : 
     253              :   /* If the type is of variable size or a type which must be created by the
     254              :      frontend, something is wrong.  Note that we explicitly allow
     255              :      incomplete types here, since we create them ourselves here.  */
     256        20823 :   gcc_assert (!TREE_ADDRESSABLE (type));
     257        20823 :   gcc_assert (!TYPE_SIZE_UNIT (type)
     258              :               || TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST);
     259              : 
     260        20823 :   tmp_var = create_tmp_var_raw (type, prefix);
     261        20823 :   DECL_CONTEXT (tmp_var) = info->context;
     262        20823 :   DECL_CHAIN (tmp_var) = info->new_local_var_chain;
     263        20823 :   DECL_SEEN_IN_BIND_EXPR_P (tmp_var) = 1;
     264              : 
     265        20823 :   info->new_local_var_chain = tmp_var;
     266              : 
     267        20823 :   return tmp_var;
     268              : }
     269              : 
     270              : /* Like build_simple_mem_ref, but set TREE_THIS_NOTRAP on the result.  */
     271              : 
     272              : static tree
     273        23014 : build_simple_mem_ref_notrap (tree ptr)
     274              : {
     275        23014 :   tree t = build_simple_mem_ref (ptr);
     276        23014 :   TREE_THIS_NOTRAP (t) = 1;
     277        23014 :   return t;
     278              : }
     279              : 
     280              : /* Take the address of EXP to be used within function CONTEXT.
     281              :    Mark it for addressability as necessary.  */
     282              : 
     283              : tree
     284        56253 : build_addr (tree exp)
     285              : {
     286        56253 :   mark_addressable (exp);
     287        56253 :   return build_fold_addr_expr (exp);
     288              : }
     289              : 
     290              : /* Insert FIELD into TYPE, sorted by alignment requirements.  */
     291              : 
     292              : void
     293       176143 : insert_field_into_struct (tree type, tree field)
     294              : {
     295       176143 :   tree *p;
     296              : 
     297       176143 :   DECL_CONTEXT (field) = type;
     298              : 
     299       216936 :   for (p = &TYPE_FIELDS (type); *p ; p = &DECL_CHAIN (*p))
     300       156756 :     if (DECL_ALIGN (field) >= DECL_ALIGN (*p))
     301              :       break;
     302              : 
     303       176143 :   DECL_CHAIN (field) = *p;
     304       176143 :   *p = field;
     305              : 
     306              :   /* Set correct alignment for frame struct type.  */
     307       176143 :   if (TYPE_ALIGN (type) < DECL_ALIGN (field))
     308        58019 :     SET_TYPE_ALIGN (type, DECL_ALIGN (field));
     309       176143 : }
     310              : 
     311              : /* Build or return the RECORD_TYPE that describes the frame state that is
     312              :    shared between INFO->CONTEXT and its nested functions.  This record will
     313              :    not be complete until finalize_nesting_tree; up until that point we'll
     314              :    be adding fields as necessary.
     315              : 
     316              :    We also build the DECL that represents this frame in the function.  */
     317              : 
     318              : static tree
     319        36299 : get_frame_type (struct nesting_info *info)
     320              : {
     321        36299 :   tree type = info->frame_type;
     322        36299 :   if (!type)
     323              :     {
     324         3538 :       char *name;
     325              : 
     326         3538 :       type = make_node (RECORD_TYPE);
     327              : 
     328        10614 :       name = concat ("FRAME.",
     329         3538 :                      IDENTIFIER_POINTER (DECL_NAME (info->context)),
     330              :                      NULL);
     331         3538 :       TYPE_NAME (type) = get_identifier (name);
     332         3538 :       free (name);
     333              : 
     334         3538 :       info->frame_type = type;
     335              : 
     336              :       /* Do not put info->frame_decl on info->new_local_var_chain,
     337              :          so that we can declare it in the lexical blocks, which
     338              :          makes sure virtual regs that end up appearing in its RTL
     339              :          expression get substituted in instantiate_virtual_regs.  */
     340         3538 :       info->frame_decl = create_tmp_var_raw (type, "FRAME");
     341         3538 :       DECL_CONTEXT (info->frame_decl) = info->context;
     342         3538 :       DECL_NONLOCAL_FRAME (info->frame_decl) = 1;
     343         3538 :       DECL_SEEN_IN_BIND_EXPR_P (info->frame_decl) = 1;
     344              : 
     345              :       /* ??? Always make it addressable for now, since it is meant to
     346              :          be pointed to by the static chain pointer.  This pessimizes
     347              :          when it turns out that no static chains are needed because
     348              :          the nested functions referencing non-local variables are not
     349              :          reachable, but the true pessimization is to create the non-
     350              :          local frame structure in the first place.  */
     351         3538 :       TREE_ADDRESSABLE (info->frame_decl) = 1;
     352              :     }
     353              : 
     354        36299 :   return type;
     355              : }
     356              : 
     357              : /* Return true if DECL should be referenced by pointer in the non-local frame
     358              :    structure.  */
     359              : 
     360              : static bool
     361      4944492 : use_pointer_in_frame (tree decl)
     362              : {
     363      4944492 :   if (TREE_CODE (decl) == PARM_DECL)
     364              :     {
     365              :       /* It's illegal to copy TREE_ADDRESSABLE, impossible to copy variable-
     366              :          sized DECLs, and inefficient to copy large aggregates.  Don't bother
     367              :          moving anything but scalar parameters.  */
     368       197611 :       return AGGREGATE_TYPE_P (TREE_TYPE (decl));
     369              :     }
     370              :   else
     371              :     {
     372              :       /* Variable-sized DECLs can only come from OMP clauses at this point
     373              :          since the gimplifier has already turned the regular variables into
     374              :          pointers.  Do the same as the gimplifier.  */
     375      4746881 :       return !DECL_SIZE (decl) || TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST;
     376              :     }
     377              : }
     378              : 
     379              : /* Given DECL, a non-locally accessed variable, find or create a field
     380              :    in the non-local frame structure for the given nesting context.  */
     381              : 
     382              : static tree
     383      4940828 : lookup_field_for_decl (struct nesting_info *info, tree decl,
     384              :                        enum insert_option insert)
     385              : {
     386      4940828 :   gcc_checking_assert (decl_function_context (decl) == info->context);
     387              : 
     388      4940828 :   if (insert == NO_INSERT)
     389              :     {
     390      4918534 :       tree *slot = info->field_map->get (decl);
     391      4918534 :       return slot ? *slot : NULL_TREE;
     392              :     }
     393              : 
     394        22294 :   tree *slot = &info->field_map->get_or_insert (decl);
     395        22294 :   if (!*slot)
     396              :     {
     397         3490 :       tree type = get_frame_type (info);
     398         3490 :       tree field = make_node (FIELD_DECL);
     399         3490 :       DECL_NAME (field) = DECL_NAME (decl);
     400              : 
     401         3490 :       if (use_pointer_in_frame (decl))
     402              :         {
     403           27 :           TREE_TYPE (field) = build_pointer_type (TREE_TYPE (decl));
     404           27 :           SET_DECL_ALIGN (field, TYPE_ALIGN (TREE_TYPE (field)));
     405           27 :           DECL_NONADDRESSABLE_P (field) = 1;
     406              :         }
     407              :       else
     408              :         {
     409         3463 :           TREE_TYPE (field) = TREE_TYPE (decl);
     410         3463 :           DECL_SOURCE_LOCATION (field) = DECL_SOURCE_LOCATION (decl);
     411         3463 :           SET_DECL_ALIGN (field, DECL_ALIGN (decl));
     412         3463 :           DECL_USER_ALIGN (field) = DECL_USER_ALIGN (decl);
     413         3463 :           DECL_IGNORED_P (field) = DECL_IGNORED_P (decl);
     414              :           /* Even if the address of the DECL is not needed, when it is of an
     415              :              aggregate type, it may contain addressable fields whose address
     416              :              will be taken later.  */
     417         6926 :           DECL_NONADDRESSABLE_P (field)
     418         5168 :             = !TREE_ADDRESSABLE (decl) && !AGGREGATE_TYPE_P (TREE_TYPE (decl));
     419         3463 :           TREE_THIS_VOLATILE (field) = TREE_THIS_VOLATILE (decl);
     420         3463 :           copy_warning (field, decl);
     421              : 
     422              :           /* Declare the transformation and adjust the original DECL.  For a
     423              :              variable or for a parameter when not optimizing, we make it point
     424              :              to the field in the frame directly.  For a parameter, we don't do
     425              :              it when optimizing because the variable tracking pass will already
     426              :              do the job,  */
     427         3463 :           if (VAR_P (decl) || !optimize)
     428              :             {
     429         3266 :               tree x
     430         3266 :                 = build3 (COMPONENT_REF, TREE_TYPE (field), info->frame_decl,
     431              :                           field, NULL_TREE);
     432              : 
     433              :               /* If the next declaration is a PARM_DECL pointing to the DECL,
     434              :                  we need to adjust its VALUE_EXPR directly, since chains of
     435              :                  VALUE_EXPRs run afoul of garbage collection.  This occurs
     436              :                  in Ada for Out parameters that aren't copied in.  */
     437         3266 :               tree next = DECL_CHAIN (decl);
     438         3266 :               if (next
     439         2758 :                   && TREE_CODE (next) == PARM_DECL
     440            9 :                   && DECL_HAS_VALUE_EXPR_P (next)
     441         3270 :                   && DECL_VALUE_EXPR (next) == decl)
     442            0 :                 SET_DECL_VALUE_EXPR (next, x);
     443              : 
     444         3266 :               SET_DECL_VALUE_EXPR (decl, x);
     445         3266 :               DECL_HAS_VALUE_EXPR_P (decl) = 1;
     446              :             }
     447              :         }
     448              : 
     449         3490 :       insert_field_into_struct (type, field);
     450         3490 :       *slot = field;
     451              : 
     452         3490 :       if (TREE_CODE (decl) == PARM_DECL)
     453          271 :         info->any_parm_remapped = true;
     454              :     }
     455              : 
     456        22294 :   return *slot;
     457              : }
     458              : 
     459              : /* Build or return the variable that holds the static chain within
     460              :    INFO->CONTEXT.  This variable may only be used within INFO->CONTEXT.  */
     461              : 
     462              : static tree
     463        29529 : get_chain_decl (struct nesting_info *info)
     464              : {
     465        29529 :   tree decl = info->chain_decl;
     466              : 
     467        29529 :   if (!decl)
     468              :     {
     469         7090 :       tree type;
     470              : 
     471         7090 :       type = get_frame_type (info->outer);
     472         7090 :       type = build_pointer_type (type);
     473              : 
     474              :       /* Note that this variable is *not* entered into any BIND_EXPR;
     475              :          the construction of this variable is handled specially in
     476              :          expand_function_start and initialize_inlined_parameters.
     477              :          Note also that it's represented as a parameter.  This is more
     478              :          close to the truth, since the initial value does come from
     479              :          the caller.  */
     480         7090 :       decl = build_decl (DECL_SOURCE_LOCATION (info->context),
     481              :                          PARM_DECL, create_tmp_var_name ("CHAIN"), type);
     482         7090 :       DECL_ARTIFICIAL (decl) = 1;
     483         7090 :       DECL_IGNORED_P (decl) = 1;
     484         7090 :       TREE_USED (decl) = 1;
     485         7090 :       DECL_CONTEXT (decl) = info->context;
     486         7090 :       DECL_ARG_TYPE (decl) = type;
     487              : 
     488              :       /* Tell tree-inline.cc that we never write to this variable, so
     489              :          it can copy-prop the replacement value immediately.  */
     490         7090 :       TREE_READONLY (decl) = 1;
     491              : 
     492         7090 :       info->chain_decl = decl;
     493              : 
     494         7090 :       if (dump_file
     495            0 :           && (dump_flags & TDF_DETAILS)
     496         7090 :           && !DECL_STATIC_CHAIN (info->context))
     497            0 :         fprintf (dump_file, "Setting static-chain for %s\n",
     498            0 :                  lang_hooks.decl_printable_name (info->context, 2));
     499              : 
     500         7090 :       DECL_STATIC_CHAIN (info->context) = 1;
     501              :     }
     502        29529 :   return decl;
     503              : }
     504              : 
     505              : /* Build or return the field within the non-local frame state that holds
     506              :    the static chain for INFO->CONTEXT.  This is the way to walk back up
     507              :    multiple nesting levels.  */
     508              : 
     509              : static tree
     510          148 : get_chain_field (struct nesting_info *info)
     511              : {
     512          148 :   tree field = info->chain_field;
     513              : 
     514          148 :   if (!field)
     515              :     {
     516           79 :       tree type = build_pointer_type (get_frame_type (info->outer));
     517              : 
     518           79 :       field = make_node (FIELD_DECL);
     519           79 :       DECL_NAME (field) = get_identifier ("__chain");
     520           79 :       TREE_TYPE (field) = type;
     521           79 :       SET_DECL_ALIGN (field, TYPE_ALIGN (type));
     522           79 :       DECL_NONADDRESSABLE_P (field) = 1;
     523              : 
     524           79 :       insert_field_into_struct (get_frame_type (info), field);
     525              : 
     526           79 :       info->chain_field = field;
     527              : 
     528           79 :       if (dump_file
     529            0 :           && (dump_flags & TDF_DETAILS)
     530           79 :           && !DECL_STATIC_CHAIN (info->context))
     531            0 :         fprintf (dump_file, "Setting static-chain for %s\n",
     532            0 :                  lang_hooks.decl_printable_name (info->context, 2));
     533              : 
     534           79 :       DECL_STATIC_CHAIN (info->context) = 1;
     535              :     }
     536          148 :   return field;
     537              : }
     538              : 
     539              : /* Initialize a new temporary with the GIMPLE_CALL STMT.  */
     540              : 
     541              : static tree
     542         1428 : init_tmp_var_with_call (struct nesting_info *info, gimple_stmt_iterator *gsi,
     543              :                         gcall *call)
     544              : {
     545         1428 :   tree t;
     546              : 
     547         1428 :   t = create_tmp_var_for (info, gimple_call_return_type (call), NULL);
     548         1428 :   gimple_call_set_lhs (call, t);
     549         1428 :   if (! gsi_end_p (*gsi))
     550          337 :     gimple_set_location (call, gimple_location (gsi_stmt (*gsi)));
     551         1428 :   gsi_insert_before (gsi, call, GSI_SAME_STMT);
     552              : 
     553         1428 :   return t;
     554              : }
     555              : 
     556              : 
     557              : /* Copy EXP into a temporary.  Allocate the temporary in the context of
     558              :    INFO and insert the initialization statement before GSI.  */
     559              : 
     560              : static tree
     561        14327 : init_tmp_var (struct nesting_info *info, tree exp, gimple_stmt_iterator *gsi)
     562              : {
     563        14327 :   tree t;
     564        14327 :   gimple *stmt;
     565              : 
     566        14327 :   t = create_tmp_var_for (info, TREE_TYPE (exp), NULL);
     567        14327 :   stmt = gimple_build_assign (t, exp);
     568        14327 :   if (! gsi_end_p (*gsi))
     569        14309 :     gimple_set_location (stmt, gimple_location (gsi_stmt (*gsi)));
     570        14327 :   gsi_insert_before_without_update (gsi, stmt, GSI_SAME_STMT);
     571              : 
     572        14327 :   return t;
     573              : }
     574              : 
     575              : 
     576              : /* Similarly, but only do so to force EXP to satisfy is_gimple_val.  */
     577              : 
     578              : static tree
     579         4179 : gsi_gimplify_val (struct nesting_info *info, tree exp,
     580              :                   gimple_stmt_iterator *gsi)
     581              : {
     582         4179 :   if (is_gimple_val (exp))
     583              :     return exp;
     584              :   else
     585          561 :     return init_tmp_var (info, exp, gsi);
     586              : }
     587              : 
     588              : /* Similarly, but copy from the temporary and insert the statement
     589              :    after the iterator.  */
     590              : 
     591              : static tree
     592         5068 : save_tmp_var (struct nesting_info *info, tree exp, gimple_stmt_iterator *gsi)
     593              : {
     594         5068 :   tree t;
     595         5068 :   gimple *stmt;
     596              : 
     597         5068 :   t = create_tmp_var_for (info, TREE_TYPE (exp), NULL);
     598         5068 :   stmt = gimple_build_assign (exp, t);
     599         5068 :   if (! gsi_end_p (*gsi))
     600         5068 :     gimple_set_location (stmt, gimple_location (gsi_stmt (*gsi)));
     601         5068 :   gsi_insert_after_without_update (gsi, stmt, GSI_SAME_STMT);
     602              : 
     603         5068 :   return t;
     604              : }
     605              : 
     606              : /* Build or return the type used to represent a nested function trampoline.  */
     607              : 
     608              : static GTY(()) tree trampoline_type;
     609              : 
     610              : static tree
     611          290 : get_trampoline_type (struct nesting_info *info)
     612              : {
     613          290 :   unsigned align, size;
     614          290 :   tree t;
     615              : 
     616          290 :   if (trampoline_type)
     617              :     return trampoline_type;
     618              : 
     619              :   /* When trampolines are created off-stack then the only thing we need in the
     620              :      local frame is a single pointer.  */
     621          231 :   if (flag_trampoline_impl == TRAMPOLINE_IMPL_HEAP)
     622              :     {
     623            1 :       trampoline_type = build_pointer_type (void_type_node);
     624            1 :       return trampoline_type;
     625              :     }
     626              : 
     627          230 :   align = TRAMPOLINE_ALIGNMENT;
     628          230 :   size = TRAMPOLINE_SIZE;
     629              : 
     630              :   /* If we won't be able to guarantee alignment simply via TYPE_ALIGN,
     631              :      then allocate extra space so that we can do dynamic alignment.  */
     632          230 :   if (align > STACK_BOUNDARY)
     633              :     {
     634            0 :       size += ((align/BITS_PER_UNIT) - 1) & -(STACK_BOUNDARY/BITS_PER_UNIT);
     635            0 :       align = STACK_BOUNDARY;
     636              :     }
     637              : 
     638          230 :   t = build_index_type (size_int (size - 1));
     639          230 :   t = build_array_type (char_type_node, t);
     640          230 :   t = build_decl (DECL_SOURCE_LOCATION (info->context),
     641              :                   FIELD_DECL, get_identifier ("__data"), t);
     642          230 :   SET_DECL_ALIGN (t, align);
     643          230 :   DECL_USER_ALIGN (t) = 1;
     644              : 
     645          230 :   trampoline_type = make_node (RECORD_TYPE);
     646          230 :   TYPE_NAME (trampoline_type) = get_identifier ("__builtin_trampoline");
     647          230 :   TYPE_FIELDS (trampoline_type) = t;
     648          230 :   layout_type (trampoline_type);
     649          230 :   DECL_CONTEXT (t) = trampoline_type;
     650              : 
     651          230 :   return trampoline_type;
     652              : }
     653              : 
     654              : /* Build or return the type used to represent a nested function descriptor.  */
     655              : 
     656              : static GTY(()) tree descriptor_type;
     657              : 
     658              : static tree
     659            0 : get_descriptor_type (struct nesting_info *info)
     660              : {
     661              :   /* The base alignment is that of a function.  */
     662            0 :   const unsigned align = FUNCTION_ALIGNMENT (FUNCTION_BOUNDARY);
     663            0 :   tree t;
     664              : 
     665            0 :   if (descriptor_type)
     666              :     return descriptor_type;
     667              : 
     668            0 :   t = build_index_type (integer_one_node);
     669            0 :   t = build_array_type (ptr_type_node, t);
     670            0 :   t = build_decl (DECL_SOURCE_LOCATION (info->context),
     671              :                   FIELD_DECL, get_identifier ("__data"), t);
     672            0 :   SET_DECL_ALIGN (t, MAX (TYPE_ALIGN (ptr_type_node), align));
     673            0 :   DECL_USER_ALIGN (t) = 1;
     674              : 
     675            0 :   descriptor_type = make_node (RECORD_TYPE);
     676            0 :   TYPE_NAME (descriptor_type) = get_identifier ("__builtin_descriptor");
     677            0 :   TYPE_FIELDS (descriptor_type) = t;
     678            0 :   layout_type (descriptor_type);
     679            0 :   DECL_CONTEXT (t) = descriptor_type;
     680              : 
     681            0 :   return descriptor_type;
     682              : }
     683              : 
     684              : /* Given DECL, a nested function, find or create an element in the
     685              :    var map for this function.  */
     686              : 
     687              : static tree
     688          714 : lookup_element_for_decl (struct nesting_info *info, tree decl,
     689              :                          enum insert_option insert)
     690              : {
     691          714 :   if (insert == NO_INSERT)
     692              :     {
     693          374 :       tree *slot = info->var_map->get (decl);
     694          374 :       return slot ? *slot : NULL_TREE;
     695              :     }
     696              : 
     697          340 :   tree *slot = &info->var_map->get_or_insert (decl);
     698          340 :   if (!*slot)
     699          290 :     *slot = build_tree_list (NULL_TREE, NULL_TREE);
     700              : 
     701          340 :   return (tree) *slot;
     702              : }
     703              : 
     704              : /* Given DECL, a nested function, create a field in the non-local
     705              :    frame structure for this function.  */
     706              : 
     707              : static tree
     708          290 : create_field_for_decl (struct nesting_info *info, tree decl, tree type)
     709              : {
     710          290 :   tree field = make_node (FIELD_DECL);
     711          290 :   DECL_NAME (field) = DECL_NAME (decl);
     712          290 :   TREE_TYPE (field) = type;
     713          290 :   TREE_ADDRESSABLE (field) = 1;
     714          290 :   insert_field_into_struct (get_frame_type (info), field);
     715          290 :   return field;
     716              : }
     717              : 
     718              : /* Given DECL, a nested function, find or create a field in the non-local
     719              :    frame structure for a trampoline for this function.  */
     720              : 
     721              : static tree
     722          714 : lookup_tramp_for_decl (struct nesting_info *info, tree decl,
     723              :                        enum insert_option insert)
     724              : {
     725          714 :   tree elt, field;
     726              : 
     727          714 :   elt = lookup_element_for_decl (info, decl, insert);
     728          714 :   if (!elt)
     729              :     return NULL_TREE;
     730              : 
     731          630 :   field = TREE_PURPOSE (elt);
     732              : 
     733          630 :   if (!field && insert == INSERT)
     734              :     {
     735          290 :       field = create_field_for_decl (info, decl, get_trampoline_type (info));
     736          290 :       TREE_PURPOSE (elt) = field;
     737          290 :       info->any_tramp_created = true;
     738              :     }
     739              : 
     740              :   return field;
     741              : }
     742              : 
     743              : /* Given DECL, a nested function, find or create a field in the non-local
     744              :    frame structure for a descriptor for this function.  */
     745              : 
     746              : static tree
     747            0 : lookup_descr_for_decl (struct nesting_info *info, tree decl,
     748              :                        enum insert_option insert)
     749              : {
     750            0 :   tree elt, field;
     751              : 
     752            0 :   elt = lookup_element_for_decl (info, decl, insert);
     753            0 :   if (!elt)
     754              :     return NULL_TREE;
     755              : 
     756            0 :   field = TREE_VALUE (elt);
     757              : 
     758            0 :   if (!field && insert == INSERT)
     759              :     {
     760            0 :       field = create_field_for_decl (info, decl, get_descriptor_type (info));
     761            0 :       TREE_VALUE (elt) = field;
     762            0 :       info->any_descr_created = true;
     763              :     }
     764              : 
     765              :   return field;
     766              : }
     767              : 
     768              : /* Build or return the field within the non-local frame state that holds
     769              :    the non-local goto "jmp_buf".  The buffer itself is maintained by the
     770              :    rtl middle-end as dynamic stack space is allocated.  */
     771              : 
     772              : static tree
     773          522 : get_nl_goto_field (struct nesting_info *info)
     774              : {
     775          522 :   tree field = info->nl_goto_field;
     776          522 :   if (!field)
     777              :     {
     778          375 :       unsigned size;
     779          375 :       tree type;
     780              : 
     781              :       /* For __builtin_nonlocal_goto, we need N words.  The first is the
     782              :          frame pointer, the rest is for the target's stack pointer save
     783              :          area.  The number of words is controlled by STACK_SAVEAREA_MODE;
     784              :          not the best interface, but it'll do for now.  */
     785          375 :       if (Pmode == ptr_mode)
     786          375 :         type = ptr_type_node;
     787              :       else
     788            0 :         type = lang_hooks.types.type_for_mode (Pmode, 1);
     789              : 
     790          375 :       fixed_size_mode mode
     791          375 :         = as_a <fixed_size_mode> (STACK_SAVEAREA_MODE (SAVE_NONLOCAL));
     792          375 :       size = GET_MODE_SIZE (mode);
     793          375 :       size = size / GET_MODE_SIZE (Pmode);
     794          375 :       size = size + 1;
     795              : 
     796          375 :       type = build_array_type
     797          375 :         (type, build_index_type (size_int (size)));
     798              : 
     799          375 :       field = make_node (FIELD_DECL);
     800          375 :       DECL_NAME (field) = get_identifier ("__nl_goto_buf");
     801          375 :       TREE_TYPE (field) = type;
     802          375 :       SET_DECL_ALIGN (field, TYPE_ALIGN (type));
     803          375 :       TREE_ADDRESSABLE (field) = 1;
     804              : 
     805          375 :       insert_field_into_struct (get_frame_type (info), field);
     806              : 
     807          375 :       info->nl_goto_field = field;
     808              :     }
     809              : 
     810          522 :   return field;
     811              : }
     812              : 
     813              : /* Invoke CALLBACK on all statements of GIMPLE sequence *PSEQ.  */
     814              : 
     815              : static void
     816       246238 : walk_body (walk_stmt_fn callback_stmt, walk_tree_fn callback_op,
     817              :            struct nesting_info *info, gimple_seq *pseq)
     818              : {
     819       246238 :   struct walk_stmt_info wi;
     820              : 
     821       246238 :   memset (&wi, 0, sizeof (wi));
     822       246238 :   wi.info = info;
     823       246238 :   wi.val_only = true;
     824       246238 :   walk_gimple_seq_mod (pseq, callback_stmt, callback_op, &wi);
     825       246238 : }
     826              : 
     827              : 
     828              : /* Invoke CALLBACK_STMT/CALLBACK_OP on all statements of INFO->CONTEXT.  */
     829              : 
     830              : static inline void
     831       212722 : walk_function (walk_stmt_fn callback_stmt, walk_tree_fn callback_op,
     832              :                struct nesting_info *info)
     833              : {
     834       212722 :   gimple_seq body = gimple_body (info->context);
     835       212722 :   walk_body (callback_stmt, callback_op, info, &body);
     836       212722 :   gimple_set_body (info->context, body);
     837       212722 : }
     838              : 
     839              : /* Invoke CALLBACK on a GIMPLE_OMP_FOR's init, cond, incr and pre-body.  */
     840              : 
     841              : static void
     842         3208 : walk_gimple_omp_for (gomp_for *for_stmt,
     843              :                      walk_stmt_fn callback_stmt, walk_tree_fn callback_op,
     844              :                      struct nesting_info *info)
     845              : {
     846         3208 :   struct walk_stmt_info wi;
     847         3208 :   gimple_seq seq;
     848         3208 :   tree t;
     849         3208 :   size_t i;
     850              : 
     851         3208 :   walk_body (callback_stmt, callback_op, info, gimple_omp_for_pre_body_ptr (for_stmt));
     852              : 
     853         3208 :   seq = NULL;
     854         3208 :   memset (&wi, 0, sizeof (wi));
     855         3208 :   wi.info = info;
     856         3208 :   wi.gsi = gsi_last (seq);
     857              : 
     858         7334 :   for (i = 0; i < gimple_omp_for_collapse (for_stmt); i++)
     859              :     {
     860         4126 :       wi.val_only = false;
     861         4126 :       walk_tree (gimple_omp_for_index_ptr (for_stmt, i), callback_op,
     862              :                  &wi, NULL);
     863         4126 :       wi.val_only = true;
     864         4126 :       wi.is_lhs = false;
     865         4126 :       walk_tree (gimple_omp_for_initial_ptr (for_stmt, i), callback_op,
     866              :                  &wi, NULL);
     867              : 
     868         4126 :       wi.val_only = true;
     869         4126 :       wi.is_lhs = false;
     870         4126 :       walk_tree (gimple_omp_for_final_ptr (for_stmt, i), callback_op,
     871              :                  &wi, NULL);
     872              : 
     873         4126 :       t = gimple_omp_for_incr (for_stmt, i);
     874         4126 :       gcc_assert (BINARY_CLASS_P (t));
     875         4126 :       wi.val_only = false;
     876         4126 :       walk_tree (&TREE_OPERAND (t, 0), callback_op, &wi, NULL);
     877         4126 :       wi.val_only = true;
     878         4126 :       wi.is_lhs = false;
     879         4126 :       walk_tree (&TREE_OPERAND (t, 1), callback_op, &wi, NULL);
     880              :     }
     881              : 
     882         3208 :   seq = gsi_seq (wi.gsi);
     883         3208 :   if (!gimple_seq_empty_p (seq))
     884              :     {
     885            9 :       gimple_seq pre_body = gimple_omp_for_pre_body (for_stmt);
     886            9 :       annotate_all_with_location (seq, gimple_location (for_stmt));
     887            9 :       gimple_seq_add_seq (&pre_body, seq);
     888            9 :       gimple_omp_for_set_pre_body (for_stmt, pre_body);
     889              :     }
     890         3208 : }
     891              : 
     892              : /* Similarly for ROOT and all functions nested underneath, depth first.  */
     893              : 
     894              : static void
     895        38520 : walk_all_functions (walk_stmt_fn callback_stmt, walk_tree_fn callback_op,
     896              :                     struct nesting_info *root)
     897              : {
     898        38520 :   struct nesting_info *n;
     899       359952 :   FOR_EACH_NEST_INFO (n, root)
     900       141456 :     walk_function (callback_stmt, callback_op, n);
     901        38520 : }
     902              : 
     903              : 
     904              : /* We have to check for a fairly pathological case.  The operands of function
     905              :    nested function are to be interpreted in the context of the enclosing
     906              :    function.  So if any are variably-sized, they will get remapped when the
     907              :    enclosing function is inlined.  But that remapping would also have to be
     908              :    done in the types of the PARM_DECLs of the nested function, meaning the
     909              :    argument types of that function will disagree with the arguments in the
     910              :    calls to that function.  So we'd either have to make a copy of the nested
     911              :    function corresponding to each time the enclosing function was inlined or
     912              :    add a VIEW_CONVERT_EXPR to each such operand for each call to the nested
     913              :    function.  The former is not practical.  The latter would still require
     914              :    detecting this case to know when to add the conversions.  So, for now at
     915              :    least, we don't inline such an enclosing function.  A similar issue
     916              :    applies if the nested function has a variably modified return type, and
     917              :    is not inlined, but the enclosing function is inlined and so the type of
     918              :    the return slot as used in the enclosing function is remapped, so also
     919              :    avoid inlining in that case.
     920              : 
     921              :    We have to do that check recursively, so here return indicating whether
     922              :    FNDECL has such a nested function.  ORIG_FN is the function we were
     923              :    trying to inline to use for checking whether any argument is variably
     924              :    modified by anything in it.
     925              : 
     926              :    It would be better to do this in tree-inline.cc so that we could give
     927              :    the appropriate warning for why a function can't be inlined, but that's
     928              :    too late since the nesting structure has already been flattened and
     929              :    adding a flag just to record this fact seems a waste of a flag.  */
     930              : 
     931              : static bool
     932        60332 : check_for_nested_with_variably_modified (tree fndecl, tree orig_fndecl)
     933              : {
     934        60332 :   struct cgraph_node *cgn = cgraph_node::get (fndecl);
     935        60332 :   tree arg;
     936              : 
     937       170600 :   for (cgn = first_nested_function (cgn); cgn;
     938        24968 :        cgn = next_nested_function (cgn))
     939              :     {
     940        25347 :       if (variably_modified_type_p (TREE_TYPE (TREE_TYPE (cgn->decl)),
     941              :                                     orig_fndecl))
     942              :         return true;
     943        68346 :       for (arg = DECL_ARGUMENTS (cgn->decl); arg; arg = DECL_CHAIN (arg))
     944        43378 :         if (variably_modified_type_p (TREE_TYPE (arg), orig_fndecl))
     945              :           return true;
     946              : 
     947        24968 :       if (check_for_nested_with_variably_modified (cgn->decl,
     948              :                                                    orig_fndecl))
     949              :         return true;
     950              :     }
     951              : 
     952              :   return false;
     953              : }
     954              : 
     955              : /* Construct our local datastructure describing the function nesting
     956              :    tree rooted by CGN.  */
     957              : 
     958              : static struct nesting_info *
     959        35364 : create_nesting_tree (struct cgraph_node *cgn)
     960              : {
     961        35364 :   struct nesting_info *info = XCNEW (struct nesting_info);
     962        35364 :   info->field_map = new hash_map<tree, tree>;
     963        35364 :   info->var_map = new hash_map<tree, tree>;
     964        35364 :   info->mem_refs = new hash_set<tree *>;
     965        35364 :   info->suppress_expansion = BITMAP_ALLOC (&nesting_info_bitmap_obstack);
     966        35364 :   info->context = cgn->decl;
     967        35364 :   info->thunk_p = cgn->thunk;
     968              : 
     969        96462 :   for (cgn = first_nested_function (cgn); cgn;
     970        25734 :        cgn = next_nested_function (cgn))
     971              :     {
     972        25734 :       struct nesting_info *sub = create_nesting_tree (cgn);
     973        25734 :       sub->outer = info;
     974        25734 :       sub->next = info->inner;
     975        25734 :       info->inner = sub;
     976              :     }
     977              : 
     978              :   /* See discussion at check_for_nested_with_variably_modified for a
     979              :      discussion of why this has to be here.  */
     980        35364 :   if (check_for_nested_with_variably_modified (info->context, info->context))
     981              :     {
     982          379 :       DECL_UNINLINABLE (info->context) = true;
     983          379 :       tree attrs = DECL_ATTRIBUTES (info->context);
     984          379 :       if (lookup_attribute ("noclone", attrs) == NULL)
     985          378 :         DECL_ATTRIBUTES (info->context)
     986          756 :           = tree_cons (get_identifier ("noclone"), NULL, attrs);
     987              :     }
     988              : 
     989        35364 :   return info;
     990              : }
     991              : 
     992              : /* Return an expression computing the static chain for TARGET_CONTEXT
     993              :    from INFO->CONTEXT.  Insert any necessary computations before TSI.  */
     994              : 
     995              : static tree
     996        16486 : get_static_chain (struct nesting_info *info, tree target_context,
     997              :                   gimple_stmt_iterator *gsi)
     998              : {
     999        16486 :   struct nesting_info *i;
    1000        16486 :   tree x;
    1001              : 
    1002        16486 :   if (info->context == target_context)
    1003              :     {
    1004        14336 :       x = build_addr (info->frame_decl);
    1005        14336 :       info->static_chain_added |= 1;
    1006              :     }
    1007              :   else
    1008              :     {
    1009         2150 :       x = get_chain_decl (info);
    1010         2150 :       info->static_chain_added |= 2;
    1011              : 
    1012         2190 :       for (i = info->outer; i->context != target_context; i = i->outer)
    1013              :         {
    1014           40 :           tree field = get_chain_field (i);
    1015              : 
    1016           40 :           x = build_simple_mem_ref_notrap (x);
    1017           40 :           x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
    1018           40 :           x = init_tmp_var (info, x, gsi);
    1019              :         }
    1020              :     }
    1021              : 
    1022        16486 :   return x;
    1023              : }
    1024              : 
    1025              : 
    1026              : /* Return an expression referencing FIELD from TARGET_CONTEXT's non-local
    1027              :    frame as seen from INFO->CONTEXT.  Insert any necessary computations
    1028              :    before GSI.  */
    1029              : 
    1030              : static tree
    1031        45183 : get_frame_field (struct nesting_info *info, tree target_context,
    1032              :                  tree field, gimple_stmt_iterator *gsi)
    1033              : {
    1034        45183 :   struct nesting_info *i;
    1035        45183 :   tree x;
    1036              : 
    1037        45183 :   if (info->context == target_context)
    1038              :     {
    1039              :       /* Make sure frame_decl gets created.  */
    1040        22994 :       (void) get_frame_type (info);
    1041        22994 :       x = info->frame_decl;
    1042        22994 :       info->static_chain_added |= 1;
    1043              :     }
    1044              :   else
    1045              :     {
    1046        22189 :       x = get_chain_decl (info);
    1047        22189 :       info->static_chain_added |= 2;
    1048              : 
    1049        22297 :       for (i = info->outer; i->context != target_context; i = i->outer)
    1050              :         {
    1051          108 :           tree field = get_chain_field (i);
    1052              : 
    1053          108 :           x = build_simple_mem_ref_notrap (x);
    1054          108 :           x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
    1055          108 :           x = init_tmp_var (info, x, gsi);
    1056              :         }
    1057              : 
    1058        22189 :       x = build_simple_mem_ref_notrap (x);
    1059              :     }
    1060              : 
    1061        45183 :   x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
    1062        45183 :   TREE_THIS_VOLATILE (x) = TREE_THIS_VOLATILE (field);
    1063        45183 :   return x;
    1064              : }
    1065              : 
    1066              : static void note_nonlocal_vla_type (struct nesting_info *info, tree type);
    1067              : 
    1068              : /* Helper for get_nonlocal_debug_decl and get_local_debug_decl.  */
    1069              : 
    1070              : static tree
    1071          782 : get_debug_decl (tree decl)
    1072              : {
    1073          782 :   tree new_decl
    1074          782 :     = build_decl (DECL_SOURCE_LOCATION (decl),
    1075          782 :                   VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
    1076          782 :   DECL_ARTIFICIAL (new_decl) = DECL_ARTIFICIAL (decl);
    1077          782 :   DECL_IGNORED_P (new_decl) = DECL_IGNORED_P (decl);
    1078          782 :   TREE_THIS_VOLATILE (new_decl) = TREE_THIS_VOLATILE (decl);
    1079          782 :   TREE_SIDE_EFFECTS (new_decl) = TREE_SIDE_EFFECTS (decl);
    1080          782 :   TREE_READONLY (new_decl) = TREE_READONLY (decl);
    1081          782 :   TREE_ADDRESSABLE (new_decl) = TREE_ADDRESSABLE (decl);
    1082          782 :   DECL_SEEN_IN_BIND_EXPR_P (new_decl) = 1;
    1083          782 :   if ((TREE_CODE (decl) == PARM_DECL
    1084              :        || TREE_CODE (decl) == RESULT_DECL
    1085              :        || VAR_P (decl))
    1086          776 :       && DECL_BY_REFERENCE (decl))
    1087            8 :     DECL_BY_REFERENCE (new_decl) = 1;
    1088              :   /* Copy DECL_LANG_SPECIFIC and DECL_LANG_FLAG_* for OpenMP langhook
    1089              :      purposes.  */
    1090          782 :   DECL_LANG_SPECIFIC (new_decl) = DECL_LANG_SPECIFIC (decl);
    1091              : #define COPY_DLF(n) DECL_LANG_FLAG_##n (new_decl) = DECL_LANG_FLAG_##n (decl)
    1092          782 :   COPY_DLF (0); COPY_DLF (1); COPY_DLF (2); COPY_DLF (3);
    1093          782 :   COPY_DLF (4); COPY_DLF (5); COPY_DLF (6); COPY_DLF (7);
    1094          782 :   COPY_DLF (8);
    1095              : #undef COPY_DLF
    1096          782 :   return new_decl;
    1097              : }
    1098              : 
    1099              : /* A subroutine of convert_nonlocal_reference_op.  Create a local variable
    1100              :    in the nested function with DECL_VALUE_EXPR set to reference the true
    1101              :    variable in the parent function.  This is used both for debug info
    1102              :    and in OMP lowering.  */
    1103              : 
    1104              : static tree
    1105         3681 : get_nonlocal_debug_decl (struct nesting_info *info, tree decl)
    1106              : {
    1107         3681 :   tree target_context;
    1108         3681 :   struct nesting_info *i;
    1109         3681 :   tree x, field, new_decl;
    1110              : 
    1111         3681 :   tree *slot = &info->var_map->get_or_insert (decl);
    1112              : 
    1113         3681 :   if (*slot)
    1114              :     return *slot;
    1115              : 
    1116          650 :   target_context = decl_function_context (decl);
    1117              : 
    1118              :   /* A copy of the code in get_frame_field, but without the temporaries.  */
    1119          650 :   if (info->context == target_context)
    1120              :     {
    1121              :       /* Make sure frame_decl gets created.  */
    1122            0 :       (void) get_frame_type (info);
    1123            0 :       x = info->frame_decl;
    1124            0 :       i = info;
    1125            0 :       info->static_chain_added |= 1;
    1126              :     }
    1127              :   else
    1128              :     {
    1129          650 :       x = get_chain_decl (info);
    1130          650 :       info->static_chain_added |= 2;
    1131          650 :       for (i = info->outer; i->context != target_context; i = i->outer)
    1132              :         {
    1133            0 :           field = get_chain_field (i);
    1134            0 :           x = build_simple_mem_ref_notrap (x);
    1135            0 :           x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
    1136              :         }
    1137          650 :       x = build_simple_mem_ref_notrap (x);
    1138              :     }
    1139              : 
    1140          650 :   field = lookup_field_for_decl (i, decl, INSERT);
    1141          650 :   x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
    1142          650 :   if (use_pointer_in_frame (decl))
    1143            6 :     x = build_simple_mem_ref_notrap (x);
    1144              : 
    1145              :   /* ??? We should be remapping types as well, surely.  */
    1146          650 :   new_decl = get_debug_decl (decl);
    1147          650 :   DECL_CONTEXT (new_decl) = info->context;
    1148              : 
    1149          650 :   SET_DECL_VALUE_EXPR (new_decl, x);
    1150          650 :   DECL_HAS_VALUE_EXPR_P (new_decl) = 1;
    1151              : 
    1152          650 :   *slot = new_decl;
    1153          650 :   DECL_CHAIN (new_decl) = info->debug_var_chain;
    1154          650 :   info->debug_var_chain = new_decl;
    1155              : 
    1156          650 :   if (!optimize
    1157          121 :       && info->context != target_context
    1158          771 :       && variably_modified_type_p (TREE_TYPE (decl), NULL))
    1159            1 :     note_nonlocal_vla_type (info, TREE_TYPE (decl));
    1160              : 
    1161              :   return new_decl;
    1162              : }
    1163              : 
    1164              : 
    1165              : /* Callback for walk_gimple_stmt, rewrite all references to VAR
    1166              :    and PARM_DECLs that belong to outer functions.
    1167              : 
    1168              :    The rewrite will involve some number of structure accesses back up
    1169              :    the static chain.  E.g. for a variable FOO up one nesting level it'll
    1170              :    be CHAIN->FOO.  For two levels it'll be CHAIN->__chain->FOO.  Further
    1171              :    indirections apply to decls for which use_pointer_in_frame is true.  */
    1172              : 
    1173              : static tree
    1174     17124578 : convert_nonlocal_reference_op (tree *tp, int *walk_subtrees, void *data)
    1175              : {
    1176     17124578 :   struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
    1177     17124578 :   struct nesting_info *const info = (struct nesting_info *) wi->info;
    1178     17124578 :   tree t = *tp;
    1179              : 
    1180     17124578 :   *walk_subtrees = 0;
    1181     17124578 :   switch (TREE_CODE (t))
    1182              :     {
    1183      4766833 :     case VAR_DECL:
    1184              :       /* Non-automatic variables are never processed.  */
    1185      4766833 :       if (TREE_STATIC (t) || DECL_EXTERNAL (t))
    1186              :         break;
    1187              :       /* FALLTHRU */
    1188              : 
    1189      4754532 :     case PARM_DECL:
    1190      4754532 :       {
    1191      4754532 :         tree x, target_context = decl_function_context (t);
    1192              : 
    1193      4754532 :         if (info->context == target_context)
    1194              :           break;
    1195              : 
    1196        24117 :         wi->changed = true;
    1197              : 
    1198        24117 :         if (bitmap_bit_p (info->suppress_expansion, DECL_UID (t)))
    1199         2473 :           x = get_nonlocal_debug_decl (info, t);
    1200              :         else
    1201              :           {
    1202              :             struct nesting_info *i = info;
    1203        43396 :             while (i && i->context != target_context)
    1204        21752 :               i = i->outer;
    1205              :             /* If none of the outer contexts is the target context, this means
    1206              :                that the VAR or PARM_DECL is referenced in a wrong context.  */
    1207        21644 :             if (!i)
    1208            0 :               internal_error ("%s from %s referenced in %s",
    1209            0 :                               IDENTIFIER_POINTER (DECL_NAME (t)),
    1210            0 :                               IDENTIFIER_POINTER (DECL_NAME (target_context)),
    1211            0 :                               IDENTIFIER_POINTER (DECL_NAME (info->context)));
    1212              : 
    1213        21644 :             x = lookup_field_for_decl (i, t, INSERT);
    1214        21644 :             x = get_frame_field (info, target_context, x, &wi->gsi);
    1215        21644 :             if (use_pointer_in_frame (t))
    1216              :               {
    1217           21 :                 x = init_tmp_var (info, x, &wi->gsi);
    1218           21 :                 x = build_simple_mem_ref_notrap (x);
    1219              :               }
    1220              :           }
    1221              : 
    1222        24117 :         if (wi->val_only)
    1223              :           {
    1224         8889 :             if (wi->is_lhs)
    1225         2046 :               x = save_tmp_var (info, x, &wi->gsi);
    1226              :             else
    1227         6843 :               x = init_tmp_var (info, x, &wi->gsi);
    1228              :           }
    1229              : 
    1230        24117 :         *tp = x;
    1231              :       }
    1232        24117 :       break;
    1233              : 
    1234      1903566 :     case LABEL_DECL:
    1235              :       /* We're taking the address of a label from a parent function, but
    1236              :          this is not itself a non-local goto.  Mark the label such that it
    1237              :          will not be deleted, much as we would with a label address in
    1238              :          static storage.  */
    1239      1903566 :       if (decl_function_context (t) != info->context)
    1240           79 :         FORCED_LABEL (t) = 1;
    1241              :       break;
    1242              : 
    1243       757878 :     case ADDR_EXPR:
    1244       757878 :       {
    1245       757878 :         bool save_val_only = wi->val_only;
    1246              : 
    1247       757878 :         wi->val_only = false;
    1248       757878 :         wi->is_lhs = false;
    1249       757878 :         wi->changed = false;
    1250       757878 :         walk_tree (&TREE_OPERAND (t, 0), convert_nonlocal_reference_op, wi, 0);
    1251       757878 :         wi->val_only = true;
    1252              : 
    1253       757878 :         if (wi->changed)
    1254              :           {
    1255         2920 :             tree save_context;
    1256              : 
    1257              :             /* If we changed anything, we might no longer be directly
    1258              :                referencing a decl.  */
    1259         2920 :             save_context = current_function_decl;
    1260         2920 :             current_function_decl = info->context;
    1261         2920 :             recompute_tree_invariant_for_addr_expr (t);
    1262              : 
    1263              :             /* If the callback converted the address argument in a context
    1264              :                where we only accept variables (and min_invariant, presumably),
    1265              :                then compute the address into a temporary.  */
    1266         2920 :             if (save_val_only)
    1267           12 :               *tp = gsi_gimplify_val ((struct nesting_info *) wi->info,
    1268              :                                       t, &wi->gsi);
    1269         2920 :             current_function_decl = save_context;
    1270              :           }
    1271              :       }
    1272              :       break;
    1273              : 
    1274      1856988 :     case REALPART_EXPR:
    1275      1856988 :     case IMAGPART_EXPR:
    1276      1856988 :     case COMPONENT_REF:
    1277      1856988 :     case ARRAY_REF:
    1278      1856988 :     case ARRAY_RANGE_REF:
    1279      1856988 :     case BIT_FIELD_REF:
    1280              :       /* Go down this entire nest and just look at the final prefix and
    1281              :          anything that describes the references.  Otherwise, we lose track
    1282              :          of whether a NOP_EXPR or VIEW_CONVERT_EXPR needs a simple value.  */
    1283      1856988 :       wi->val_only = true;
    1284      1856988 :       wi->is_lhs = false;
    1285      5433257 :       for (; handled_component_p (t); tp = &TREE_OPERAND (t, 0), t = *tp)
    1286              :         {
    1287      3576269 :           if (TREE_CODE (t) == COMPONENT_REF)
    1288      2681971 :             walk_tree (&TREE_OPERAND (t, 2), convert_nonlocal_reference_op, wi,
    1289              :                        NULL);
    1290       894298 :           else if (TREE_CODE (t) == ARRAY_REF
    1291       894298 :                    || TREE_CODE (t) == ARRAY_RANGE_REF)
    1292              :             {
    1293       893576 :               walk_tree (&TREE_OPERAND (t, 1), convert_nonlocal_reference_op,
    1294              :                          wi, NULL);
    1295       893576 :               walk_tree (&TREE_OPERAND (t, 2), convert_nonlocal_reference_op,
    1296              :                          wi, NULL);
    1297       893576 :               walk_tree (&TREE_OPERAND (t, 3), convert_nonlocal_reference_op,
    1298              :                          wi, NULL);
    1299              :             }
    1300              :         }
    1301      1856988 :       wi->val_only = false;
    1302      1856988 :       walk_tree (tp, convert_nonlocal_reference_op, wi, NULL);
    1303      1856988 :       break;
    1304              : 
    1305          882 :     case VIEW_CONVERT_EXPR:
    1306              :       /* Just request to look at the subtrees, leaving val_only and lhs
    1307              :          untouched.  This might actually be for !val_only + lhs, in which
    1308              :          case we don't want to force a replacement by a temporary.  */
    1309          882 :       *walk_subtrees = 1;
    1310          882 :       break;
    1311              : 
    1312      7664961 :     default:
    1313      7664961 :       if (!IS_TYPE_OR_DECL_P (t))
    1314              :         {
    1315      7248491 :           *walk_subtrees = 1;
    1316      7248491 :           wi->val_only = true;
    1317      7248491 :           wi->is_lhs = false;
    1318              :         }
    1319              :       break;
    1320              :     }
    1321              : 
    1322     17124578 :   return NULL_TREE;
    1323              : }
    1324              : 
    1325              : static tree convert_nonlocal_reference_stmt (gimple_stmt_iterator *, bool *,
    1326              :                                              struct walk_stmt_info *);
    1327              : 
    1328              : /* Helper for convert_nonlocal_references, rewrite all references to VAR
    1329              :    and PARM_DECLs that belong to outer functions.  */
    1330              : 
    1331              : static bool
    1332         5539 : convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
    1333              : {
    1334         5539 :   struct nesting_info *const info = (struct nesting_info *) wi->info;
    1335         5539 :   bool need_chain = false, need_stmts = false;
    1336         5539 :   tree clause, decl, *pdecl;
    1337         5539 :   int dummy;
    1338         5539 :   bitmap new_suppress;
    1339              : 
    1340         5539 :   new_suppress = BITMAP_GGC_ALLOC ();
    1341         5539 :   bitmap_copy (new_suppress, info->suppress_expansion);
    1342              : 
    1343        32567 :   for (clause = *pclauses; clause ; clause = OMP_CLAUSE_CHAIN (clause))
    1344              :     {
    1345        27028 :       pdecl = NULL;
    1346        27028 :       switch (OMP_CLAUSE_CODE (clause))
    1347              :         {
    1348          663 :         case OMP_CLAUSE_REDUCTION:
    1349          663 :         case OMP_CLAUSE_IN_REDUCTION:
    1350          663 :         case OMP_CLAUSE_TASK_REDUCTION:
    1351          663 :           if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause))
    1352           37 :             need_stmts = true;
    1353          663 :           if (TREE_CODE (OMP_CLAUSE_DECL (clause)) == MEM_REF)
    1354              :             {
    1355            6 :               pdecl = &TREE_OPERAND (OMP_CLAUSE_DECL (clause), 0);
    1356            6 :               if (TREE_CODE (*pdecl) == POINTER_PLUS_EXPR)
    1357            0 :                 pdecl = &TREE_OPERAND (*pdecl, 0);
    1358            6 :               if (INDIRECT_REF_P (*pdecl)
    1359            6 :                   || TREE_CODE (*pdecl) == ADDR_EXPR)
    1360            4 :                 pdecl = &TREE_OPERAND (*pdecl, 0);
    1361              :             }
    1362          663 :           goto do_decl_clause;
    1363              : 
    1364         1176 :         case OMP_CLAUSE_LASTPRIVATE:
    1365         1176 :           if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (clause))
    1366          250 :             need_stmts = true;
    1367         1176 :           goto do_decl_clause;
    1368              : 
    1369          391 :         case OMP_CLAUSE_LINEAR:
    1370          391 :           if (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (clause))
    1371           74 :             need_stmts = true;
    1372          391 :           wi->val_only = true;
    1373          391 :           wi->is_lhs = false;
    1374          391 :           convert_nonlocal_reference_op (&OMP_CLAUSE_LINEAR_STEP (clause),
    1375              :                                          &dummy, wi);
    1376          391 :           goto do_decl_clause;
    1377              : 
    1378         6358 :         case OMP_CLAUSE_PRIVATE:
    1379         6358 :         case OMP_CLAUSE_FIRSTPRIVATE:
    1380         6358 :         case OMP_CLAUSE_COPYPRIVATE:
    1381         6358 :         case OMP_CLAUSE_SHARED:
    1382         6358 :         case OMP_CLAUSE_ENTER:
    1383         6358 :         case OMP_CLAUSE_LINK:
    1384         6358 :         case OMP_CLAUSE_USE_DEVICE_PTR:
    1385         6358 :         case OMP_CLAUSE_USE_DEVICE_ADDR:
    1386         6358 :         case OMP_CLAUSE_HAS_DEVICE_ADDR:
    1387         6358 :         case OMP_CLAUSE_IS_DEVICE_PTR:
    1388         6358 :         case OMP_CLAUSE_DETACH:
    1389         6358 :         do_decl_clause:
    1390         2230 :           if (pdecl == NULL)
    1391        18120 :             pdecl = &OMP_CLAUSE_DECL (clause);
    1392        18126 :           decl = *pdecl;
    1393        18126 :           if (VAR_P (decl)
    1394        18126 :               && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
    1395              :             break;
    1396        17608 :           if (decl_function_context (decl) != info->context)
    1397              :             {
    1398         1194 :               if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_SHARED)
    1399          356 :                 OMP_CLAUSE_SHARED_READONLY (clause) = 0;
    1400         1194 :               bitmap_set_bit (new_suppress, DECL_UID (decl));
    1401         1194 :               *pdecl = get_nonlocal_debug_decl (info, decl);
    1402         1194 :               if (OMP_CLAUSE_CODE (clause) != OMP_CLAUSE_PRIVATE)
    1403        27028 :                 need_chain = true;
    1404              :             }
    1405              :           break;
    1406              : 
    1407          177 :         case OMP_CLAUSE_SCHEDULE:
    1408          177 :           if (OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (clause) == NULL)
    1409              :             break;
    1410              :           /* FALLTHRU */
    1411         3176 :         case OMP_CLAUSE_FINAL:
    1412         3176 :         case OMP_CLAUSE_IF:
    1413         3176 :         case OMP_CLAUSE_SELF:
    1414         3176 :         case OMP_CLAUSE_NUM_THREADS:
    1415         3176 :         case OMP_CLAUSE_DEPEND:
    1416         3176 :         case OMP_CLAUSE_DOACROSS:
    1417         3176 :         case OMP_CLAUSE_DEVICE:
    1418         3176 :         case OMP_CLAUSE_DYN_GROUPPRIVATE:
    1419         3176 :         case OMP_CLAUSE_NUM_TEAMS:
    1420         3176 :         case OMP_CLAUSE_THREAD_LIMIT:
    1421         3176 :         case OMP_CLAUSE_SAFELEN:
    1422         3176 :         case OMP_CLAUSE_SIMDLEN:
    1423         3176 :         case OMP_CLAUSE_PRIORITY:
    1424         3176 :         case OMP_CLAUSE_GRAINSIZE:
    1425         3176 :         case OMP_CLAUSE_NUM_TASKS:
    1426         3176 :         case OMP_CLAUSE_HINT:
    1427         3176 :         case OMP_CLAUSE_FILTER:
    1428         3176 :         case OMP_CLAUSE_NUM_GANGS:
    1429         3176 :         case OMP_CLAUSE_NUM_WORKERS:
    1430         3176 :         case OMP_CLAUSE_VECTOR_LENGTH:
    1431         3176 :         case OMP_CLAUSE_GANG:
    1432         3176 :         case OMP_CLAUSE_WORKER:
    1433         3176 :         case OMP_CLAUSE_VECTOR:
    1434         3176 :         case OMP_CLAUSE_ASYNC:
    1435         3176 :         case OMP_CLAUSE_WAIT:
    1436              :           /* Several OpenACC clauses have optional arguments.  Check if they
    1437              :              are present.  */
    1438         3176 :           if (OMP_CLAUSE_OPERAND (clause, 0))
    1439              :             {
    1440         2919 :               wi->val_only = true;
    1441         2919 :               wi->is_lhs = false;
    1442         2919 :               convert_nonlocal_reference_op (&OMP_CLAUSE_OPERAND (clause, 0),
    1443              :                                              &dummy, wi);
    1444              :             }
    1445              : 
    1446              :           /* The gang clause accepts two arguments.  */
    1447         3176 :           if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_GANG
    1448         3176 :               && OMP_CLAUSE_GANG_STATIC_EXPR (clause))
    1449              :             {
    1450           28 :                 wi->val_only = true;
    1451           28 :                 wi->is_lhs = false;
    1452           28 :                 convert_nonlocal_reference_op
    1453           28 :                   (&OMP_CLAUSE_GANG_STATIC_EXPR (clause), &dummy, wi);
    1454              :             }
    1455              :           break;
    1456              : 
    1457            7 :         case OMP_CLAUSE_DIST_SCHEDULE:
    1458            7 :           if (OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (clause) != NULL)
    1459              :             {
    1460            7 :               wi->val_only = true;
    1461            7 :               wi->is_lhs = false;
    1462            7 :               convert_nonlocal_reference_op (&OMP_CLAUSE_OPERAND (clause, 0),
    1463              :                                              &dummy, wi);
    1464              :             }
    1465              :           break;
    1466              : 
    1467         8516 :         case OMP_CLAUSE_MAP:
    1468         8516 :         case OMP_CLAUSE_TO:
    1469         8516 :         case OMP_CLAUSE_FROM:
    1470         8516 :           if (OMP_CLAUSE_SIZE (clause))
    1471              :             {
    1472         8516 :               wi->val_only = true;
    1473         8516 :               wi->is_lhs = false;
    1474         8516 :               convert_nonlocal_reference_op (&OMP_CLAUSE_SIZE (clause),
    1475              :                                              &dummy, wi);
    1476              :             }
    1477         8516 :           if (DECL_P (OMP_CLAUSE_DECL (clause)))
    1478         4128 :             goto do_decl_clause;
    1479         4388 :           wi->val_only = true;
    1480         4388 :           wi->is_lhs = false;
    1481         4388 :           walk_tree (&OMP_CLAUSE_DECL (clause), convert_nonlocal_reference_op,
    1482              :                      wi, NULL);
    1483         4388 :           break;
    1484              : 
    1485            6 :         case OMP_CLAUSE_ALIGNED:
    1486            6 :           if (OMP_CLAUSE_ALIGNED_ALIGNMENT (clause))
    1487              :             {
    1488            6 :               wi->val_only = true;
    1489            6 :               wi->is_lhs = false;
    1490            6 :               convert_nonlocal_reference_op
    1491            6 :                 (&OMP_CLAUSE_ALIGNED_ALIGNMENT (clause), &dummy, wi);
    1492              :             }
    1493              :           /* FALLTHRU */
    1494           42 :         case OMP_CLAUSE_NONTEMPORAL:
    1495            0 :         do_decl_clause_no_supp:
    1496              :           /* Like do_decl_clause, but don't add any suppression.  */
    1497           42 :           decl = OMP_CLAUSE_DECL (clause);
    1498           42 :           if (VAR_P (decl)
    1499           42 :               && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
    1500              :             break;
    1501           30 :           if (decl_function_context (decl) != info->context)
    1502              :             {
    1503            6 :               OMP_CLAUSE_DECL (clause) = get_nonlocal_debug_decl (info, decl);
    1504            6 :               need_chain = true;
    1505              :             }
    1506              :           break;
    1507              : 
    1508           36 :         case OMP_CLAUSE_ALLOCATE:
    1509           36 :           if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (clause))
    1510              :             {
    1511           36 :               wi->val_only = true;
    1512           36 :               wi->is_lhs = false;
    1513           36 :               convert_nonlocal_reference_op
    1514           36 :                 (&OMP_CLAUSE_ALLOCATE_ALLOCATOR (clause), &dummy, wi);
    1515              :             }
    1516           36 :           goto do_decl_clause_no_supp;
    1517              : 
    1518              :         case OMP_CLAUSE_NOWAIT:
    1519              :         case OMP_CLAUSE_ORDERED:
    1520              :         case OMP_CLAUSE_DEFAULT:
    1521              :         case OMP_CLAUSE_COPYIN:
    1522              :         case OMP_CLAUSE_COLLAPSE:
    1523              :         case OMP_CLAUSE_TILE:
    1524              :         case OMP_CLAUSE_UNTIED:
    1525              :         case OMP_CLAUSE_MERGEABLE:
    1526              :         case OMP_CLAUSE_PROC_BIND:
    1527              :         case OMP_CLAUSE_NOGROUP:
    1528              :         case OMP_CLAUSE_THREADS:
    1529              :         case OMP_CLAUSE_SIMD:
    1530              :         case OMP_CLAUSE_DEFAULTMAP:
    1531              :         case OMP_CLAUSE_ORDER:
    1532              :         case OMP_CLAUSE_SEQ:
    1533              :         case OMP_CLAUSE_INDEPENDENT:
    1534              :         case OMP_CLAUSE_AUTO:
    1535              :         case OMP_CLAUSE_IF_PRESENT:
    1536              :         case OMP_CLAUSE_FINALIZE:
    1537              :         case OMP_CLAUSE_BIND:
    1538              :         case OMP_CLAUSE__CONDTEMP_:
    1539              :         case OMP_CLAUSE__SCANTEMP_:
    1540              :           break;
    1541              : 
    1542              :           /* The following clause belongs to the OpenACC cache directive, which
    1543              :              is discarded during gimplification.  */
    1544            0 :         case OMP_CLAUSE__CACHE_:
    1545              :           /* The following clauses are only allowed in the OpenMP declare simd
    1546              :              directive, so not seen here.  */
    1547            0 :         case OMP_CLAUSE_UNIFORM:
    1548            0 :         case OMP_CLAUSE_INBRANCH:
    1549            0 :         case OMP_CLAUSE_NOTINBRANCH:
    1550              :           /* The following clauses are only allowed on OpenMP cancel and
    1551              :              cancellation point directives, which at this point have already
    1552              :              been lowered into a function call.  */
    1553            0 :         case OMP_CLAUSE_FOR:
    1554            0 :         case OMP_CLAUSE_PARALLEL:
    1555            0 :         case OMP_CLAUSE_SECTIONS:
    1556            0 :         case OMP_CLAUSE_TASKGROUP:
    1557              :           /* The following clauses are only added during OMP lowering; nested
    1558              :              function decomposition happens before that.  */
    1559            0 :         case OMP_CLAUSE__LOOPTEMP_:
    1560            0 :         case OMP_CLAUSE__REDUCTEMP_:
    1561            0 :         case OMP_CLAUSE__SIMDUID_:
    1562            0 :         case OMP_CLAUSE__SIMT_:
    1563              :           /* The following clauses are only allowed on OpenACC 'routine'
    1564              :              directives, not seen here.  */
    1565            0 :         case OMP_CLAUSE_NOHOST:
    1566              :           /* Anything else.  */
    1567            0 :         default:
    1568            0 :           gcc_unreachable ();
    1569              :         }
    1570              :     }
    1571              : 
    1572         5539 :   info->suppress_expansion = new_suppress;
    1573              : 
    1574         5539 :   if (need_stmts)
    1575         1540 :     for (clause = *pclauses; clause ; clause = OMP_CLAUSE_CHAIN (clause))
    1576         1255 :       switch (OMP_CLAUSE_CODE (clause))
    1577              :         {
    1578          103 :         case OMP_CLAUSE_REDUCTION:
    1579          103 :         case OMP_CLAUSE_IN_REDUCTION:
    1580          103 :         case OMP_CLAUSE_TASK_REDUCTION:
    1581          103 :           if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause))
    1582              :             {
    1583           37 :               tree old_context
    1584           37 :                 = DECL_CONTEXT (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause));
    1585           37 :               DECL_CONTEXT (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause))
    1586           37 :                 = info->context;
    1587           37 :               if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (clause))
    1588            0 :                 DECL_CONTEXT (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (clause))
    1589            0 :                   = info->context;
    1590           37 :               tree save_local_var_chain = info->new_local_var_chain;
    1591           37 :               info->new_local_var_chain = NULL;
    1592           37 :               gimple_seq *seq = &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (clause);
    1593           37 :               walk_body (convert_nonlocal_reference_stmt,
    1594              :                          convert_nonlocal_reference_op, info, seq);
    1595           37 :               if (info->new_local_var_chain)
    1596            1 :                 declare_vars (info->new_local_var_chain,
    1597              :                               gimple_seq_first_stmt (*seq), false);
    1598           37 :               info->new_local_var_chain = NULL;
    1599           37 :               seq = &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (clause);
    1600           37 :               walk_body (convert_nonlocal_reference_stmt,
    1601              :                          convert_nonlocal_reference_op, info, seq);
    1602           37 :               if (info->new_local_var_chain)
    1603            1 :                 declare_vars (info->new_local_var_chain,
    1604              :                               gimple_seq_first_stmt (*seq), false);
    1605           37 :               info->new_local_var_chain = save_local_var_chain;
    1606           37 :               DECL_CONTEXT (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause))
    1607           37 :                 = old_context;
    1608           37 :               if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (clause))
    1609            0 :                 DECL_CONTEXT (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (clause))
    1610            0 :                   = old_context;
    1611              :             }
    1612              :           break;
    1613              : 
    1614          625 :         case OMP_CLAUSE_LASTPRIVATE:
    1615          625 :         case OMP_CLAUSE_LINEAR:
    1616          625 :           {
    1617          625 :             tree save_local_var_chain = info->new_local_var_chain;
    1618          625 :             info->new_local_var_chain = NULL;
    1619          625 :             gimple_seq *seq;
    1620          625 :             if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_LASTPRIVATE)
    1621          410 :               seq = &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (clause);
    1622              :             else
    1623          215 :               seq = &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (clause);
    1624          625 :             walk_body (convert_nonlocal_reference_stmt,
    1625              :                        convert_nonlocal_reference_op, info, seq);
    1626          625 :             if (info->new_local_var_chain)
    1627              :               {
    1628            8 :                 gimple *g = gimple_seq_first_stmt (*seq);
    1629            8 :                 if (gimple_code (g) != GIMPLE_BIND)
    1630              :                   {
    1631            2 :                     g = gimple_build_bind (NULL_TREE, *seq, NULL_TREE);
    1632            2 :                     *seq = NULL;
    1633            2 :                     gimple_seq_add_stmt_without_update (seq, g);
    1634              :                   }
    1635            8 :                 declare_vars (info->new_local_var_chain,
    1636              :                               gimple_seq_first_stmt (*seq), false);
    1637              :               }
    1638          625 :             info->new_local_var_chain = save_local_var_chain;
    1639              :           }
    1640          625 :           break;
    1641              : 
    1642              :         default:
    1643              :           break;
    1644              :         }
    1645              : 
    1646         5539 :   return need_chain;
    1647              : }
    1648              : 
    1649              : /* Create nonlocal debug decls for nonlocal VLA array bounds.  */
    1650              : 
    1651              : static void
    1652            2 : note_nonlocal_vla_type (struct nesting_info *info, tree type)
    1653              : {
    1654            3 :   while (POINTER_TYPE_P (type) && !TYPE_NAME (type))
    1655            1 :     type = TREE_TYPE (type);
    1656              : 
    1657            2 :   if (TYPE_NAME (type)
    1658            2 :       && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
    1659            4 :       && DECL_ORIGINAL_TYPE (TYPE_NAME (type)))
    1660            1 :     type = DECL_ORIGINAL_TYPE (TYPE_NAME (type));
    1661              : 
    1662            2 :   while (POINTER_TYPE_P (type)
    1663              :          || VECTOR_TYPE_P (type)
    1664              :          || TREE_CODE (type) == FUNCTION_TYPE
    1665            2 :          || TREE_CODE (type) == METHOD_TYPE)
    1666            0 :     type = TREE_TYPE (type);
    1667              : 
    1668            2 :   if (TREE_CODE (type) == ARRAY_TYPE)
    1669              :     {
    1670            1 :       tree domain, t;
    1671              : 
    1672            1 :       note_nonlocal_vla_type (info, TREE_TYPE (type));
    1673            1 :       domain = TYPE_DOMAIN (type);
    1674            1 :       if (domain)
    1675              :         {
    1676            1 :           t = TYPE_MIN_VALUE (domain);
    1677            1 :           if (t && (VAR_P (t) || TREE_CODE (t) == PARM_DECL)
    1678            1 :               && decl_function_context (t) != info->context)
    1679            0 :             get_nonlocal_debug_decl (info, t);
    1680            1 :           t = TYPE_MAX_VALUE (domain);
    1681            1 :           if (t && (VAR_P (t) || TREE_CODE (t) == PARM_DECL)
    1682            2 :               && decl_function_context (t) != info->context)
    1683            1 :             get_nonlocal_debug_decl (info, t);
    1684              :         }
    1685              :     }
    1686            2 : }
    1687              : 
    1688              : /* Callback for walk_gimple_stmt.  Rewrite all references to VAR and
    1689              :    PARM_DECLs that belong to outer functions.  This handles statements
    1690              :    that are not handled via the standard recursion done in
    1691              :    walk_gimple_stmt.  STMT is the statement to examine, DATA is as in
    1692              :    convert_nonlocal_reference_op.  Set *HANDLED_OPS_P to true if all the
    1693              :    operands of STMT have been handled by this function.  */
    1694              : 
    1695              : static tree
    1696      6347914 : convert_nonlocal_reference_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
    1697              :                                  struct walk_stmt_info *wi)
    1698              : {
    1699      6347914 :   struct nesting_info *info = (struct nesting_info *) wi->info;
    1700      6347914 :   tree save_local_var_chain;
    1701      6347914 :   bitmap save_suppress;
    1702      6347914 :   gimple *stmt = gsi_stmt (*gsi);
    1703              : 
    1704      6347914 :   switch (gimple_code (stmt))
    1705              :     {
    1706       241187 :     case GIMPLE_GOTO:
    1707              :       /* Don't walk non-local gotos for now.  */
    1708       241187 :       if (TREE_CODE (gimple_goto_dest (stmt)) != LABEL_DECL)
    1709              :         {
    1710           75 :           wi->val_only = true;
    1711           75 :           wi->is_lhs = false;
    1712           75 :           *handled_ops_p = false;
    1713           75 :           return NULL_TREE;
    1714              :         }
    1715              :       break;
    1716              : 
    1717           53 :     case GIMPLE_OMP_TEAMS:
    1718           53 :       if (!gimple_omp_teams_host (as_a <gomp_teams *> (stmt)))
    1719              :         {
    1720           41 :           save_suppress = info->suppress_expansion;
    1721           41 :           convert_nonlocal_omp_clauses (gimple_omp_teams_clauses_ptr (stmt),
    1722              :                                         wi);
    1723           41 :           walk_body (convert_nonlocal_reference_stmt,
    1724              :                      convert_nonlocal_reference_op, info,
    1725              :                      gimple_omp_body_ptr (stmt));
    1726           41 :           info->suppress_expansion = save_suppress;
    1727           41 :           break;
    1728              :         }
    1729              :       /* FALLTHRU */
    1730              : 
    1731         1404 :     case GIMPLE_OMP_PARALLEL:
    1732         1404 :     case GIMPLE_OMP_TASK:
    1733         1404 :       save_suppress = info->suppress_expansion;
    1734         1404 :       if (convert_nonlocal_omp_clauses (gimple_omp_taskreg_clauses_ptr (stmt),
    1735              :                                         wi))
    1736              :         {
    1737          164 :           tree c, decl;
    1738          164 :           decl = get_chain_decl (info);
    1739          164 :           c = build_omp_clause (gimple_location (stmt),
    1740              :                                 OMP_CLAUSE_FIRSTPRIVATE);
    1741          164 :           OMP_CLAUSE_DECL (c) = decl;
    1742          164 :           OMP_CLAUSE_CHAIN (c) = gimple_omp_taskreg_clauses (stmt);
    1743          164 :           gimple_omp_taskreg_set_clauses (stmt, c);
    1744              :         }
    1745              : 
    1746         1404 :       save_local_var_chain = info->new_local_var_chain;
    1747         1404 :       info->new_local_var_chain = NULL;
    1748              : 
    1749         1404 :       walk_body (convert_nonlocal_reference_stmt, convert_nonlocal_reference_op,
    1750              :                  info, gimple_omp_body_ptr (stmt));
    1751              : 
    1752         1404 :       if (info->new_local_var_chain)
    1753          122 :         declare_vars (info->new_local_var_chain,
    1754              :                       gimple_seq_first_stmt (gimple_omp_body (stmt)),
    1755              :                       false);
    1756         1404 :       info->new_local_var_chain = save_local_var_chain;
    1757         1404 :       info->suppress_expansion = save_suppress;
    1758         1404 :       break;
    1759              : 
    1760         1604 :     case GIMPLE_OMP_FOR:
    1761         1604 :       save_suppress = info->suppress_expansion;
    1762         1604 :       convert_nonlocal_omp_clauses (gimple_omp_for_clauses_ptr (stmt), wi);
    1763         1604 :       walk_gimple_omp_for (as_a <gomp_for *> (stmt),
    1764              :                            convert_nonlocal_reference_stmt,
    1765              :                            convert_nonlocal_reference_op, info);
    1766         1604 :       walk_body (convert_nonlocal_reference_stmt,
    1767              :                  convert_nonlocal_reference_op, info, gimple_omp_body_ptr (stmt));
    1768         1604 :       info->suppress_expansion = save_suppress;
    1769         1604 :       break;
    1770              : 
    1771           42 :     case GIMPLE_OMP_SECTIONS:
    1772           42 :       save_suppress = info->suppress_expansion;
    1773           42 :       convert_nonlocal_omp_clauses (gimple_omp_sections_clauses_ptr (stmt), wi);
    1774           42 :       walk_body (convert_nonlocal_reference_stmt, convert_nonlocal_reference_op,
    1775              :                  info, gimple_omp_body_ptr (stmt));
    1776           42 :       info->suppress_expansion = save_suppress;
    1777           42 :       break;
    1778              : 
    1779          185 :     case GIMPLE_OMP_SINGLE:
    1780          185 :       save_suppress = info->suppress_expansion;
    1781          185 :       convert_nonlocal_omp_clauses (gimple_omp_single_clauses_ptr (stmt), wi);
    1782          185 :       walk_body (convert_nonlocal_reference_stmt, convert_nonlocal_reference_op,
    1783              :                  info, gimple_omp_body_ptr (stmt));
    1784          185 :       info->suppress_expansion = save_suppress;
    1785          185 :       break;
    1786              : 
    1787            0 :     case GIMPLE_OMP_SCOPE:
    1788            0 :       save_suppress = info->suppress_expansion;
    1789            0 :       convert_nonlocal_omp_clauses (gimple_omp_scope_clauses_ptr (stmt), wi);
    1790            0 :       walk_body (convert_nonlocal_reference_stmt, convert_nonlocal_reference_op,
    1791              :                  info, gimple_omp_body_ptr (stmt));
    1792            0 :       info->suppress_expansion = save_suppress;
    1793            0 :       break;
    1794              : 
    1795           38 :     case GIMPLE_OMP_TASKGROUP:
    1796           38 :       save_suppress = info->suppress_expansion;
    1797           38 :       convert_nonlocal_omp_clauses (gimple_omp_taskgroup_clauses_ptr (stmt), wi);
    1798           38 :       walk_body (convert_nonlocal_reference_stmt, convert_nonlocal_reference_op,
    1799              :                  info, gimple_omp_body_ptr (stmt));
    1800           38 :       info->suppress_expansion = save_suppress;
    1801           38 :       break;
    1802              : 
    1803         2225 :     case GIMPLE_OMP_TARGET:
    1804         2225 :       walk_body (convert_nonlocal_reference_stmt, convert_nonlocal_reference_op,
    1805              :                  info, gimple_omp_target_iterator_loops_ptr (stmt));
    1806         2225 :       if (!is_gimple_omp_offloaded (stmt))
    1807              :         {
    1808          778 :           save_suppress = info->suppress_expansion;
    1809          778 :           convert_nonlocal_omp_clauses (gimple_omp_target_clauses_ptr (stmt),
    1810              :                                         wi);
    1811          778 :           info->suppress_expansion = save_suppress;
    1812          778 :           walk_body (convert_nonlocal_reference_stmt,
    1813              :                      convert_nonlocal_reference_op, info,
    1814              :                      gimple_omp_body_ptr (stmt));
    1815          778 :           break;
    1816              :         }
    1817         1447 :       save_suppress = info->suppress_expansion;
    1818         1447 :       if (convert_nonlocal_omp_clauses (gimple_omp_target_clauses_ptr (stmt),
    1819              :                                         wi))
    1820              :         {
    1821           67 :           tree c, decl;
    1822           67 :           decl = get_chain_decl (info);
    1823           67 :           c = build_omp_clause (gimple_location (stmt), OMP_CLAUSE_MAP);
    1824           67 :           OMP_CLAUSE_DECL (c) = decl;
    1825           67 :           OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TO);
    1826           67 :           OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
    1827           67 :           OMP_CLAUSE_CHAIN (c) = gimple_omp_target_clauses (stmt);
    1828           67 :           gimple_omp_target_set_clauses (as_a <gomp_target *> (stmt), c);
    1829              :         }
    1830              : 
    1831         1447 :       save_local_var_chain = info->new_local_var_chain;
    1832         1447 :       info->new_local_var_chain = NULL;
    1833              : 
    1834         1447 :       walk_body (convert_nonlocal_reference_stmt, convert_nonlocal_reference_op,
    1835              :                  info, gimple_omp_body_ptr (stmt));
    1836              : 
    1837         1447 :       if (info->new_local_var_chain)
    1838          217 :         declare_vars (info->new_local_var_chain,
    1839              :                       gimple_seq_first_stmt (gimple_omp_body (stmt)),
    1840              :                       false);
    1841         1447 :       info->new_local_var_chain = save_local_var_chain;
    1842         1447 :       info->suppress_expansion = save_suppress;
    1843         1447 :       break;
    1844              : 
    1845          606 :     case GIMPLE_OMP_SECTION:
    1846          606 :     case GIMPLE_OMP_STRUCTURED_BLOCK:
    1847          606 :     case GIMPLE_OMP_MASTER:
    1848          606 :     case GIMPLE_OMP_MASKED:
    1849          606 :     case GIMPLE_OMP_ORDERED:
    1850          606 :     case GIMPLE_OMP_SCAN:
    1851          606 :       walk_body (convert_nonlocal_reference_stmt, convert_nonlocal_reference_op,
    1852              :                  info, gimple_omp_body_ptr (stmt));
    1853          606 :       break;
    1854              : 
    1855       295407 :     case GIMPLE_BIND:
    1856       295407 :       {
    1857       295407 :       gbind *bind_stmt = as_a <gbind *> (stmt);
    1858              : 
    1859      1378592 :       for (tree var = gimple_bind_vars (bind_stmt); var; var = DECL_CHAIN (var))
    1860      1083185 :         if (TREE_CODE (var) == NAMELIST_DECL)
    1861              :           {
    1862              :             /* Adjust decls mentioned in NAMELIST_DECL.  */
    1863          151 :             tree decls = NAMELIST_DECL_ASSOCIATED_DECL (var);
    1864          151 :             tree decl;
    1865          151 :             unsigned int i;
    1866              : 
    1867      1083882 :             FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (decls), i, decl)
    1868              :               {
    1869          779 :                 if (VAR_P (decl)
    1870          697 :                     && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
    1871           82 :                   continue;
    1872          615 :                 if (decl_function_context (decl) != info->context)
    1873            7 :                   CONSTRUCTOR_ELT (decls, i)->value
    1874           14 :                     = get_nonlocal_debug_decl (info, decl);
    1875              :               }
    1876              :           }
    1877              : 
    1878       295407 :       *handled_ops_p = false;
    1879       295407 :       return NULL_TREE;
    1880              :       }
    1881       394060 :     case GIMPLE_COND:
    1882       394060 :       wi->val_only = true;
    1883       394060 :       wi->is_lhs = false;
    1884       394060 :       *handled_ops_p = false;
    1885       394060 :       return NULL_TREE;
    1886              : 
    1887      3806137 :     case GIMPLE_ASSIGN:
    1888      3806137 :       if (gimple_clobber_p (stmt))
    1889              :         {
    1890       130019 :           tree lhs = gimple_assign_lhs (stmt);
    1891       130019 :           if (DECL_P (lhs)
    1892       129996 :               && !(TREE_STATIC (lhs) || DECL_EXTERNAL (lhs))
    1893       259946 :               && decl_function_context (lhs) != info->context)
    1894              :             {
    1895           11 :               gsi_replace (gsi, gimple_build_nop (), true);
    1896           11 :               break;
    1897              :             }
    1898              :         }
    1899      3806126 :       *handled_ops_p = false;
    1900      3806126 :       return NULL_TREE;
    1901              : 
    1902      1604978 :     default:
    1903              :       /* For every other statement that we are not interested in
    1904              :          handling here, let the walker traverse the operands.  */
    1905      1604978 :       *handled_ops_p = false;
    1906      1604978 :       return NULL_TREE;
    1907              :     }
    1908              : 
    1909              :   /* We have handled all of STMT operands, no need to traverse the operands.  */
    1910       247268 :   *handled_ops_p = true;
    1911       247268 :   return NULL_TREE;
    1912              : }
    1913              : 
    1914              : 
    1915              : /* A subroutine of convert_local_reference.  Create a local variable
    1916              :    in the parent function with DECL_VALUE_EXPR set to reference the
    1917              :    field in FRAME.  This is used both for debug info and in OMP
    1918              :    lowering.  */
    1919              : 
    1920              : static tree
    1921          840 : get_local_debug_decl (struct nesting_info *info, tree decl, tree field)
    1922              : {
    1923          840 :   tree x, new_decl;
    1924              : 
    1925          840 :   tree *slot = &info->var_map->get_or_insert (decl);
    1926          840 :   if (*slot)
    1927              :     return *slot;
    1928              : 
    1929              :   /* Make sure frame_decl gets created.  */
    1930          132 :   (void) get_frame_type (info);
    1931          132 :   x = info->frame_decl;
    1932          132 :   x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
    1933              : 
    1934          132 :   new_decl = get_debug_decl (decl);
    1935          132 :   DECL_CONTEXT (new_decl) = info->context;
    1936              : 
    1937          132 :   SET_DECL_VALUE_EXPR (new_decl, x);
    1938          132 :   DECL_HAS_VALUE_EXPR_P (new_decl) = 1;
    1939          132 :   *slot = new_decl;
    1940              : 
    1941          132 :   DECL_CHAIN (new_decl) = info->debug_var_chain;
    1942          132 :   info->debug_var_chain = new_decl;
    1943              : 
    1944              :   /* Do not emit debug info twice.  */
    1945          132 :   DECL_IGNORED_P (decl) = 1;
    1946              : 
    1947          132 :   return new_decl;
    1948              : }
    1949              : 
    1950              : 
    1951              : /* Called via walk_function+walk_gimple_stmt, rewrite all references to VAR
    1952              :    and PARM_DECLs that were referenced by inner nested functions.
    1953              :    The rewrite will be a structure reference to the local frame variable.  */
    1954              : 
    1955              : static bool convert_local_omp_clauses (tree *, struct walk_stmt_info *);
    1956              : 
    1957              : static tree
    1958     17048250 : convert_local_reference_op (tree *tp, int *walk_subtrees, void *data)
    1959              : {
    1960     17048250 :   struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
    1961     17048250 :   struct nesting_info *const info = (struct nesting_info *) wi->info;
    1962     17048250 :   tree t = *tp, field, x;
    1963     17048250 :   bool save_val_only;
    1964              : 
    1965     17048250 :   *walk_subtrees = 0;
    1966     17048250 :   switch (TREE_CODE (t))
    1967              :     {
    1968      4765862 :     case VAR_DECL:
    1969              :       /* Non-automatic variables are never processed.  */
    1970      4765862 :       if (TREE_STATIC (t) || DECL_EXTERNAL (t))
    1971              :         break;
    1972              :       /* FALLTHRU */
    1973              : 
    1974      4772861 :     case PARM_DECL:
    1975      4772861 :       if (t != info->frame_decl && decl_function_context (t) == info->context)
    1976              :         {
    1977              :           /* If we copied a pointer to the frame, then the original decl
    1978              :              is used unchanged in the parent function.  */
    1979      4769970 :           if (use_pointer_in_frame (t))
    1980              :             break;
    1981              : 
    1982              :           /* No need to transform anything if no child references the
    1983              :              variable.  */
    1984      4769778 :           field = lookup_field_for_decl (info, t, NO_INSERT);
    1985      4769778 :           if (!field)
    1986              :             break;
    1987        22975 :           wi->changed = true;
    1988              : 
    1989        22975 :           if (bitmap_bit_p (info->suppress_expansion, DECL_UID (t)))
    1990          673 :             x = get_local_debug_decl (info, t, field);
    1991              :           else
    1992        22302 :             x = get_frame_field (info, info->context, field, &wi->gsi);
    1993              : 
    1994        22975 :           if (wi->val_only)
    1995              :             {
    1996         9392 :               if (wi->is_lhs)
    1997         3022 :                 x = save_tmp_var (info, x, &wi->gsi);
    1998              :               else
    1999         6370 :                 x = init_tmp_var (info, x, &wi->gsi);
    2000              :             }
    2001              : 
    2002        22975 :           *tp = x;
    2003              :         }
    2004              :       break;
    2005              : 
    2006       757878 :     case ADDR_EXPR:
    2007       757878 :       save_val_only = wi->val_only;
    2008       757878 :       wi->val_only = false;
    2009       757878 :       wi->is_lhs = false;
    2010       757878 :       wi->changed = false;
    2011       757878 :       walk_tree (&TREE_OPERAND (t, 0), convert_local_reference_op, wi, NULL);
    2012       757878 :       wi->val_only = save_val_only;
    2013              : 
    2014              :       /* If we converted anything ... */
    2015       757878 :       if (wi->changed)
    2016              :         {
    2017         3897 :           tree save_context;
    2018              : 
    2019              :           /* Then the frame decl is now addressable.  */
    2020         3897 :           TREE_ADDRESSABLE (info->frame_decl) = 1;
    2021              : 
    2022         3897 :           save_context = current_function_decl;
    2023         3897 :           current_function_decl = info->context;
    2024         3897 :           recompute_tree_invariant_for_addr_expr (t);
    2025              : 
    2026              :           /* If we are in a context where we only accept values, then
    2027              :              compute the address into a temporary.  */
    2028         3897 :           if (save_val_only)
    2029         3305 :             *tp = gsi_gimplify_val ((struct nesting_info *) wi->info,
    2030              :                                     t, &wi->gsi);
    2031         3897 :           current_function_decl = save_context;
    2032              :         }
    2033              :       break;
    2034              : 
    2035      1869401 :     case REALPART_EXPR:
    2036      1869401 :     case IMAGPART_EXPR:
    2037      1869401 :     case COMPONENT_REF:
    2038      1869401 :     case ARRAY_REF:
    2039      1869401 :     case ARRAY_RANGE_REF:
    2040      1869401 :     case BIT_FIELD_REF:
    2041              :       /* Go down this entire nest and just look at the final prefix and
    2042              :          anything that describes the references.  Otherwise, we lose track
    2043              :          of whether a NOP_EXPR or VIEW_CONVERT_EXPR needs a simple value.  */
    2044      1869401 :       save_val_only = wi->val_only;
    2045      1869401 :       wi->val_only = true;
    2046      1869401 :       wi->is_lhs = false;
    2047      5468494 :       for (; handled_component_p (t); tp = &TREE_OPERAND (t, 0), t = *tp)
    2048              :         {
    2049      3599093 :           if (TREE_CODE (t) == COMPONENT_REF)
    2050      2704795 :             walk_tree (&TREE_OPERAND (t, 2), convert_local_reference_op, wi,
    2051              :                        NULL);
    2052       894298 :           else if (TREE_CODE (t) == ARRAY_REF
    2053       894298 :                    || TREE_CODE (t) == ARRAY_RANGE_REF)
    2054              :             {
    2055       893576 :               walk_tree (&TREE_OPERAND (t, 1), convert_local_reference_op, wi,
    2056              :                          NULL);
    2057       893576 :               walk_tree (&TREE_OPERAND (t, 2), convert_local_reference_op, wi,
    2058              :                          NULL);
    2059       893576 :               walk_tree (&TREE_OPERAND (t, 3), convert_local_reference_op, wi,
    2060              :                          NULL);
    2061              :             }
    2062              :         }
    2063      1869401 :       wi->val_only = false;
    2064      1869401 :       walk_tree (tp, convert_local_reference_op, wi, NULL);
    2065      1869401 :       wi->val_only = save_val_only;
    2066      1869401 :       break;
    2067              : 
    2068       386434 :     case MEM_REF:
    2069       386434 :       save_val_only = wi->val_only;
    2070       386434 :       wi->val_only = true;
    2071       386434 :       wi->is_lhs = false;
    2072       386434 :       walk_tree (&TREE_OPERAND (t, 0), convert_local_reference_op,
    2073              :                  wi, NULL);
    2074              :       /* We need to re-fold the MEM_REF as component references as
    2075              :          part of a ADDR_EXPR address are not allowed.  But we cannot
    2076              :          fold here, as the chain record type is not yet finalized.  */
    2077       386434 :       if (TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR
    2078       386434 :           && !DECL_P (TREE_OPERAND (TREE_OPERAND (t, 0), 0)))
    2079            0 :         info->mem_refs->add (tp);
    2080       386434 :       wi->val_only = save_val_only;
    2081       386434 :       break;
    2082              : 
    2083          882 :     case VIEW_CONVERT_EXPR:
    2084              :       /* Just request to look at the subtrees, leaving val_only and lhs
    2085              :          untouched.  This might actually be for !val_only + lhs, in which
    2086              :          case we don't want to force a replacement by a temporary.  */
    2087          882 :       *walk_subtrees = 1;
    2088          882 :       break;
    2089              : 
    2090      9075023 :     default:
    2091      9075023 :       if (!IS_TYPE_OR_DECL_P (t))
    2092              :         {
    2093      6513875 :           *walk_subtrees = 1;
    2094      6513875 :           wi->val_only = true;
    2095      6513875 :           wi->is_lhs = false;
    2096              :         }
    2097              :       break;
    2098              :     }
    2099              : 
    2100     17048250 :   return NULL_TREE;
    2101              : }
    2102              : 
    2103              : static tree convert_local_reference_stmt (gimple_stmt_iterator *, bool *,
    2104              :                                           struct walk_stmt_info *);
    2105              : 
    2106              : /* Helper for convert_local_reference.  Convert all the references in
    2107              :    the chain of clauses at *PCLAUSES.  WI is as in convert_local_reference.  */
    2108              : 
    2109              : static bool
    2110         5539 : convert_local_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
    2111              : {
    2112         5539 :   struct nesting_info *const info = (struct nesting_info *) wi->info;
    2113         5539 :   bool need_frame = false, need_stmts = false;
    2114         5539 :   tree clause, decl, *pdecl;
    2115         5539 :   int dummy;
    2116         5539 :   bitmap new_suppress;
    2117              : 
    2118         5539 :   new_suppress = BITMAP_GGC_ALLOC ();
    2119         5539 :   bitmap_copy (new_suppress, info->suppress_expansion);
    2120              : 
    2121        32798 :   for (clause = *pclauses; clause ; clause = OMP_CLAUSE_CHAIN (clause))
    2122              :     {
    2123        27259 :       pdecl = NULL;
    2124        27259 :       switch (OMP_CLAUSE_CODE (clause))
    2125              :         {
    2126          663 :         case OMP_CLAUSE_REDUCTION:
    2127          663 :         case OMP_CLAUSE_IN_REDUCTION:
    2128          663 :         case OMP_CLAUSE_TASK_REDUCTION:
    2129          663 :           if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause))
    2130           37 :             need_stmts = true;
    2131          663 :           if (TREE_CODE (OMP_CLAUSE_DECL (clause)) == MEM_REF)
    2132              :             {
    2133            6 :               pdecl = &TREE_OPERAND (OMP_CLAUSE_DECL (clause), 0);
    2134            6 :               if (TREE_CODE (*pdecl) == POINTER_PLUS_EXPR)
    2135            0 :                 pdecl = &TREE_OPERAND (*pdecl, 0);
    2136            6 :               if (INDIRECT_REF_P (*pdecl)
    2137            6 :                   || TREE_CODE (*pdecl) == ADDR_EXPR)
    2138            4 :                 pdecl = &TREE_OPERAND (*pdecl, 0);
    2139              :             }
    2140          663 :           goto do_decl_clause;
    2141              : 
    2142         1176 :         case OMP_CLAUSE_LASTPRIVATE:
    2143         1176 :           if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (clause))
    2144          250 :             need_stmts = true;
    2145         1176 :           goto do_decl_clause;
    2146              : 
    2147          391 :         case OMP_CLAUSE_LINEAR:
    2148          391 :           if (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (clause))
    2149           74 :             need_stmts = true;
    2150          391 :           wi->val_only = true;
    2151          391 :           wi->is_lhs = false;
    2152          391 :           convert_local_reference_op (&OMP_CLAUSE_LINEAR_STEP (clause), &dummy,
    2153              :                                       wi);
    2154          391 :           goto do_decl_clause;
    2155              : 
    2156         6425 :         case OMP_CLAUSE_PRIVATE:
    2157         6425 :         case OMP_CLAUSE_FIRSTPRIVATE:
    2158         6425 :         case OMP_CLAUSE_COPYPRIVATE:
    2159         6425 :         case OMP_CLAUSE_SHARED:
    2160         6425 :         case OMP_CLAUSE_ENTER:
    2161         6425 :         case OMP_CLAUSE_LINK:
    2162         6425 :         case OMP_CLAUSE_USE_DEVICE_PTR:
    2163         6425 :         case OMP_CLAUSE_USE_DEVICE_ADDR:
    2164         6425 :         case OMP_CLAUSE_HAS_DEVICE_ADDR:
    2165         6425 :         case OMP_CLAUSE_IS_DEVICE_PTR:
    2166         6425 :         case OMP_CLAUSE_DETACH:
    2167         6425 :         do_decl_clause:
    2168         2230 :           if (pdecl == NULL)
    2169        18351 :             pdecl = &OMP_CLAUSE_DECL (clause);
    2170        18357 :           decl = *pdecl;
    2171        18357 :           if (VAR_P (decl)
    2172        18357 :               && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
    2173              :             break;
    2174        17839 :           if (decl_function_context (decl) == info->context
    2175        17839 :               && !use_pointer_in_frame (decl))
    2176              :             {
    2177        17713 :               tree field = lookup_field_for_decl (info, decl, NO_INSERT);
    2178        17713 :               if (field)
    2179              :                 {
    2180          165 :                   if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_SHARED)
    2181           37 :                     OMP_CLAUSE_SHARED_READONLY (clause) = 0;
    2182          165 :                   bitmap_set_bit (new_suppress, DECL_UID (decl));
    2183          165 :                   *pdecl = get_local_debug_decl (info, decl, field);
    2184          165 :                   need_frame = true;
    2185              :                 }
    2186              :             }
    2187              :           break;
    2188              : 
    2189          177 :         case OMP_CLAUSE_SCHEDULE:
    2190          177 :           if (OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (clause) == NULL)
    2191              :             break;
    2192              :           /* FALLTHRU */
    2193         3176 :         case OMP_CLAUSE_FINAL:
    2194         3176 :         case OMP_CLAUSE_IF:
    2195         3176 :         case OMP_CLAUSE_SELF:
    2196         3176 :         case OMP_CLAUSE_NUM_THREADS:
    2197         3176 :         case OMP_CLAUSE_DEPEND:
    2198         3176 :         case OMP_CLAUSE_DOACROSS:
    2199         3176 :         case OMP_CLAUSE_DEVICE:
    2200         3176 :         case OMP_CLAUSE_DYN_GROUPPRIVATE:
    2201         3176 :         case OMP_CLAUSE_NUM_TEAMS:
    2202         3176 :         case OMP_CLAUSE_THREAD_LIMIT:
    2203         3176 :         case OMP_CLAUSE_SAFELEN:
    2204         3176 :         case OMP_CLAUSE_SIMDLEN:
    2205         3176 :         case OMP_CLAUSE_PRIORITY:
    2206         3176 :         case OMP_CLAUSE_GRAINSIZE:
    2207         3176 :         case OMP_CLAUSE_NUM_TASKS:
    2208         3176 :         case OMP_CLAUSE_HINT:
    2209         3176 :         case OMP_CLAUSE_FILTER:
    2210         3176 :         case OMP_CLAUSE_NUM_GANGS:
    2211         3176 :         case OMP_CLAUSE_NUM_WORKERS:
    2212         3176 :         case OMP_CLAUSE_VECTOR_LENGTH:
    2213         3176 :         case OMP_CLAUSE_GANG:
    2214         3176 :         case OMP_CLAUSE_WORKER:
    2215         3176 :         case OMP_CLAUSE_VECTOR:
    2216         3176 :         case OMP_CLAUSE_ASYNC:
    2217         3176 :         case OMP_CLAUSE_WAIT:
    2218              :           /* Several OpenACC clauses have optional arguments.  Check if they
    2219              :              are present.  */
    2220         3176 :           if (OMP_CLAUSE_OPERAND (clause, 0))
    2221              :             {
    2222         2919 :               wi->val_only = true;
    2223         2919 :               wi->is_lhs = false;
    2224         2919 :               convert_local_reference_op (&OMP_CLAUSE_OPERAND (clause, 0),
    2225              :                                           &dummy, wi);
    2226              :             }
    2227              : 
    2228              :           /* The gang clause accepts two arguments.  */
    2229         3176 :           if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_GANG
    2230         3176 :               && OMP_CLAUSE_GANG_STATIC_EXPR (clause))
    2231              :             {
    2232           28 :                 wi->val_only = true;
    2233           28 :                 wi->is_lhs = false;
    2234           28 :                 convert_nonlocal_reference_op
    2235           28 :                   (&OMP_CLAUSE_GANG_STATIC_EXPR (clause), &dummy, wi);
    2236              :             }
    2237              :           break;
    2238              : 
    2239            7 :         case OMP_CLAUSE_DIST_SCHEDULE:
    2240            7 :           if (OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (clause) != NULL)
    2241              :             {
    2242            7 :               wi->val_only = true;
    2243            7 :               wi->is_lhs = false;
    2244            7 :               convert_local_reference_op (&OMP_CLAUSE_OPERAND (clause, 0),
    2245              :                                           &dummy, wi);
    2246              :             }
    2247              :           break;
    2248              : 
    2249         8583 :         case OMP_CLAUSE_MAP:
    2250         8583 :         case OMP_CLAUSE_TO:
    2251         8583 :         case OMP_CLAUSE_FROM:
    2252         8583 :           if (OMP_CLAUSE_SIZE (clause))
    2253              :             {
    2254         8583 :               wi->val_only = true;
    2255         8583 :               wi->is_lhs = false;
    2256         8583 :               convert_local_reference_op (&OMP_CLAUSE_SIZE (clause),
    2257              :                                           &dummy, wi);
    2258              :             }
    2259         8583 :           if (DECL_P (OMP_CLAUSE_DECL (clause)))
    2260         4195 :             goto do_decl_clause;
    2261         4388 :           wi->val_only = true;
    2262         4388 :           wi->is_lhs = false;
    2263         4388 :           walk_tree (&OMP_CLAUSE_DECL (clause), convert_local_reference_op,
    2264              :                      wi, NULL);
    2265         4388 :           break;
    2266              : 
    2267            6 :         case OMP_CLAUSE_ALIGNED:
    2268            6 :           if (OMP_CLAUSE_ALIGNED_ALIGNMENT (clause))
    2269              :             {
    2270            6 :               wi->val_only = true;
    2271            6 :               wi->is_lhs = false;
    2272            6 :               convert_local_reference_op
    2273            6 :                 (&OMP_CLAUSE_ALIGNED_ALIGNMENT (clause), &dummy, wi);
    2274              :             }
    2275              :           /* FALLTHRU */
    2276           42 :         case OMP_CLAUSE_NONTEMPORAL:
    2277            0 :         do_decl_clause_no_supp:
    2278              :           /* Like do_decl_clause, but don't add any suppression.  */
    2279           42 :           decl = OMP_CLAUSE_DECL (clause);
    2280           42 :           if (VAR_P (decl)
    2281           42 :               && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
    2282              :             break;
    2283           30 :           if (decl_function_context (decl) == info->context
    2284           30 :               && !use_pointer_in_frame (decl))
    2285              :             {
    2286           30 :               tree field = lookup_field_for_decl (info, decl, NO_INSERT);
    2287           30 :               if (field)
    2288              :                 {
    2289            0 :                   OMP_CLAUSE_DECL (clause)
    2290            0 :                     = get_local_debug_decl (info, decl, field);
    2291            0 :                   need_frame = true;
    2292              :                 }
    2293              :             }
    2294              :           break;
    2295              : 
    2296           36 :         case OMP_CLAUSE_ALLOCATE:
    2297           36 :           if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (clause))
    2298              :             {
    2299           36 :               wi->val_only = true;
    2300           36 :               wi->is_lhs = false;
    2301           36 :               convert_local_reference_op
    2302           36 :                 (&OMP_CLAUSE_ALLOCATE_ALLOCATOR (clause), &dummy, wi);
    2303              :             }
    2304           36 :           goto do_decl_clause_no_supp;
    2305              : 
    2306              :         case OMP_CLAUSE_NOWAIT:
    2307              :         case OMP_CLAUSE_ORDERED:
    2308              :         case OMP_CLAUSE_DEFAULT:
    2309              :         case OMP_CLAUSE_COPYIN:
    2310              :         case OMP_CLAUSE_COLLAPSE:
    2311              :         case OMP_CLAUSE_TILE:
    2312              :         case OMP_CLAUSE_UNTIED:
    2313              :         case OMP_CLAUSE_MERGEABLE:
    2314              :         case OMP_CLAUSE_PROC_BIND:
    2315              :         case OMP_CLAUSE_NOGROUP:
    2316              :         case OMP_CLAUSE_THREADS:
    2317              :         case OMP_CLAUSE_SIMD:
    2318              :         case OMP_CLAUSE_DEFAULTMAP:
    2319              :         case OMP_CLAUSE_ORDER:
    2320              :         case OMP_CLAUSE_SEQ:
    2321              :         case OMP_CLAUSE_INDEPENDENT:
    2322              :         case OMP_CLAUSE_AUTO:
    2323              :         case OMP_CLAUSE_IF_PRESENT:
    2324              :         case OMP_CLAUSE_FINALIZE:
    2325              :         case OMP_CLAUSE_BIND:
    2326              :         case OMP_CLAUSE__CONDTEMP_:
    2327              :         case OMP_CLAUSE__SCANTEMP_:
    2328              :           break;
    2329              : 
    2330              :           /* The following clause belongs to the OpenACC cache directive, which
    2331              :              is discarded during gimplification.  */
    2332            0 :         case OMP_CLAUSE__CACHE_:
    2333              :           /* The following clauses are only allowed in the OpenMP declare simd
    2334              :              directive, so not seen here.  */
    2335            0 :         case OMP_CLAUSE_UNIFORM:
    2336            0 :         case OMP_CLAUSE_INBRANCH:
    2337            0 :         case OMP_CLAUSE_NOTINBRANCH:
    2338              :           /* The following clauses are only allowed on OpenMP cancel and
    2339              :              cancellation point directives, which at this point have already
    2340              :              been lowered into a function call.  */
    2341            0 :         case OMP_CLAUSE_FOR:
    2342            0 :         case OMP_CLAUSE_PARALLEL:
    2343            0 :         case OMP_CLAUSE_SECTIONS:
    2344            0 :         case OMP_CLAUSE_TASKGROUP:
    2345              :           /* The following clauses are only added during OMP lowering; nested
    2346              :              function decomposition happens before that.  */
    2347            0 :         case OMP_CLAUSE__LOOPTEMP_:
    2348            0 :         case OMP_CLAUSE__REDUCTEMP_:
    2349            0 :         case OMP_CLAUSE__SIMDUID_:
    2350            0 :         case OMP_CLAUSE__SIMT_:
    2351              :           /* The following clauses are only allowed on OpenACC 'routine'
    2352              :              directives, not seen here.  */
    2353            0 :         case OMP_CLAUSE_NOHOST:
    2354              :           /* Anything else.  */
    2355            0 :         default:
    2356            0 :           gcc_unreachable ();
    2357              :         }
    2358              :     }
    2359              : 
    2360         5539 :   info->suppress_expansion = new_suppress;
    2361              : 
    2362         5539 :   if (need_stmts)
    2363         1547 :     for (clause = *pclauses; clause ; clause = OMP_CLAUSE_CHAIN (clause))
    2364         1262 :       switch (OMP_CLAUSE_CODE (clause))
    2365              :         {
    2366          103 :         case OMP_CLAUSE_REDUCTION:
    2367          103 :         case OMP_CLAUSE_IN_REDUCTION:
    2368          103 :         case OMP_CLAUSE_TASK_REDUCTION:
    2369          103 :           if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause))
    2370              :             {
    2371           37 :               tree old_context
    2372           37 :                 = DECL_CONTEXT (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause));
    2373           37 :               DECL_CONTEXT (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause))
    2374           37 :                 = info->context;
    2375           37 :               if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (clause))
    2376            0 :                 DECL_CONTEXT (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (clause))
    2377            0 :                   = info->context;
    2378           37 :               walk_body (convert_local_reference_stmt,
    2379              :                          convert_local_reference_op, info,
    2380           37 :                          &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (clause));
    2381           37 :               walk_body (convert_local_reference_stmt,
    2382              :                          convert_local_reference_op, info,
    2383           37 :                          &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (clause));
    2384           37 :               DECL_CONTEXT (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause))
    2385           37 :                 = old_context;
    2386           37 :               if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (clause))
    2387            0 :                 DECL_CONTEXT (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (clause))
    2388            0 :                   = old_context;
    2389              :             }
    2390              :           break;
    2391              : 
    2392          410 :         case OMP_CLAUSE_LASTPRIVATE:
    2393          410 :           walk_body (convert_local_reference_stmt,
    2394              :                      convert_local_reference_op, info,
    2395          410 :                      &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (clause));
    2396          410 :           break;
    2397              : 
    2398          215 :         case OMP_CLAUSE_LINEAR:
    2399          215 :           walk_body (convert_local_reference_stmt,
    2400              :                      convert_local_reference_op, info,
    2401          215 :                      &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (clause));
    2402          215 :           break;
    2403              : 
    2404              :         default:
    2405              :           break;
    2406              :         }
    2407              : 
    2408         5539 :   return need_frame;
    2409              : }
    2410              : 
    2411              : 
    2412              : /* Called via walk_function+walk_gimple_stmt, rewrite all references to VAR
    2413              :    and PARM_DECLs that were referenced by inner nested functions.
    2414              :    The rewrite will be a structure reference to the local frame variable.  */
    2415              : 
    2416              : static tree
    2417      6357922 : convert_local_reference_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
    2418              :                               struct walk_stmt_info *wi)
    2419              : {
    2420      6357922 :   struct nesting_info *info = (struct nesting_info *) wi->info;
    2421      6357922 :   tree save_local_var_chain;
    2422      6357922 :   bitmap save_suppress;
    2423      6357922 :   char save_static_chain_added;
    2424      6357922 :   bool frame_decl_added;
    2425      6357922 :   gimple *stmt = gsi_stmt (*gsi);
    2426              : 
    2427      6357922 :   switch (gimple_code (stmt))
    2428              :     {
    2429           53 :     case GIMPLE_OMP_TEAMS:
    2430           53 :       if (!gimple_omp_teams_host (as_a <gomp_teams *> (stmt)))
    2431              :         {
    2432           41 :           save_suppress = info->suppress_expansion;
    2433           41 :           convert_local_omp_clauses (gimple_omp_teams_clauses_ptr (stmt), wi);
    2434           41 :           walk_body (convert_local_reference_stmt, convert_local_reference_op,
    2435              :                      info, gimple_omp_body_ptr (stmt));
    2436           41 :           info->suppress_expansion = save_suppress;
    2437           41 :           break;
    2438              :         }
    2439              :       /* FALLTHRU */
    2440              : 
    2441         1404 :     case GIMPLE_OMP_PARALLEL:
    2442         1404 :     case GIMPLE_OMP_TASK:
    2443         1404 :       save_suppress = info->suppress_expansion;
    2444         1404 :       frame_decl_added = false;
    2445         1404 :       if (convert_local_omp_clauses (gimple_omp_taskreg_clauses_ptr (stmt),
    2446              :                                      wi))
    2447              :         {
    2448           41 :           tree c = build_omp_clause (gimple_location (stmt),
    2449              :                                      OMP_CLAUSE_SHARED);
    2450           41 :           (void) get_frame_type (info);
    2451           41 :           OMP_CLAUSE_DECL (c) = info->frame_decl;
    2452           41 :           OMP_CLAUSE_CHAIN (c) = gimple_omp_taskreg_clauses (stmt);
    2453           41 :           gimple_omp_taskreg_set_clauses (stmt, c);
    2454           41 :           info->static_chain_added |= 4;
    2455           41 :           frame_decl_added = true;
    2456              :         }
    2457              : 
    2458         1404 :       save_local_var_chain = info->new_local_var_chain;
    2459         1404 :       save_static_chain_added = info->static_chain_added;
    2460         1404 :       info->new_local_var_chain = NULL;
    2461         1404 :       info->static_chain_added = 0;
    2462              : 
    2463         1404 :       walk_body (convert_local_reference_stmt, convert_local_reference_op, info,
    2464              :                  gimple_omp_body_ptr (stmt));
    2465              : 
    2466         1404 :       if ((info->static_chain_added & 4) != 0 && !frame_decl_added)
    2467              :         {
    2468            1 :           tree c = build_omp_clause (gimple_location (stmt),
    2469              :                                      OMP_CLAUSE_SHARED);
    2470            1 :           (void) get_frame_type (info);
    2471            1 :           OMP_CLAUSE_DECL (c) = info->frame_decl;
    2472            1 :           OMP_CLAUSE_CHAIN (c) = gimple_omp_taskreg_clauses (stmt);
    2473            1 :           info->static_chain_added |= 4;
    2474            1 :           gimple_omp_taskreg_set_clauses (stmt, c);
    2475              :         }
    2476         1404 :       if (info->new_local_var_chain)
    2477           20 :         declare_vars (info->new_local_var_chain,
    2478              :                       gimple_seq_first_stmt (gimple_omp_body (stmt)), false);
    2479         1404 :       info->new_local_var_chain = save_local_var_chain;
    2480         1404 :       info->suppress_expansion = save_suppress;
    2481         1404 :       info->static_chain_added |= save_static_chain_added;
    2482         1404 :       break;
    2483              : 
    2484         1604 :     case GIMPLE_OMP_FOR:
    2485         1604 :       save_suppress = info->suppress_expansion;
    2486         1604 :       convert_local_omp_clauses (gimple_omp_for_clauses_ptr (stmt), wi);
    2487         1604 :       walk_gimple_omp_for (as_a <gomp_for *> (stmt),
    2488              :                            convert_local_reference_stmt,
    2489              :                            convert_local_reference_op, info);
    2490         1604 :       walk_body (convert_local_reference_stmt, convert_local_reference_op,
    2491              :                  info, gimple_omp_body_ptr (stmt));
    2492         1604 :       info->suppress_expansion = save_suppress;
    2493         1604 :       break;
    2494              : 
    2495           42 :     case GIMPLE_OMP_SECTIONS:
    2496           42 :       save_suppress = info->suppress_expansion;
    2497           42 :       convert_local_omp_clauses (gimple_omp_sections_clauses_ptr (stmt), wi);
    2498           42 :       walk_body (convert_local_reference_stmt, convert_local_reference_op,
    2499              :                  info, gimple_omp_body_ptr (stmt));
    2500           42 :       info->suppress_expansion = save_suppress;
    2501           42 :       break;
    2502              : 
    2503          185 :     case GIMPLE_OMP_SINGLE:
    2504          185 :       save_suppress = info->suppress_expansion;
    2505          185 :       convert_local_omp_clauses (gimple_omp_single_clauses_ptr (stmt), wi);
    2506          185 :       walk_body (convert_local_reference_stmt, convert_local_reference_op,
    2507              :                  info, gimple_omp_body_ptr (stmt));
    2508          185 :       info->suppress_expansion = save_suppress;
    2509          185 :       break;
    2510              : 
    2511            0 :     case GIMPLE_OMP_SCOPE:
    2512            0 :       save_suppress = info->suppress_expansion;
    2513            0 :       convert_local_omp_clauses (gimple_omp_scope_clauses_ptr (stmt), wi);
    2514            0 :       walk_body (convert_local_reference_stmt, convert_local_reference_op,
    2515              :                  info, gimple_omp_body_ptr (stmt));
    2516            0 :       info->suppress_expansion = save_suppress;
    2517            0 :       break;
    2518              : 
    2519           38 :     case GIMPLE_OMP_TASKGROUP:
    2520           38 :       save_suppress = info->suppress_expansion;
    2521           38 :       convert_local_omp_clauses (gimple_omp_taskgroup_clauses_ptr (stmt), wi);
    2522           38 :       walk_body (convert_local_reference_stmt, convert_local_reference_op,
    2523              :                  info, gimple_omp_body_ptr (stmt));
    2524           38 :       info->suppress_expansion = save_suppress;
    2525           38 :       break;
    2526              : 
    2527         2225 :     case GIMPLE_OMP_TARGET:
    2528         2225 :       walk_body (convert_local_reference_stmt, convert_local_reference_op, info,
    2529              :                  gimple_omp_target_iterator_loops_ptr (stmt));
    2530              : 
    2531         2225 :       if (!is_gimple_omp_offloaded (stmt))
    2532              :         {
    2533          778 :           save_suppress = info->suppress_expansion;
    2534          778 :           convert_local_omp_clauses (gimple_omp_target_clauses_ptr (stmt), wi);
    2535          778 :           info->suppress_expansion = save_suppress;
    2536          778 :           walk_body (convert_local_reference_stmt, convert_local_reference_op,
    2537              :                      info, gimple_omp_body_ptr (stmt));
    2538          778 :           break;
    2539              :         }
    2540         1447 :       save_suppress = info->suppress_expansion;
    2541         1447 :       frame_decl_added = false;
    2542         1447 :       if (convert_local_omp_clauses (gimple_omp_target_clauses_ptr (stmt), wi))
    2543              :         {
    2544           30 :           tree c = build_omp_clause (gimple_location (stmt), OMP_CLAUSE_MAP);
    2545           30 :           (void) get_frame_type (info);
    2546           30 :           OMP_CLAUSE_DECL (c) = info->frame_decl;
    2547           30 :           OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TOFROM);
    2548           30 :           OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (info->frame_decl);
    2549           30 :           OMP_CLAUSE_CHAIN (c) = gimple_omp_target_clauses (stmt);
    2550           30 :           gimple_omp_target_set_clauses (as_a <gomp_target *> (stmt), c);
    2551           30 :           info->static_chain_added |= 4;
    2552           30 :           frame_decl_added = true;
    2553              :         }
    2554              : 
    2555         1447 :       save_local_var_chain = info->new_local_var_chain;
    2556         1447 :       save_static_chain_added = info->static_chain_added;
    2557         1447 :       info->new_local_var_chain = NULL;
    2558         1447 :       info->static_chain_added = 0;
    2559              : 
    2560         1447 :       walk_body (convert_local_reference_stmt, convert_local_reference_op, info,
    2561              :                  gimple_omp_body_ptr (stmt));
    2562              : 
    2563         1447 :       if ((info->static_chain_added & 4) != 0 && !frame_decl_added)
    2564              :         {
    2565            0 :           tree c = build_omp_clause (gimple_location (stmt), OMP_CLAUSE_MAP);
    2566            0 :           (void) get_frame_type (info);
    2567            0 :           OMP_CLAUSE_DECL (c) = info->frame_decl;
    2568            0 :           OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TOFROM);
    2569            0 :           OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (info->frame_decl);
    2570            0 :           OMP_CLAUSE_CHAIN (c) = gimple_omp_target_clauses (stmt);
    2571            0 :           gimple_omp_target_set_clauses (as_a <gomp_target *> (stmt), c);
    2572            0 :           info->static_chain_added |= 4;
    2573              :         }
    2574              : 
    2575         1447 :       if (info->new_local_var_chain)
    2576           32 :         declare_vars (info->new_local_var_chain,
    2577              :                       gimple_seq_first_stmt (gimple_omp_body (stmt)), false);
    2578         1447 :       info->new_local_var_chain = save_local_var_chain;
    2579         1447 :       info->suppress_expansion = save_suppress;
    2580         1447 :       info->static_chain_added |= save_static_chain_added;
    2581         1447 :       break;
    2582              : 
    2583          606 :     case GIMPLE_OMP_SECTION:
    2584          606 :     case GIMPLE_OMP_STRUCTURED_BLOCK:
    2585          606 :     case GIMPLE_OMP_MASTER:
    2586          606 :     case GIMPLE_OMP_MASKED:
    2587          606 :     case GIMPLE_OMP_ORDERED:
    2588          606 :     case GIMPLE_OMP_SCAN:
    2589          606 :       walk_body (convert_local_reference_stmt, convert_local_reference_op,
    2590              :                  info, gimple_omp_body_ptr (stmt));
    2591          606 :       break;
    2592              : 
    2593       394060 :     case GIMPLE_COND:
    2594       394060 :       wi->val_only = true;
    2595       394060 :       wi->is_lhs = false;
    2596       394060 :       *handled_ops_p = false;
    2597       394060 :       return NULL_TREE;
    2598              : 
    2599      3816132 :     case GIMPLE_ASSIGN:
    2600      3816132 :       if (gimple_clobber_p (stmt))
    2601              :         {
    2602       130008 :           tree lhs = gimple_assign_lhs (stmt);
    2603       130008 :           if (DECL_P (lhs)
    2604       129985 :               && decl_function_context (lhs) == info->context
    2605       129983 :               && !use_pointer_in_frame (lhs)
    2606       259991 :               && lookup_field_for_decl (info, lhs, NO_INSERT))
    2607              :             {
    2608         1675 :               gsi_replace (gsi, gimple_build_nop (), true);
    2609         1675 :               break;
    2610              :             }
    2611              :         }
    2612      3814457 :       *handled_ops_p = false;
    2613      3814457 :       return NULL_TREE;
    2614              : 
    2615       295409 :     case GIMPLE_BIND:
    2616       295409 :       for (tree var = gimple_bind_vars (as_a <gbind *> (stmt));
    2617      1379880 :            var;
    2618      1084471 :            var = DECL_CHAIN (var))
    2619      1084471 :         if (TREE_CODE (var) == NAMELIST_DECL)
    2620              :           {
    2621              :             /* Adjust decls mentioned in NAMELIST_DECL.  */
    2622          151 :             tree decls = NAMELIST_DECL_ASSOCIATED_DECL (var);
    2623          151 :             tree decl;
    2624          151 :             unsigned int i;
    2625              : 
    2626      1085168 :             FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (decls), i, decl)
    2627              :               {
    2628          779 :                 if (VAR_P (decl)
    2629          697 :                     && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
    2630           82 :                   continue;
    2631          615 :                 if (decl_function_context (decl) == info->context
    2632          615 :                     && !use_pointer_in_frame (decl))
    2633              :                   {
    2634          615 :                     tree field = lookup_field_for_decl (info, decl, NO_INSERT);
    2635          615 :                     if (field)
    2636              :                       {
    2637            2 :                         CONSTRUCTOR_ELT (decls, i)->value
    2638            4 :                           = get_local_debug_decl (info, decl, field);
    2639              :                       }
    2640              :                   }
    2641              :               }
    2642              :           }
    2643              : 
    2644       295409 :       *handled_ops_p = false;
    2645       295409 :       return NULL_TREE;
    2646              : 
    2647      1846176 :     default:
    2648              :       /* For every other statement that we are not interested in
    2649              :          handling here, let the walker traverse the operands.  */
    2650      1846176 :       *handled_ops_p = false;
    2651      1846176 :       return NULL_TREE;
    2652              :     }
    2653              : 
    2654              :   /* Indicate that we have handled all the operands ourselves.  */
    2655         7820 :   *handled_ops_p = true;
    2656         7820 :   return NULL_TREE;
    2657              : }
    2658              : 
    2659              : 
    2660              : /* Called via walk_function+walk_gimple_stmt, rewrite all GIMPLE_GOTOs
    2661              :    that reference labels from outer functions.  The rewrite will be a
    2662              :    call to __builtin_nonlocal_goto.  */
    2663              : 
    2664              : static tree
    2665      6360407 : convert_nl_goto_reference (gimple_stmt_iterator *gsi, bool *handled_ops_p,
    2666              :                            struct walk_stmt_info *wi)
    2667              : {
    2668      6360407 :   struct nesting_info *const info = (struct nesting_info *) wi->info, *i;
    2669      6360407 :   tree label, new_label, target_context, x, field;
    2670      6360407 :   gcall *call;
    2671      6360407 :   gimple *stmt = gsi_stmt (*gsi);
    2672              : 
    2673      6360407 :   if (gimple_code (stmt) != GIMPLE_GOTO)
    2674              :     {
    2675      6119360 :       *handled_ops_p = false;
    2676      6119360 :       return NULL_TREE;
    2677              :     }
    2678              : 
    2679       241047 :   label = gimple_goto_dest (stmt);
    2680       241047 :   if (TREE_CODE (label) != LABEL_DECL)
    2681              :     {
    2682           75 :       *handled_ops_p = false;
    2683           75 :       return NULL_TREE;
    2684              :     }
    2685              : 
    2686       240972 :   target_context = decl_function_context (label);
    2687       240972 :   if (target_context == info->context)
    2688              :     {
    2689       240450 :       *handled_ops_p = false;
    2690       240450 :       return NULL_TREE;
    2691              :     }
    2692              : 
    2693          522 :   for (i = info->outer; target_context != i->context; i = i->outer)
    2694            0 :     continue;
    2695              : 
    2696              :   /* The original user label may also be use for a normal goto, therefore
    2697              :      we must create a new label that will actually receive the abnormal
    2698              :      control transfer.  This new label will be marked LABEL_NONLOCAL; this
    2699              :      mark will trigger proper behavior in the cfg, as well as cause the
    2700              :      (hairy target-specific) non-local goto receiver code to be generated
    2701              :      when we expand rtl.  Enter this association into var_map so that we
    2702              :      can insert the new label into the IL during a second pass.  */
    2703          522 :   tree *slot = &i->var_map->get_or_insert (label);
    2704          522 :   if (*slot == NULL)
    2705              :     {
    2706          479 :       new_label = create_artificial_label (UNKNOWN_LOCATION);
    2707          479 :       DECL_NONLOCAL (new_label) = 1;
    2708          479 :       DECL_CONTEXT (new_label) = target_context;
    2709          479 :       *slot = new_label;
    2710              :     }
    2711              :   else
    2712              :     new_label = *slot;
    2713              : 
    2714              :   /* Build: __builtin_nl_goto(new_label, &chain->nl_goto_field).  */
    2715          522 :   field = get_nl_goto_field (i);
    2716          522 :   x = get_frame_field (info, target_context, field, gsi);
    2717          522 :   x = build_addr (x);
    2718          522 :   x = gsi_gimplify_val (info, x, gsi);
    2719         1044 :   call = gimple_build_call (builtin_decl_implicit (BUILT_IN_NONLOCAL_GOTO),
    2720              :                             2, build_addr (new_label), x);
    2721          522 :   gsi_replace (gsi, call, false);
    2722              : 
    2723              :   /* We have handled all of STMT's operands, no need to keep going.  */
    2724          522 :   *handled_ops_p = true;
    2725          522 :   return NULL_TREE;
    2726            0 : }
    2727              : 
    2728              : 
    2729              : /* Called via walk_function+walk_tree, rewrite all GIMPLE_LABELs whose labels
    2730              :    are referenced via nonlocal goto from a nested function.  The rewrite
    2731              :    will involve installing a newly generated DECL_NONLOCAL label, and
    2732              :    (potentially) a branch around the rtl gunk that is assumed to be
    2733              :    attached to such a label.  */
    2734              : 
    2735              : static tree
    2736      6360929 : convert_nl_goto_receiver (gimple_stmt_iterator *gsi, bool *handled_ops_p,
    2737              :                           struct walk_stmt_info *wi)
    2738              : {
    2739      6360929 :   struct nesting_info *const info = (struct nesting_info *) wi->info;
    2740      6360929 :   tree label, new_label;
    2741      6360929 :   gimple_stmt_iterator tmp_gsi;
    2742      6360929 :   glabel *stmt = dyn_cast <glabel *> (gsi_stmt (*gsi));
    2743              : 
    2744      6360929 :   if (!stmt)
    2745              :     {
    2746      5250651 :       *handled_ops_p = false;
    2747      5250651 :       return NULL_TREE;
    2748              :     }
    2749              : 
    2750      1110278 :   label = gimple_label_label (stmt);
    2751              : 
    2752      1110278 :   tree *slot = info->var_map->get (label);
    2753      1110278 :   if (!slot)
    2754              :     {
    2755      1109799 :       *handled_ops_p = false;
    2756      1109799 :       return NULL_TREE;
    2757              :     }
    2758              : 
    2759              :   /* If there's any possibility that the previous statement falls through,
    2760              :      then we must branch around the new non-local label.  */
    2761          479 :   tmp_gsi = wi->gsi;
    2762          479 :   gsi_prev (&tmp_gsi);
    2763          479 :   if (gsi_end_p (tmp_gsi) || gimple_stmt_may_fallthru (gsi_stmt (tmp_gsi)))
    2764              :     {
    2765          268 :       gimple *stmt = gimple_build_goto (label);
    2766          268 :       gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
    2767              :     }
    2768              : 
    2769          479 :   new_label = (tree) *slot;
    2770          479 :   stmt = gimple_build_label (new_label);
    2771          479 :   gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
    2772              : 
    2773          479 :   *handled_ops_p = true;
    2774          479 :   return NULL_TREE;
    2775              : }
    2776              : 
    2777              : 
    2778              : /* Called via walk_function+walk_stmt, rewrite all references to addresses
    2779              :    of nested functions that require the use of trampolines.  The rewrite
    2780              :    will involve a reference a trampoline generated for the occasion.  */
    2781              : 
    2782              : static tree
    2783     20349120 : convert_tramp_reference_op (tree *tp, int *walk_subtrees, void *data)
    2784              : {
    2785     20349120 :   struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
    2786     20349120 :   struct nesting_info *const info = (struct nesting_info *) wi->info, *i;
    2787     20349120 :   tree t = *tp, decl, target_context, x, builtin;
    2788     20349120 :   bool descr;
    2789     20349120 :   gcall *call;
    2790              : 
    2791     20349120 :   *walk_subtrees = 0;
    2792     20349120 :   switch (TREE_CODE (t))
    2793              :     {
    2794       395243 :     case ADDR_EXPR:
    2795              :       /* Build
    2796              :            T.1 = &CHAIN->tramp;
    2797              :            T.2 = __builtin_adjust_trampoline (T.1);
    2798              :            T.3 = (func_type)T.2;
    2799              :       */
    2800              : 
    2801       395243 :       decl = TREE_OPERAND (t, 0);
    2802       395243 :       if (TREE_CODE (decl) != FUNCTION_DECL)
    2803              :         break;
    2804              : 
    2805              :       /* Only need to process nested functions.  */
    2806         2840 :       target_context = decl_function_context (decl);
    2807         2840 :       if (!target_context)
    2808              :         break;
    2809              : 
    2810              :       /* If the nested function doesn't use a static chain, then
    2811              :          it doesn't need a trampoline.  */
    2812         2363 :       if (!DECL_STATIC_CHAIN (decl))
    2813              :         break;
    2814              : 
    2815              :       /* If we don't want a trampoline, then don't build one.  */
    2816          520 :       if (TREE_NO_TRAMPOLINE (t))
    2817              :         break;
    2818              : 
    2819              :       /* Lookup the immediate parent of the callee, as that's where
    2820              :          we need to insert the trampoline.  */
    2821          363 :       for (i = info; i->context != target_context; i = i->outer)
    2822           23 :         continue;
    2823              : 
    2824              :       /* Decide whether to generate a descriptor or a trampoline. */
    2825          340 :       descr = FUNC_ADDR_BY_DESCRIPTOR (t) && !flag_trampolines;
    2826              : 
    2827          340 :       if (descr)
    2828            0 :         x = lookup_descr_for_decl (i, decl, INSERT);
    2829              :       else
    2830          340 :         x = lookup_tramp_for_decl (i, decl, INSERT);
    2831              : 
    2832              :       /* Compute the address of the field holding the trampoline.  */
    2833          340 :       x = get_frame_field (info, target_context, x, &wi->gsi);
    2834              : 
    2835              :       /* APB: We don't need to do the adjustment calls when using off-stack
    2836              :          trampolines, any such adjustment will be done when the off-stack
    2837              :          trampoline is created.  */
    2838          340 :       if (!descr && flag_trampoline_impl == TRAMPOLINE_IMPL_HEAP)
    2839            3 :         x = gsi_gimplify_val (info, x, &wi->gsi);
    2840              :       else
    2841              :         {
    2842          337 :           x = build_addr (x);
    2843              : 
    2844          337 :           x = gsi_gimplify_val (info, x, &wi->gsi);
    2845              : 
    2846              :           /* Do machine-specific ugliness.  Normally this will involve
    2847              :              computing extra alignment, but it can really be anything.  */
    2848          337 :           if (descr)
    2849            0 :             builtin = builtin_decl_implicit (BUILT_IN_ADJUST_DESCRIPTOR);
    2850              :           else
    2851          337 :             builtin = builtin_decl_implicit (BUILT_IN_ADJUST_TRAMPOLINE);
    2852          337 :           call = gimple_build_call (builtin, 1, x);
    2853          337 :           x = init_tmp_var_with_call (info, &wi->gsi, call);
    2854              :         }
    2855              : 
    2856              :       /* Cast back to the proper function type.  */
    2857          340 :       x = build1 (NOP_EXPR, TREE_TYPE (t), x);
    2858          340 :       x = init_tmp_var (info, x, &wi->gsi);
    2859              : 
    2860          340 :       *tp = x;
    2861          340 :       break;
    2862              : 
    2863     19953877 :     default:
    2864     19953877 :       if (!IS_TYPE_OR_DECL_P (t))
    2865     10336278 :         *walk_subtrees = 1;
    2866              :       break;
    2867              :     }
    2868              : 
    2869     20349120 :   return NULL_TREE;
    2870              : }
    2871              : 
    2872              : 
    2873              : /* Called via walk_function+walk_gimple_stmt, rewrite all references
    2874              :    to addresses of nested functions that require the use of
    2875              :    trampolines.  The rewrite will involve a reference a trampoline
    2876              :    generated for the occasion.  */
    2877              : 
    2878              : static tree
    2879      6393052 : convert_tramp_reference_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
    2880              :                               struct walk_stmt_info *wi)
    2881              : {
    2882      6393052 :   struct nesting_info *info = (struct nesting_info *) wi->info;
    2883      6393052 :   gimple *stmt = gsi_stmt (*gsi);
    2884              : 
    2885      6393052 :   switch (gimple_code (stmt))
    2886              :     {
    2887       404333 :     case GIMPLE_CALL:
    2888       404333 :       {
    2889              :         /* Only walk call arguments, lest we generate trampolines for
    2890              :            direct calls.  */
    2891       404333 :         unsigned long i, nargs = gimple_call_num_args (stmt);
    2892      1370498 :         for (i = 0; i < nargs; i++)
    2893       966165 :           walk_tree (gimple_call_arg_ptr (stmt, i), convert_tramp_reference_op,
    2894              :                      wi, NULL);
    2895              :         break;
    2896              :       }
    2897              : 
    2898           53 :     case GIMPLE_OMP_TEAMS:
    2899           53 :       if (!gimple_omp_teams_host (as_a <gomp_teams *> (stmt)))
    2900              :         {
    2901           41 :           *handled_ops_p = false;
    2902           41 :           return NULL_TREE;
    2903              :         }
    2904           12 :       goto do_parallel;
    2905              : 
    2906         2225 :     case GIMPLE_OMP_TARGET:
    2907         2225 :       if (!is_gimple_omp_offloaded (stmt))
    2908              :         {
    2909          778 :           *handled_ops_p = false;
    2910          778 :           return NULL_TREE;
    2911              :         }
    2912         1447 :       walk_body (convert_tramp_reference_stmt, convert_tramp_reference_op,
    2913              :                  info, gimple_omp_target_iterator_loops_ptr (stmt));
    2914              :       /* FALLTHRU */
    2915         2867 :     case GIMPLE_OMP_PARALLEL:
    2916         2867 :     case GIMPLE_OMP_TASK:
    2917         2867 :     do_parallel:
    2918         2867 :       {
    2919         2867 :         tree save_local_var_chain = info->new_local_var_chain;
    2920         2867 :         walk_gimple_op (stmt, convert_tramp_reference_op, wi);
    2921         2867 :         info->new_local_var_chain = NULL;
    2922         2867 :         char save_static_chain_added = info->static_chain_added;
    2923         2867 :         info->static_chain_added = 0;
    2924         2867 :         walk_body (convert_tramp_reference_stmt, convert_tramp_reference_op,
    2925              :                    info, gimple_omp_body_ptr (stmt));
    2926         2867 :         if (info->new_local_var_chain)
    2927            6 :           declare_vars (info->new_local_var_chain,
    2928              :                         gimple_seq_first_stmt (gimple_omp_body (stmt)),
    2929              :                         false);
    2930         8601 :         for (int i = 0; i < 2; i++)
    2931              :           {
    2932         5734 :             tree c, decl;
    2933         5734 :             if ((info->static_chain_added & (1 << i)) == 0)
    2934         5728 :               continue;
    2935            6 :             decl = i ? get_chain_decl (info) : info->frame_decl;
    2936              :             /* Don't add CHAIN.* or FRAME.* twice.  */
    2937            6 :             if (gimple_code (stmt) == GIMPLE_OMP_TARGET)
    2938            0 :               c = gimple_omp_target_clauses (stmt);
    2939              :             else
    2940            6 :               c = gimple_omp_taskreg_clauses (stmt);
    2941            6 :             for (; c; c = OMP_CLAUSE_CHAIN (c))
    2942            1 :               if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
    2943            1 :                    || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED)
    2944            2 :                   && OMP_CLAUSE_DECL (c) == decl)
    2945              :                 break;
    2946            6 :             if (c == NULL && gimple_code (stmt) != GIMPLE_OMP_TARGET)
    2947              :               {
    2948            8 :                 c = build_omp_clause (gimple_location (stmt),
    2949              :                                       i ? OMP_CLAUSE_FIRSTPRIVATE
    2950              :                                       : OMP_CLAUSE_SHARED);
    2951            5 :                 OMP_CLAUSE_DECL (c) = decl;
    2952            5 :                 OMP_CLAUSE_CHAIN (c) = gimple_omp_taskreg_clauses (stmt);
    2953            5 :                 gimple_omp_taskreg_set_clauses (stmt, c);
    2954              :               }
    2955            1 :             else if (c == NULL)
    2956              :               {
    2957            0 :                 c = build_omp_clause (gimple_location (stmt),
    2958              :                                       OMP_CLAUSE_MAP);
    2959            0 :                 OMP_CLAUSE_DECL (c) = decl;
    2960            0 :                 OMP_CLAUSE_SET_MAP_KIND (c,
    2961              :                                          i ? GOMP_MAP_TO : GOMP_MAP_TOFROM);
    2962            0 :                 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
    2963            0 :                 OMP_CLAUSE_CHAIN (c) = gimple_omp_target_clauses (stmt);
    2964            0 :                 gimple_omp_target_set_clauses (as_a <gomp_target *> (stmt),
    2965              :                                                c);
    2966              :               }
    2967              :           }
    2968         2867 :         info->new_local_var_chain = save_local_var_chain;
    2969         2867 :         info->static_chain_added |= save_static_chain_added;
    2970              :       }
    2971         2867 :       break;
    2972              : 
    2973      5985033 :     default:
    2974      5985033 :       *handled_ops_p = false;
    2975      5985033 :       return NULL_TREE;
    2976              :     }
    2977              : 
    2978       407200 :   *handled_ops_p = true;
    2979       407200 :   return NULL_TREE;
    2980              : }
    2981              : 
    2982              : 
    2983              : 
    2984              : /* Called via walk_function+walk_gimple_stmt, rewrite all GIMPLE_CALLs
    2985              :    that reference nested functions to make sure that the static chain
    2986              :    is set up properly for the call.  */
    2987              : 
    2988              : static tree
    2989      6392958 : convert_gimple_call (gimple_stmt_iterator *gsi, bool *handled_ops_p,
    2990              :                      struct walk_stmt_info *wi)
    2991              : {
    2992      6392958 :   struct nesting_info *const info = (struct nesting_info *) wi->info;
    2993      6392958 :   tree decl, target_context;
    2994      6392958 :   char save_static_chain_added;
    2995      6392958 :   int i;
    2996      6392958 :   gimple *stmt = gsi_stmt (*gsi);
    2997              : 
    2998      6392958 :   switch (gimple_code (stmt))
    2999              :     {
    3000       404670 :     case GIMPLE_CALL:
    3001       404670 :       if (gimple_call_chain (stmt))
    3002              :         break;
    3003       404462 :       decl = gimple_call_fndecl (stmt);
    3004       404462 :       if (!decl)
    3005              :         break;
    3006       367506 :       target_context = decl_function_context (decl);
    3007       420822 :       if (target_context && DECL_STATIC_CHAIN (decl))
    3008              :         {
    3009              :           struct nesting_info *i = info;
    3010        18676 :           while (i && i->context != target_context)
    3011         2190 :             i = i->outer;
    3012              :           /* If none of the outer contexts is the target context, this means
    3013              :              that the function is called in a wrong context.  */
    3014        16486 :           if (!i)
    3015            0 :             internal_error ("%s from %s called in %s",
    3016            0 :                             IDENTIFIER_POINTER (DECL_NAME (decl)),
    3017            0 :                             IDENTIFIER_POINTER (DECL_NAME (target_context)),
    3018            0 :                             IDENTIFIER_POINTER (DECL_NAME (info->context)));
    3019              : 
    3020        16486 :           gimple_call_set_chain (as_a <gcall *> (stmt),
    3021              :                                  get_static_chain (info, target_context,
    3022              :                                                    &wi->gsi));
    3023        30822 :           info->static_chain_added |= (1 << (info->context != target_context));
    3024              :         }
    3025              :       break;
    3026              : 
    3027           53 :     case GIMPLE_OMP_TEAMS:
    3028           53 :       if (!gimple_omp_teams_host (as_a <gomp_teams *> (stmt)))
    3029              :         {
    3030           41 :           walk_body (convert_gimple_call, NULL, info,
    3031              :                      gimple_omp_body_ptr (stmt));
    3032           41 :           break;
    3033              :         }
    3034              :       /* FALLTHRU */
    3035              : 
    3036         1420 :     case GIMPLE_OMP_PARALLEL:
    3037         1420 :     case GIMPLE_OMP_TASK:
    3038         1420 :       save_static_chain_added = info->static_chain_added;
    3039         1420 :       info->static_chain_added = 0;
    3040         1420 :       walk_body (convert_gimple_call, NULL, info, gimple_omp_body_ptr (stmt));
    3041         4260 :       for (i = 0; i < 2; i++)
    3042              :         {
    3043         2840 :           tree c, decl;
    3044         2840 :           if ((info->static_chain_added & (1 << i)) == 0)
    3045         2770 :             continue;
    3046           70 :           decl = i ? get_chain_decl (info) : info->frame_decl;
    3047              :           /* Don't add CHAIN.* or FRAME.* twice.  */
    3048           70 :           for (c = gimple_omp_taskreg_clauses (stmt);
    3049          750 :                c;
    3050          680 :                c = OMP_CLAUSE_CHAIN (c))
    3051          682 :             if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
    3052          270 :                  || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED)
    3053          742 :                 && OMP_CLAUSE_DECL (c) == decl)
    3054              :               break;
    3055           70 :           if (c == NULL)
    3056              :             {
    3057          112 :               c = build_omp_clause (gimple_location (stmt),
    3058              :                                     i ? OMP_CLAUSE_FIRSTPRIVATE
    3059              :                                     : OMP_CLAUSE_SHARED);
    3060           68 :               OMP_CLAUSE_DECL (c) = decl;
    3061           68 :               OMP_CLAUSE_CHAIN (c) = gimple_omp_taskreg_clauses (stmt);
    3062           68 :               gimple_omp_taskreg_set_clauses (stmt, c);
    3063              :             }
    3064              :         }
    3065         1420 :       info->static_chain_added |= save_static_chain_added;
    3066         1420 :       break;
    3067              : 
    3068         2225 :     case GIMPLE_OMP_TARGET:
    3069         2225 :       if (!is_gimple_omp_offloaded (stmt))
    3070              :         {
    3071          778 :           walk_body (convert_gimple_call, NULL, info, gimple_omp_body_ptr (stmt));
    3072          778 :           break;
    3073              :         }
    3074         1447 :       save_static_chain_added = info->static_chain_added;
    3075         1447 :       info->static_chain_added = 0;
    3076         1447 :       walk_body (convert_gimple_call, NULL, info, gimple_omp_body_ptr (stmt));
    3077         4341 :       for (i = 0; i < 2; i++)
    3078              :         {
    3079         2894 :           tree c, decl;
    3080         2894 :           if ((info->static_chain_added & (1 << i)) == 0)
    3081         2873 :             continue;
    3082           21 :           decl = i ? get_chain_decl (info) : info->frame_decl;
    3083              :           /* Don't add CHAIN.* or FRAME.* twice.  */
    3084           21 :           for (c = gimple_omp_target_clauses (stmt);
    3085          154 :                c;
    3086          133 :                c = OMP_CLAUSE_CHAIN (c))
    3087          133 :             if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
    3088          133 :                 && OMP_CLAUSE_DECL (c) == decl)
    3089              :               break;
    3090           21 :           if (c == NULL)
    3091              :             {
    3092           21 :               c = build_omp_clause (gimple_location (stmt), OMP_CLAUSE_MAP);
    3093           21 :               OMP_CLAUSE_DECL (c) = decl;
    3094           32 :               OMP_CLAUSE_SET_MAP_KIND (c, i ? GOMP_MAP_TO : GOMP_MAP_TOFROM);
    3095           21 :               OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
    3096           21 :               OMP_CLAUSE_CHAIN (c) = gimple_omp_target_clauses (stmt);
    3097           21 :               gimple_omp_target_set_clauses (as_a <gomp_target *> (stmt),
    3098              :                                              c);
    3099              :             }
    3100              :         }
    3101         1447 :       info->static_chain_added |= save_static_chain_added;
    3102         1447 :       break;
    3103              : 
    3104         1609 :     case GIMPLE_OMP_FOR:
    3105         1609 :       walk_body (convert_gimple_call, NULL, info,
    3106              :                  gimple_omp_for_pre_body_ptr (stmt));
    3107              :       /* FALLTHRU */
    3108         2561 :     case GIMPLE_OMP_SECTIONS:
    3109         2561 :     case GIMPLE_OMP_SECTION:
    3110         2561 :     case GIMPLE_OMP_STRUCTURED_BLOCK:
    3111         2561 :     case GIMPLE_OMP_SINGLE:
    3112         2561 :     case GIMPLE_OMP_SCOPE:
    3113         2561 :     case GIMPLE_OMP_MASTER:
    3114         2561 :     case GIMPLE_OMP_MASKED:
    3115         2561 :     case GIMPLE_OMP_TASKGROUP:
    3116         2561 :     case GIMPLE_OMP_ORDERED:
    3117         2561 :     case GIMPLE_OMP_SCAN:
    3118         2561 :     case GIMPLE_OMP_CRITICAL:
    3119         2561 :       walk_body (convert_gimple_call, NULL, info, gimple_omp_body_ptr (stmt));
    3120         2561 :       break;
    3121              : 
    3122      5982041 :     default:
    3123              :       /* Keep looking for other operands.  */
    3124      5982041 :       *handled_ops_p = false;
    3125      5982041 :       return NULL_TREE;
    3126              :     }
    3127              : 
    3128       410917 :   *handled_ops_p = true;
    3129       410917 :   return NULL_TREE;
    3130              : }
    3131              : 
    3132              : /* Walk the nesting tree starting with ROOT.  Convert all trampolines and
    3133              :    call expressions.  At the same time, determine if a nested function
    3134              :    actually uses its static chain; if not, remember that.  */
    3135              : 
    3136              : static void
    3137         9630 : convert_all_function_calls (struct nesting_info *root)
    3138              : {
    3139         9630 :   unsigned int chain_count = 0, old_chain_count, iter_count;
    3140         9630 :   struct nesting_info *n;
    3141              : 
    3142              :   /* First, optimistically clear static_chain for all decls that haven't
    3143              :      used the static chain already for variable access.  But always create
    3144              :      it if not optimizing.  This makes it possible to reconstruct the static
    3145              :      nesting tree at run time and thus to resolve up-level references from
    3146              :      within the debugger.  */
    3147        89988 :   FOR_EACH_NEST_INFO (n, root)
    3148              :     {
    3149        35364 :       if (n->thunk_p)
    3150            0 :         continue;
    3151        35364 :       tree decl = n->context;
    3152        35364 :       if (!optimize)
    3153              :         {
    3154         5821 :           if (n->inner)
    3155         1698 :             (void) get_frame_type (n);
    3156         5821 :           if (n->outer)
    3157         4193 :             (void) get_chain_decl (n);
    3158              :         }
    3159        29543 :       else if (!n->outer || (!n->chain_decl && !n->chain_field))
    3160              :         {
    3161        26707 :           DECL_STATIC_CHAIN (decl) = 0;
    3162        26707 :           if (dump_file && (dump_flags & TDF_DETAILS))
    3163            0 :             fprintf (dump_file, "Guessing no static-chain for %s\n",
    3164            0 :                      lang_hooks.decl_printable_name (decl, 2));
    3165              :         }
    3166              :       else
    3167         2836 :         DECL_STATIC_CHAIN (decl) = 1;
    3168        35364 :       chain_count += DECL_STATIC_CHAIN (decl);
    3169              :     }
    3170              : 
    3171        80358 :   FOR_EACH_NEST_INFO (n, root)
    3172        35364 :     if (n->thunk_p)
    3173              :       {
    3174            0 :         tree decl = n->context;
    3175            0 :         tree alias = thunk_info::get (cgraph_node::get (decl))->alias;
    3176            0 :         DECL_STATIC_CHAIN (decl) = DECL_STATIC_CHAIN (alias);
    3177              :       }
    3178              : 
    3179              :   /* Walk the functions and perform transformations.  Note that these
    3180              :      transformations can induce new uses of the static chain, which in turn
    3181              :      require re-examining all users of the decl.  */
    3182              :   /* ??? It would make sense to try to use the call graph to speed this up,
    3183              :      but the call graph hasn't really been built yet.  Even if it did, we
    3184              :      would still need to iterate in this loop since address-of references
    3185              :      wouldn't show up in the callgraph anyway.  */
    3186              :   iter_count = 0;
    3187         9686 :   do
    3188              :     {
    3189         9686 :       old_chain_count = chain_count;
    3190         9686 :       chain_count = 0;
    3191         9686 :       iter_count++;
    3192              : 
    3193         9686 :       if (dump_file && (dump_flags & TDF_DETAILS))
    3194            0 :         fputc ('\n', dump_file);
    3195              : 
    3196        90638 :       FOR_EACH_NEST_INFO (n, root)
    3197              :         {
    3198        35633 :           if (n->thunk_p)
    3199            0 :             continue;
    3200        35633 :           tree decl = n->context;
    3201        35633 :           walk_function (convert_tramp_reference_stmt,
    3202              :                          convert_tramp_reference_op, n);
    3203        35633 :           walk_function (convert_gimple_call, NULL, n);
    3204        35633 :           chain_count += DECL_STATIC_CHAIN (decl);
    3205              :         }
    3206              : 
    3207        80952 :       FOR_EACH_NEST_INFO (n, root)
    3208        35633 :         if (n->thunk_p)
    3209              :           {
    3210            0 :             tree decl = n->context;
    3211            0 :             tree alias = thunk_info::get (cgraph_node::get (decl))->alias;
    3212            0 :             DECL_STATIC_CHAIN (decl) = DECL_STATIC_CHAIN (alias);
    3213              :           }
    3214              :     }
    3215         9686 :   while (chain_count != old_chain_count);
    3216              : 
    3217         9630 :   if (dump_file && (dump_flags & TDF_DETAILS))
    3218            0 :     fprintf (dump_file, "convert_all_function_calls iterations: %u\n\n",
    3219              :              iter_count);
    3220         9630 : }
    3221              : 
    3222              : struct nesting_copy_body_data
    3223              : {
    3224              :   copy_body_data cb;
    3225              :   struct nesting_info *root;
    3226              : };
    3227              : 
    3228              : /* A helper subroutine for debug_var_chain type remapping.  */
    3229              : 
    3230              : static tree
    3231           30 : nesting_copy_decl (tree decl, copy_body_data *id)
    3232              : {
    3233           30 :   struct nesting_copy_body_data *nid = (struct nesting_copy_body_data *) id;
    3234           30 :   tree *slot = nid->root->var_map->get (decl);
    3235              : 
    3236           30 :   if (slot)
    3237            6 :     return (tree) *slot;
    3238              : 
    3239           24 :   if (TREE_CODE (decl) == TYPE_DECL && DECL_ORIGINAL_TYPE (decl))
    3240              :     {
    3241            6 :       tree new_decl = copy_decl_no_change (decl, id);
    3242           12 :       DECL_ORIGINAL_TYPE (new_decl)
    3243            6 :         = remap_type (DECL_ORIGINAL_TYPE (decl), id);
    3244            6 :       return new_decl;
    3245              :     }
    3246              : 
    3247           18 :   if (VAR_P (decl)
    3248              :       || TREE_CODE (decl) == PARM_DECL
    3249              :       || TREE_CODE (decl) == RESULT_DECL)
    3250              :     return decl;
    3251              : 
    3252            0 :   return copy_decl_no_change (decl, id);
    3253              : }
    3254              : 
    3255              : /* A helper function for remap_vla_decls.  See if *TP contains
    3256              :    some remapped variables.  */
    3257              : 
    3258              : static tree
    3259           39 : contains_remapped_vars (tree *tp, int *walk_subtrees, void *data)
    3260              : {
    3261           39 :   struct nesting_info *root = (struct nesting_info *) data;
    3262           39 :   tree t = *tp;
    3263              : 
    3264           39 :   if (DECL_P (t))
    3265              :     {
    3266            0 :       *walk_subtrees = 0;
    3267            0 :       tree *slot = root->var_map->get (t);
    3268              : 
    3269            0 :       if (slot)
    3270            0 :         return *slot;
    3271              :     }
    3272              :   return NULL;
    3273              : }
    3274              : 
    3275              : /* Remap VLA decls in BLOCK and subblocks if remapped variables are
    3276              :    involved.  */
    3277              : 
    3278              : static void
    3279         2997 : remap_vla_decls (tree block, struct nesting_info *root)
    3280              : {
    3281         2997 :   tree var, subblock, val, type;
    3282         2997 :   struct nesting_copy_body_data id;
    3283              : 
    3284         5610 :   for (subblock = BLOCK_SUBBLOCKS (block);
    3285         5610 :        subblock;
    3286         2613 :        subblock = BLOCK_CHAIN (subblock))
    3287         2613 :     remap_vla_decls (subblock, root);
    3288              : 
    3289         9382 :   for (var = BLOCK_VARS (block); var; var = DECL_CHAIN (var))
    3290         6385 :     if (VAR_P (var) && DECL_HAS_VALUE_EXPR_P (var))
    3291              :       {
    3292          167 :         val = DECL_VALUE_EXPR (var);
    3293          167 :         type = TREE_TYPE (var);
    3294              : 
    3295          180 :         if (! (INDIRECT_REF_P (val)
    3296           13 :               && VAR_P (TREE_OPERAND (val, 0))
    3297           13 :               && variably_modified_type_p (type, NULL)))
    3298          154 :           continue;
    3299              : 
    3300           13 :         if (root->var_map->get (TREE_OPERAND (val, 0))
    3301           13 :             || walk_tree (&type, contains_remapped_vars, root, NULL))
    3302              :           break;
    3303              :       }
    3304              : 
    3305         2997 :   if (var == NULL_TREE)
    3306         2997 :     return;
    3307              : 
    3308            0 :   memset (&id, 0, sizeof (id));
    3309            0 :   id.cb.copy_decl = nesting_copy_decl;
    3310            0 :   id.cb.decl_map = new hash_map<tree, tree>;
    3311            0 :   id.root = root;
    3312              : 
    3313            0 :   for (; var; var = DECL_CHAIN (var))
    3314            0 :     if (VAR_P (var) && DECL_HAS_VALUE_EXPR_P (var))
    3315              :       {
    3316            0 :         struct nesting_info *i;
    3317            0 :         tree newt, context;
    3318              : 
    3319            0 :         val = DECL_VALUE_EXPR (var);
    3320            0 :         type = TREE_TYPE (var);
    3321              : 
    3322            0 :         if (! (INDIRECT_REF_P (val)
    3323            0 :               && VAR_P (TREE_OPERAND (val, 0))
    3324            0 :               && variably_modified_type_p (type, NULL)))
    3325            0 :           continue;
    3326              : 
    3327            0 :         tree *slot = root->var_map->get (TREE_OPERAND (val, 0));
    3328            0 :         if (!slot && !walk_tree (&type, contains_remapped_vars, root, NULL))
    3329            0 :           continue;
    3330              : 
    3331            0 :         context = decl_function_context (var);
    3332            0 :         for (i = root; i; i = i->outer)
    3333            0 :           if (i->context == context)
    3334              :             break;
    3335              : 
    3336            0 :         if (i == NULL)
    3337            0 :           continue;
    3338              : 
    3339              :         /* Fully expand value expressions.  This avoids having debug variables
    3340              :            only referenced from them and that can be swept during GC.  */
    3341            0 :         if (slot)
    3342              :           {
    3343            0 :             tree t = (tree) *slot;
    3344            0 :             gcc_assert (DECL_P (t) && DECL_HAS_VALUE_EXPR_P (t));
    3345            0 :             val = build1 (INDIRECT_REF, TREE_TYPE (val), DECL_VALUE_EXPR (t));
    3346              :           }
    3347              : 
    3348            0 :         id.cb.src_fn = i->context;
    3349            0 :         id.cb.dst_fn = i->context;
    3350            0 :         id.cb.src_cfun = DECL_STRUCT_FUNCTION (root->context);
    3351              : 
    3352            0 :         TREE_TYPE (var) = newt = remap_type (type, &id.cb);
    3353            0 :         while (POINTER_TYPE_P (newt) && !TYPE_NAME (newt))
    3354              :           {
    3355            0 :             newt = TREE_TYPE (newt);
    3356            0 :             type = TREE_TYPE (type);
    3357              :           }
    3358            0 :         if (TYPE_NAME (newt)
    3359            0 :             && TREE_CODE (TYPE_NAME (newt)) == TYPE_DECL
    3360            0 :             && DECL_ORIGINAL_TYPE (TYPE_NAME (newt))
    3361            0 :             && newt != type
    3362            0 :             && TYPE_NAME (newt) == TYPE_NAME (type))
    3363            0 :           TYPE_NAME (newt) = remap_decl (TYPE_NAME (newt), &id.cb);
    3364              : 
    3365            0 :         walk_tree (&val, copy_tree_body_r, &id.cb, NULL);
    3366            0 :         if (val != DECL_VALUE_EXPR (var))
    3367            0 :           SET_DECL_VALUE_EXPR (var, val);
    3368              :       }
    3369              : 
    3370            0 :   delete id.cb.decl_map;
    3371              : }
    3372              : 
    3373              : /* Fixup VLA decls in BLOCK and subblocks if remapped variables are
    3374              :    involved.  */
    3375              : 
    3376              : static void
    3377       293035 : fixup_vla_decls (tree block)
    3378              : {
    3379      1278007 :   for (tree var = BLOCK_VARS (block); var; var = DECL_CHAIN (var))
    3380       984972 :     if (VAR_P (var) && DECL_HAS_VALUE_EXPR_P (var))
    3381              :       {
    3382         3865 :         tree val = DECL_VALUE_EXPR (var);
    3383              : 
    3384         3865 :         if (! (INDIRECT_REF_P (val)
    3385          352 :               && VAR_P (TREE_OPERAND (val, 0))
    3386          350 :               && DECL_HAS_VALUE_EXPR_P (TREE_OPERAND (val, 0))))
    3387         3832 :           continue;
    3388              : 
    3389              :         /* Fully expand value expressions.  This avoids having debug variables
    3390              :            only referenced from them and that can be swept during GC.  */
    3391           33 :         val = build1 (INDIRECT_REF, TREE_TYPE (val),
    3392           33 :                       DECL_VALUE_EXPR (TREE_OPERAND (val, 0)));
    3393           33 :         SET_DECL_VALUE_EXPR (var, val);
    3394              :       }
    3395              : 
    3396       551090 :   for (tree sub = BLOCK_SUBBLOCKS (block); sub; sub = BLOCK_CHAIN (sub))
    3397       258055 :     fixup_vla_decls (sub);
    3398       293035 : }
    3399              : 
    3400              : /* Fold the MEM_REF *E.  */
    3401              : bool
    3402            0 : fold_mem_refs (tree *const &e, void *data ATTRIBUTE_UNUSED)
    3403              : {
    3404            0 :   tree *ref_p = const_cast<tree *> (e);
    3405            0 :   *ref_p = fold (*ref_p);
    3406            0 :   return true;
    3407              : }
    3408              : 
    3409              : /* Given DECL, a nested function, build an initialization call for FIELD,
    3410              :    the trampoline or descriptor for DECL, using FUNC as the function.  */
    3411              : 
    3412              : static gcall *
    3413          289 : build_init_call_stmt (struct nesting_info *info, tree decl, tree field,
    3414              :                       tree func)
    3415              : {
    3416          289 :   tree arg1, arg2, arg3, x;
    3417              : 
    3418          289 :   gcc_assert (DECL_STATIC_CHAIN (decl));
    3419          289 :   arg3 = build_addr (info->frame_decl);
    3420              : 
    3421          289 :   arg2 = build_addr (decl);
    3422              : 
    3423          289 :   x = build3 (COMPONENT_REF, TREE_TYPE (field),
    3424              :               info->frame_decl, field, NULL_TREE);
    3425          289 :   arg1 = build_addr (x);
    3426              : 
    3427          289 :   return gimple_build_call (func, 3, arg1, arg2, arg3);
    3428              : }
    3429              : 
    3430              : /* Do "everything else" to clean up or complete state collected by the various
    3431              :    walking passes -- create a field to hold the frame base address, lay out the
    3432              :    types and decls, generate code to initialize the frame decl, store critical
    3433              :    expressions in the struct function for rtl to find.  */
    3434              : 
    3435              : static void
    3436        35364 : finalize_nesting_tree_1 (struct nesting_info *root)
    3437              : {
    3438        35364 :   gimple_seq cleanup_list = NULL;
    3439        35364 :   gimple_seq stmt_list = NULL;
    3440        35364 :   gimple *stmt;
    3441        35364 :   tree context = root->context;
    3442        35364 :   struct function *sf;
    3443              : 
    3444        35364 :   if (root->thunk_p)
    3445            0 :     return;
    3446              : 
    3447              :   /* If we created a non-local frame type or decl, we need to lay them
    3448              :      out at this time.  */
    3449        35364 :   if (root->frame_type)
    3450              :     {
    3451              :       /* Debugging information needs to compute the frame base address of the
    3452              :          parent frame out of the static chain from the nested frame.
    3453              : 
    3454              :          The static chain is the address of the FRAME record, so one could
    3455              :          imagine it would be possible to compute the frame base address just
    3456              :          adding a constant offset to this address.  Unfortunately, this is not
    3457              :          possible: if the FRAME object has alignment constraints that are
    3458              :          stronger than the stack, then the offset between the frame base and
    3459              :          the FRAME object will be dynamic.
    3460              : 
    3461              :          What we do instead is to append a field to the FRAME object that holds
    3462              :          the frame base address: then debug info just has to fetch this
    3463              :          field.  */
    3464              : 
    3465              :       /* Debugging information will refer to the CFA as the frame base
    3466              :          address: we will do the same here.  */
    3467         3538 :       const tree frame_addr_fndecl
    3468         3538 :         = builtin_decl_explicit (BUILT_IN_DWARF_CFA);
    3469              : 
    3470              :       /* Create a field in the FRAME record to hold the frame base address for
    3471              :          this stack frame.  Since it will be used only by the debugger, put it
    3472              :          at the end of the record in order not to shift all other offsets.  */
    3473         3538 :       tree fb_decl = make_node (FIELD_DECL);
    3474              : 
    3475         3538 :       DECL_NAME (fb_decl) = get_identifier ("FRAME_BASE.PARENT");
    3476         3538 :       TREE_TYPE (fb_decl) = ptr_type_node;
    3477         3538 :       TREE_ADDRESSABLE (fb_decl) = 1;
    3478         3538 :       DECL_CONTEXT (fb_decl) = root->frame_type;
    3479         3538 :       TYPE_FIELDS (root->frame_type) = chainon (TYPE_FIELDS (root->frame_type),
    3480              :                                                 fb_decl);
    3481              : 
    3482              :       /* In some cases the frame type will trigger the -Wpadded warning.
    3483              :          This is not helpful; suppress it. */
    3484         3538 :       int save_warn_padded = warn_padded;
    3485         3538 :       warn_padded = 0;
    3486         3538 :       layout_type (root->frame_type);
    3487         3538 :       warn_padded = save_warn_padded;
    3488         3538 :       layout_decl (root->frame_decl, 0);
    3489              : 
    3490              :       /* Initialize the frame base address field.  If the builtin we need is
    3491              :          not available, set it to NULL so that debugging information does not
    3492              :          reference junk.  */
    3493         3538 :       tree fb_ref = build3 (COMPONENT_REF, TREE_TYPE (fb_decl),
    3494              :                             root->frame_decl, fb_decl, NULL_TREE);
    3495         3538 :       tree fb_tmp;
    3496              : 
    3497         3538 :       if (frame_addr_fndecl != NULL_TREE)
    3498              :         {
    3499         1091 :           gcall *fb_gimple = gimple_build_call (frame_addr_fndecl, 1,
    3500              :                                                 integer_zero_node);
    3501         1091 :           gimple_stmt_iterator gsi = gsi_last (stmt_list);
    3502              : 
    3503         1091 :           fb_tmp = init_tmp_var_with_call (root, &gsi, fb_gimple);
    3504              :         }
    3505              :       else
    3506         2447 :         fb_tmp = build_int_cst (TREE_TYPE (fb_ref), 0);
    3507         3538 :       gimple_seq_add_stmt (&stmt_list,
    3508         3538 :                            gimple_build_assign (fb_ref, fb_tmp));
    3509              : 
    3510         3538 :       declare_vars (root->frame_decl,
    3511              :                     gimple_seq_first_stmt (gimple_body (context)), true);
    3512              :     }
    3513              : 
    3514              :   /* If any parameters were referenced non-locally, then we need to insert
    3515              :      a copy or a pointer.  */
    3516        35364 :   if (root->any_parm_remapped)
    3517              :     {
    3518          232 :       tree p;
    3519          647 :       for (p = DECL_ARGUMENTS (context); p ; p = DECL_CHAIN (p))
    3520              :         {
    3521          415 :           tree field, x, y;
    3522              : 
    3523          415 :           field = lookup_field_for_decl (root, p, NO_INSERT);
    3524          415 :           if (!field)
    3525          144 :             continue;
    3526              : 
    3527          271 :           if (use_pointer_in_frame (p))
    3528           21 :             x = build_addr (p);
    3529              :           else
    3530              :             x = p;
    3531              : 
    3532              :           /* If the assignment is from a non-register the stmt is
    3533              :              not valid gimple.  Make it so by using a temporary instead.  */
    3534          271 :           if (!is_gimple_reg (x)
    3535          271 :               && is_gimple_reg_type (TREE_TYPE (x)))
    3536              :             {
    3537           44 :               gimple_stmt_iterator gsi = gsi_last (stmt_list);
    3538           44 :               x = init_tmp_var (root, x, &gsi);
    3539              :             }
    3540              : 
    3541          271 :           y = build3 (COMPONENT_REF, TREE_TYPE (field),
    3542              :                       root->frame_decl, field, NULL_TREE);
    3543          271 :           stmt = gimple_build_assign (y, x);
    3544          271 :           gimple_seq_add_stmt (&stmt_list, stmt);
    3545              :         }
    3546              :     }
    3547              : 
    3548              :   /* If a chain_field was created, then it needs to be initialized
    3549              :      from chain_decl.  */
    3550        35364 :   if (root->chain_field)
    3551              :     {
    3552           79 :       tree x = build3 (COMPONENT_REF, TREE_TYPE (root->chain_field),
    3553              :                        root->frame_decl, root->chain_field, NULL_TREE);
    3554           79 :       stmt = gimple_build_assign (x, get_chain_decl (root));
    3555           79 :       gimple_seq_add_stmt (&stmt_list, stmt);
    3556              :     }
    3557              : 
    3558              :   /* If trampolines were created, then we need to initialize them.  */
    3559        35364 :   if (root->any_tramp_created)
    3560              :     {
    3561          255 :       struct nesting_info *i;
    3562          629 :       for (i = root->inner; i ; i = i->next)
    3563              :         {
    3564          374 :           tree field, x;
    3565              : 
    3566          374 :           field = lookup_tramp_for_decl (root, i->context, NO_INSERT);
    3567          374 :           if (!field)
    3568           84 :             continue;
    3569              : 
    3570          290 :           if (flag_trampoline_impl == TRAMPOLINE_IMPL_HEAP)
    3571              :             {
    3572              :               /* We pass a whole bunch of arguments to the builtin function that
    3573              :                  creates the off-stack trampoline, these are
    3574              :                  1. The nested function chain value (that must be passed to the
    3575              :                  nested function so it can find the function arguments).
    3576              :                  2. A pointer to the nested function implementation,
    3577              :                  3. The address in the local stack frame where we should write
    3578              :                  the address of the trampoline.
    3579              : 
    3580              :                  When this code was originally written I just kind of threw
    3581              :                  everything at the builtin, figuring I'd work out what was
    3582              :                  actually needed later, I think, the stack pointer could
    3583              :                  certainly be dropped, arguments #2 and #4 are based off the
    3584              :                  stack pointer anyway, so #1 doesn't seem to add much value.  */
    3585            1 :               tree arg1, arg2, arg3;
    3586              : 
    3587            1 :               gcc_assert (DECL_STATIC_CHAIN (i->context));
    3588            1 :               arg1 = build_addr (root->frame_decl);
    3589            1 :               arg2 = build_addr (i->context);
    3590              : 
    3591            1 :               x = build3 (COMPONENT_REF, TREE_TYPE (field),
    3592              :                           root->frame_decl, field, NULL_TREE);
    3593            1 :               arg3 = build_addr (x);
    3594              : 
    3595            1 :               x = builtin_decl_explicit (BUILT_IN_GCC_NESTED_PTR_CREATED);
    3596            1 :               stmt = gimple_build_call (x, 3, arg1, arg2, arg3);
    3597            1 :               gimple_seq_add_stmt (&stmt_list, stmt);
    3598              : 
    3599              :               /* This call to delete the nested function trampoline is added to
    3600              :                  the cleanup list, and called when we exit the current scope.  */
    3601            1 :               x = builtin_decl_explicit (BUILT_IN_GCC_NESTED_PTR_DELETED);
    3602            1 :               stmt = gimple_build_call (x, 0);
    3603            1 :               gimple_seq_add_stmt (&cleanup_list, stmt);
    3604              :             }
    3605              :           else
    3606              :             {
    3607              :               /* Original code to initialise the on stack trampoline.  */
    3608          289 :               x = builtin_decl_implicit (BUILT_IN_INIT_TRAMPOLINE);
    3609          289 :               stmt = build_init_call_stmt (root, i->context, field, x);
    3610          289 :               gimple_seq_add_stmt (&stmt_list, stmt);
    3611              :             }
    3612              :         }
    3613              :     }
    3614              : 
    3615              :   /* If descriptors were created, then we need to initialize them.  */
    3616        35364 :   if (root->any_descr_created)
    3617              :     {
    3618            0 :       struct nesting_info *i;
    3619            0 :       for (i = root->inner; i ; i = i->next)
    3620              :         {
    3621            0 :           tree field, x;
    3622              : 
    3623            0 :           field = lookup_descr_for_decl (root, i->context, NO_INSERT);
    3624            0 :           if (!field)
    3625            0 :             continue;
    3626              : 
    3627            0 :           x = builtin_decl_implicit (BUILT_IN_INIT_DESCRIPTOR);
    3628            0 :           stmt = build_init_call_stmt (root, i->context, field, x);
    3629            0 :           gimple_seq_add_stmt (&stmt_list, stmt);
    3630              :         }
    3631              :     }
    3632              : 
    3633              :   /* If we created initialization statements, insert them.  */
    3634        35364 :   if (stmt_list)
    3635              :     {
    3636         3538 :       if (flag_trampoline_impl == TRAMPOLINE_IMPL_HEAP)
    3637              :         {
    3638              :           /* Handle off-stack trampolines.  */
    3639            1 :           gbind *bind;
    3640            1 :           annotate_all_with_location (stmt_list, DECL_SOURCE_LOCATION (context));
    3641            1 :           annotate_all_with_location (cleanup_list, DECL_SOURCE_LOCATION (context));
    3642            1 :           bind = gimple_seq_first_stmt_as_a_bind (gimple_body (context));
    3643            1 :           gimple_seq_add_seq (&stmt_list, gimple_bind_body (bind));
    3644              : 
    3645            1 :           gimple_seq xxx_list = NULL;
    3646              : 
    3647            1 :           if (cleanup_list != NULL)
    3648              :             {
    3649              :               /* Maybe we shouldn't be creating this try/finally if -fno-exceptions is
    3650              :                  in use.  If this is the case, then maybe we should, instead, be
    3651              :                  inserting the cleanup code onto every path out of this function?  Not
    3652              :                  yet figured out how we would do this.  */
    3653            1 :               gtry *t = gimple_build_try (stmt_list, cleanup_list, GIMPLE_TRY_FINALLY);
    3654            1 :               gimple_seq_add_stmt (&xxx_list, t);
    3655              :             }
    3656              :           else
    3657            0 :             xxx_list = stmt_list;
    3658              : 
    3659            1 :           gimple_bind_set_body (bind, xxx_list);
    3660              :         }
    3661              :       else
    3662              :         {
    3663              :           /* The traditional, on stack trampolines.  */
    3664         3537 :           gbind *bind;
    3665         3537 :           annotate_all_with_location (stmt_list, DECL_SOURCE_LOCATION (context));
    3666         3537 :           bind = gimple_seq_first_stmt_as_a_bind (gimple_body (context));
    3667         3537 :           gimple_seq_add_seq (&stmt_list, gimple_bind_body (bind));
    3668         3537 :           gimple_bind_set_body (bind, stmt_list);
    3669              :         }
    3670              :     }
    3671              : 
    3672              :   /* If a chain_decl was created, then it needs to be registered with
    3673              :      struct function so that it gets initialized from the static chain
    3674              :      register at the beginning of the function.  */
    3675        35364 :   sf = DECL_STRUCT_FUNCTION (root->context);
    3676        35364 :   sf->static_chain_decl = root->chain_decl;
    3677              : 
    3678              :   /* Similarly for the non-local goto save area.  */
    3679        35364 :   if (root->nl_goto_field)
    3680              :     {
    3681          375 :       sf->nonlocal_goto_save_area
    3682          375 :         = get_frame_field (root, context, root->nl_goto_field, NULL);
    3683          375 :       sf->has_nonlocal_label = 1;
    3684              :     }
    3685              : 
    3686              :   /* Make sure all new local variables get inserted into the
    3687              :      proper BIND_EXPR.  */
    3688        35364 :   if (root->new_local_var_chain)
    3689         3697 :     declare_vars (root->new_local_var_chain,
    3690              :                   gimple_seq_first_stmt (gimple_body (root->context)),
    3691              :                   false);
    3692              : 
    3693        35364 :   if (root->debug_var_chain)
    3694              :     {
    3695          384 :       tree debug_var;
    3696          384 :       gbind *scope;
    3697              : 
    3698          384 :       remap_vla_decls (DECL_INITIAL (root->context), root);
    3699              : 
    3700         1136 :       for (debug_var = root->debug_var_chain; debug_var;
    3701          752 :            debug_var = DECL_CHAIN (debug_var))
    3702          758 :         if (variably_modified_type_p (TREE_TYPE (debug_var), NULL))
    3703              :           break;
    3704              : 
    3705              :       /* If there are any debug decls with variable length types,
    3706              :          remap those types using other debug_var_chain variables.  */
    3707          384 :       if (debug_var)
    3708              :         {
    3709            6 :           struct nesting_copy_body_data id;
    3710              : 
    3711            6 :           memset (&id, 0, sizeof (id));
    3712            6 :           id.cb.copy_decl = nesting_copy_decl;
    3713            6 :           id.cb.decl_map = new hash_map<tree, tree>;
    3714            6 :           id.root = root;
    3715              : 
    3716           36 :           for (; debug_var; debug_var = DECL_CHAIN (debug_var))
    3717           30 :             if (variably_modified_type_p (TREE_TYPE (debug_var), NULL))
    3718              :               {
    3719            6 :                 tree type = TREE_TYPE (debug_var);
    3720            6 :                 tree newt, t = type;
    3721            6 :                 struct nesting_info *i;
    3722              : 
    3723           12 :                 for (i = root; i; i = i->outer)
    3724           12 :                   if (variably_modified_type_p (type, i->context))
    3725              :                     break;
    3726              : 
    3727            6 :                 if (i == NULL)
    3728            0 :                   continue;
    3729              : 
    3730            6 :                 id.cb.src_fn = i->context;
    3731            6 :                 id.cb.dst_fn = i->context;
    3732            6 :                 id.cb.src_cfun = DECL_STRUCT_FUNCTION (root->context);
    3733              : 
    3734            6 :                 TREE_TYPE (debug_var) = newt = remap_type (type, &id.cb);
    3735           12 :                 while (POINTER_TYPE_P (newt) && !TYPE_NAME (newt))
    3736              :                   {
    3737            6 :                     newt = TREE_TYPE (newt);
    3738            6 :                     t = TREE_TYPE (t);
    3739              :                   }
    3740            6 :                 if (TYPE_NAME (newt)
    3741            6 :                     && TREE_CODE (TYPE_NAME (newt)) == TYPE_DECL
    3742            6 :                     && DECL_ORIGINAL_TYPE (TYPE_NAME (newt))
    3743            6 :                     && newt != t
    3744           12 :                     && TYPE_NAME (newt) == TYPE_NAME (t))
    3745            6 :                   TYPE_NAME (newt) = remap_decl (TYPE_NAME (newt), &id.cb);
    3746              :               }
    3747              : 
    3748           12 :           delete id.cb.decl_map;
    3749              :         }
    3750              : 
    3751          384 :       scope = gimple_seq_first_stmt_as_a_bind (gimple_body (root->context));
    3752          384 :       if (gimple_bind_block (scope))
    3753          382 :         declare_vars (root->debug_var_chain, scope, true);
    3754              :       else
    3755            2 :         BLOCK_VARS (DECL_INITIAL (root->context))
    3756            4 :           = chainon (BLOCK_VARS (DECL_INITIAL (root->context)),
    3757              :                      root->debug_var_chain);
    3758              :     }
    3759              :   else
    3760        34980 :     fixup_vla_decls (DECL_INITIAL (root->context));
    3761              : 
    3762              :   /* Fold the rewritten MEM_REF trees.  */
    3763        35364 :   root->mem_refs->traverse<void *, fold_mem_refs> (NULL);
    3764              : 
    3765              :   /* Dump the translated tree function.  */
    3766        35364 :   if (dump_file)
    3767              :     {
    3768            0 :       fputs ("\n\n", dump_file);
    3769            0 :       dump_function_to_file (root->context, dump_file, dump_flags);
    3770              :     }
    3771              : }
    3772              : 
    3773              : static void
    3774         9630 : finalize_nesting_tree (struct nesting_info *root)
    3775              : {
    3776         9630 :   struct nesting_info *n;
    3777        89988 :   FOR_EACH_NEST_INFO (n, root)
    3778        35364 :     finalize_nesting_tree_1 (n);
    3779         9630 : }
    3780              : 
    3781              : /* Unnest the nodes and pass them to cgraph.  */
    3782              : 
    3783              : static void
    3784        35364 : unnest_nesting_tree_1 (struct nesting_info *root)
    3785              : {
    3786        35364 :   struct cgraph_node *node = cgraph_node::get (root->context);
    3787              : 
    3788              :   /* For nested functions update the cgraph to reflect unnesting.
    3789              :      We also delay finalizing of these functions up to this point.  */
    3790        35364 :   if (nested_function_info::get (node)->origin)
    3791              :     {
    3792        25734 :        unnest_function (node);
    3793        25734 :        if (!root->thunk_p)
    3794        25734 :          cgraph_node::finalize_function (root->context, true);
    3795              :     }
    3796        35364 : }
    3797              : 
    3798              : static void
    3799         9630 : unnest_nesting_tree (struct nesting_info *root)
    3800              : {
    3801         9630 :   struct nesting_info *n;
    3802        89988 :   FOR_EACH_NEST_INFO (n, root)
    3803        35364 :     unnest_nesting_tree_1 (n);
    3804         9630 : }
    3805              : 
    3806              : /* Free the data structures allocated during this pass.  */
    3807              : 
    3808              : static void
    3809         9630 : free_nesting_tree (struct nesting_info *root)
    3810              : {
    3811         9630 :   struct nesting_info *node, *next;
    3812              : 
    3813         9630 :   node = iter_nestinfo_start (root);
    3814        35364 :   do
    3815              :     {
    3816        35364 :       next = iter_nestinfo_next (node);
    3817        70728 :       delete node->var_map;
    3818        70728 :       delete node->field_map;
    3819        70728 :       delete node->mem_refs;
    3820        35364 :       free (node);
    3821        35364 :       node = next;
    3822              :     }
    3823        35364 :   while (node);
    3824         9630 : }
    3825              : 
    3826              : /* Gimplify a function and all its nested functions.  */
    3827              : static void
    3828        35364 : gimplify_all_functions (struct cgraph_node *root)
    3829              : {
    3830        35364 :   struct cgraph_node *iter;
    3831        35364 :   if (!gimple_body (root->decl))
    3832        25733 :     gimplify_function_tree (root->decl);
    3833       122196 :   for (iter = first_nested_function (root); iter;
    3834        25734 :        iter = next_nested_function (iter))
    3835        25734 :     if (!iter->thunk)
    3836        25734 :       gimplify_all_functions (iter);
    3837        35364 : }
    3838              : 
    3839              : /* Main entry point for this pass.  Process FNDECL and all of its nested
    3840              :    subroutines and turn them into something less tightly bound.  */
    3841              : 
    3842              : void
    3843         9630 : lower_nested_functions (tree fndecl)
    3844              : {
    3845         9630 :   struct cgraph_node *cgn;
    3846         9630 :   struct nesting_info *root;
    3847              : 
    3848              :   /* If there are no nested functions, there's nothing to do.  */
    3849         9630 :   cgn = cgraph_node::get (fndecl);
    3850        19260 :   if (!first_nested_function (cgn))
    3851              :     return;
    3852              : 
    3853         9630 :   gimplify_all_functions (cgn);
    3854              : 
    3855         9630 :   set_dump_file (dump_begin (TDI_nested, &dump_flags));
    3856         9630 :   if (dump_file)
    3857            0 :     fprintf (dump_file, "\n;; Function %s\n\n",
    3858            0 :              lang_hooks.decl_printable_name (fndecl, 2));
    3859              : 
    3860         9630 :   bitmap_obstack_initialize (&nesting_info_bitmap_obstack);
    3861         9630 :   root = create_nesting_tree (cgn);
    3862              : 
    3863         9630 :   walk_all_functions (convert_nonlocal_reference_stmt,
    3864              :                       convert_nonlocal_reference_op,
    3865              :                       root);
    3866         9630 :   walk_all_functions (convert_local_reference_stmt,
    3867              :                       convert_local_reference_op,
    3868              :                       root);
    3869         9630 :   walk_all_functions (convert_nl_goto_reference, NULL, root);
    3870         9630 :   walk_all_functions (convert_nl_goto_receiver, NULL, root);
    3871              : 
    3872         9630 :   convert_all_function_calls (root);
    3873         9630 :   finalize_nesting_tree (root);
    3874         9630 :   unnest_nesting_tree (root);
    3875              : 
    3876         9630 :   free_nesting_tree (root);
    3877         9630 :   bitmap_obstack_release (&nesting_info_bitmap_obstack);
    3878              : 
    3879         9630 :   if (dump_file)
    3880              :     {
    3881            0 :       dump_end (TDI_nested, dump_file);
    3882            0 :       set_dump_file (NULL);
    3883              :     }
    3884              : }
    3885              : 
    3886              : #include "gt-tree-nested.h"
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.