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