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