OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.2.2/] [gcc/] [tree-nested.c] - Blame information for rev 298

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 38 julius
/* Nested function decomposition for trees.
2
   Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
3
 
4
   This file is part of GCC.
5
 
6
   GCC is free software; you can redistribute it and/or modify
7
   it under the terms of the GNU General Public License as published by
8
   the Free Software Foundation; either version 3, or (at your option)
9
   any later version.
10
 
11
   GCC is distributed in the hope that it will be useful,
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
   GNU General Public License for more details.
15
 
16
   You should have received a copy of the GNU General Public License
17
   along with GCC; see the file COPYING3.  If not see
18
<http://www.gnu.org/licenses/>.  */
19
 
20
#include "config.h"
21
#include "system.h"
22
#include "coretypes.h"
23
#include "tm.h"
24
#include "tree.h"
25
#include "rtl.h"
26
#include "tm_p.h"
27
#include "function.h"
28
#include "tree-dump.h"
29
#include "tree-inline.h"
30
#include "tree-gimple.h"
31
#include "tree-iterator.h"
32
#include "tree-flow.h"
33
#include "cgraph.h"
34
#include "expr.h"
35
#include "langhooks.h"
36
#include "ggc.h"
37
 
38
 
39
/* The object of this pass is to lower the representation of a set of nested
40
   functions in order to expose all of the gory details of the various
41
   nonlocal references.  We want to do this sooner rather than later, in
42
   order to give us more freedom in emitting all of the functions in question.
43
 
44
   Back in olden times, when gcc was young, we developed an insanely
45
   complicated scheme whereby variables which were referenced nonlocally
46
   were forced to live in the stack of the declaring function, and then
47
   the nested functions magically discovered where these variables were
48
   placed.  In order for this scheme to function properly, it required
49
   that the outer function be partially expanded, then we switch to
50
   compiling the inner function, and once done with those we switch back
51
   to compiling the outer function.  Such delicate ordering requirements
52
   makes it difficult to do whole translation unit optimizations
53
   involving such functions.
54
 
55
   The implementation here is much more direct.  Everything that can be
56
   referenced by an inner function is a member of an explicitly created
57
   structure herein called the "nonlocal frame struct".  The incoming
58
   static chain for a nested function is a pointer to this struct in
59
   the parent.  In this way, we settle on known offsets from a known
60
   base, and so are decoupled from the logic that places objects in the
61
   function's stack frame.  More importantly, we don't have to wait for
62
   that to happen -- since the compilation of the inner function is no
63
   longer tied to a real stack frame, the nonlocal frame struct can be
64
   allocated anywhere.  Which means that the outer function is now
65
   inlinable.
66
 
67
   Theory of operation here is very simple.  Iterate over all the
68
   statements in all the functions (depth first) several times,
69
   allocating structures and fields on demand.  In general we want to
70
   examine inner functions first, so that we can avoid making changes
71
   to outer functions which are unnecessary.
72
 
73
   The order of the passes matters a bit, in that later passes will be
74
   skipped if it is discovered that the functions don't actually interact
75
   at all.  That is, they're nested in the lexical sense but could have
76
   been written as independent functions without change.  */
77
 
78
 
79
struct var_map_elt GTY(())
80
{
81
  tree old;
82
  tree new;
83
};
84
 
85
struct nesting_info GTY ((chain_next ("%h.next")))
86
{
87
  struct nesting_info *outer;
88
  struct nesting_info *inner;
89
  struct nesting_info *next;
90
 
91
  htab_t GTY ((param_is (struct var_map_elt))) field_map;
92
  htab_t GTY ((param_is (struct var_map_elt))) var_map;
93
  bitmap suppress_expansion;
94
 
95
  tree context;
96
  tree new_local_var_chain;
97
  tree debug_var_chain;
98
  tree frame_type;
99
  tree frame_decl;
100
  tree chain_field;
101
  tree chain_decl;
102
  tree nl_goto_field;
103
 
104
  bool any_parm_remapped;
105
  bool any_tramp_created;
106
  char static_chain_added;
107
};
108
 
109
 
110
/* Hashing and equality functions for nesting_info->var_map.  */
111
 
112
static hashval_t
113
var_map_hash (const void *x)
114
{
115
  const struct var_map_elt *a = (const struct var_map_elt *) x;
116
  return htab_hash_pointer (a->old);
117
}
118
 
119
static int
120
var_map_eq (const void *x, const void *y)
121
{
122
  const struct var_map_elt *a = (const struct var_map_elt *) x;
123
  const struct var_map_elt *b = (const struct var_map_elt *) y;
124
  return a->old == b->old;
125
}
126
 
127
/* We're working in so many different function contexts simultaneously,
128
   that create_tmp_var is dangerous.  Prevent mishap.  */
129
#define create_tmp_var cant_use_create_tmp_var_here_dummy
130
 
131
/* Like create_tmp_var, except record the variable for registration at
132
   the given nesting level.  */
133
 
134
static tree
135
create_tmp_var_for (struct nesting_info *info, tree type, const char *prefix)
136
{
137
  tree tmp_var;
138
 
139
  /* If the type is of variable size or a type which must be created by the
140
     frontend, something is wrong.  Note that we explicitly allow
141
     incomplete types here, since we create them ourselves here.  */
142
  gcc_assert (!TREE_ADDRESSABLE (type));
143
  gcc_assert (!TYPE_SIZE_UNIT (type)
144
              || TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST);
145
 
146
  tmp_var = create_tmp_var_raw (type, prefix);
147
  DECL_CONTEXT (tmp_var) = info->context;
148
  TREE_CHAIN (tmp_var) = info->new_local_var_chain;
149
  DECL_SEEN_IN_BIND_EXPR_P (tmp_var) = 1;
150
  if (TREE_CODE (type) == COMPLEX_TYPE)
151
    DECL_COMPLEX_GIMPLE_REG_P (tmp_var) = 1;
152
 
153
  info->new_local_var_chain = tmp_var;
154
 
155
  return tmp_var;
156
}
157
 
158
/* Take the address of EXP to be used within function CONTEXT.
159
   Mark it for addressability as necessary.  */
160
 
161
tree
162
build_addr (tree exp, tree context)
163
{
164
  tree base = exp;
165
  tree save_context;
166
  tree retval;
167
 
168
  while (handled_component_p (base))
169
    base = TREE_OPERAND (base, 0);
170
 
171
  if (DECL_P (base))
172
    TREE_ADDRESSABLE (base) = 1;
173
 
174
  /* Building the ADDR_EXPR will compute a set of properties for
175
     that ADDR_EXPR.  Those properties are unfortunately context
176
     specific.  ie, they are dependent on CURRENT_FUNCTION_DECL.
177
 
178
     Temporarily set CURRENT_FUNCTION_DECL to the desired context,
179
     build the ADDR_EXPR, then restore CURRENT_FUNCTION_DECL.  That
180
     way the properties are for the ADDR_EXPR are computed properly.  */
181
  save_context = current_function_decl;
182
  current_function_decl = context;
183
  retval = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (exp)), exp);
184
  current_function_decl = save_context;;
185
  return retval;
186
}
187
 
188
/* Insert FIELD into TYPE, sorted by alignment requirements.  */
189
 
190
void
191
insert_field_into_struct (tree type, tree field)
192
{
193
  tree *p;
194
 
195
  DECL_CONTEXT (field) = type;
196
 
197
  for (p = &TYPE_FIELDS (type); *p ; p = &TREE_CHAIN (*p))
198
    if (DECL_ALIGN (field) >= DECL_ALIGN (*p))
199
      break;
200
 
201
  TREE_CHAIN (field) = *p;
202
  *p = field;
203
}
204
 
205
/* Build or return the RECORD_TYPE that describes the frame state that is
206
   shared between INFO->CONTEXT and its nested functions.  This record will
207
   not be complete until finalize_nesting_tree; up until that point we'll
208
   be adding fields as necessary.
209
 
210
   We also build the DECL that represents this frame in the function.  */
211
 
212
static tree
213
get_frame_type (struct nesting_info *info)
214
{
215
  tree type = info->frame_type;
216
  if (!type)
217
    {
218
      char *name;
219
 
220
      type = make_node (RECORD_TYPE);
221
 
222
      name = concat ("FRAME.",
223
                     IDENTIFIER_POINTER (DECL_NAME (info->context)),
224
                     NULL);
225
      TYPE_NAME (type) = get_identifier (name);
226
      free (name);
227
 
228
      info->frame_type = type;
229
      info->frame_decl = create_tmp_var_for (info, type, "FRAME");
230
 
231
      /* ??? Always make it addressable for now, since it is meant to
232
         be pointed to by the static chain pointer.  This pessimizes
233
         when it turns out that no static chains are needed because
234
         the nested functions referencing non-local variables are not
235
         reachable, but the true pessimization is to create the non-
236
         local frame structure in the first place.  */
237
      TREE_ADDRESSABLE (info->frame_decl) = 1;
238
    }
239
  return type;
240
}
241
 
242
/* Return true if DECL should be referenced by pointer in the non-local
243
   frame structure.  */
244
 
245
static bool
246
use_pointer_in_frame (tree decl)
247
{
248
  if (TREE_CODE (decl) == PARM_DECL)
249
    {
250
      /* It's illegal to copy TREE_ADDRESSABLE, impossible to copy variable
251
         sized decls, and inefficient to copy large aggregates.  Don't bother
252
         moving anything but scalar variables.  */
253
      return AGGREGATE_TYPE_P (TREE_TYPE (decl));
254
    }
255
  else
256
    {
257
      /* Variable sized types make things "interesting" in the frame.  */
258
      return DECL_SIZE (decl) == NULL || !TREE_CONSTANT (DECL_SIZE (decl));
259
    }
260
}
261
 
262
/* Given DECL, a non-locally accessed variable, find or create a field
263
   in the non-local frame structure for the given nesting context.  */
264
 
265
static tree
266
lookup_field_for_decl (struct nesting_info *info, tree decl,
267
                       enum insert_option insert)
268
{
269
  struct var_map_elt *elt, dummy;
270
  void **slot;
271
  tree field;
272
 
273
  dummy.old = decl;
274
  slot = htab_find_slot (info->field_map, &dummy, insert);
275
  if (!slot)
276
    {
277
      gcc_assert (insert != INSERT);
278
      return NULL;
279
    }
280
  elt = (struct var_map_elt *) *slot;
281
 
282
  if (!elt && insert == INSERT)
283
    {
284
      field = make_node (FIELD_DECL);
285
      DECL_NAME (field) = DECL_NAME (decl);
286
 
287
      if (use_pointer_in_frame (decl))
288
        {
289
          TREE_TYPE (field) = build_pointer_type (TREE_TYPE (decl));
290
          DECL_ALIGN (field) = TYPE_ALIGN (TREE_TYPE (field));
291
          DECL_NONADDRESSABLE_P (field) = 1;
292
        }
293
      else
294
        {
295
          TREE_TYPE (field) = TREE_TYPE (decl);
296
          DECL_SOURCE_LOCATION (field) = DECL_SOURCE_LOCATION (decl);
297
          DECL_ALIGN (field) = DECL_ALIGN (decl);
298
          DECL_USER_ALIGN (field) = DECL_USER_ALIGN (decl);
299
          TREE_ADDRESSABLE (field) = TREE_ADDRESSABLE (decl);
300
          DECL_NONADDRESSABLE_P (field) = !TREE_ADDRESSABLE (decl);
301
          TREE_THIS_VOLATILE (field) = TREE_THIS_VOLATILE (decl);
302
        }
303
 
304
      insert_field_into_struct (get_frame_type (info), field);
305
 
306
      elt = GGC_NEW (struct var_map_elt);
307
      elt->old = decl;
308
      elt->new = field;
309
      *slot = elt;
310
 
311
      if (TREE_CODE (decl) == PARM_DECL)
312
        info->any_parm_remapped = true;
313
    }
314
  else
315
    field = elt ? elt->new : NULL;
316
 
317
  return field;
318
}
319
 
320
/* Build or return the variable that holds the static chain within
321
   INFO->CONTEXT.  This variable may only be used within INFO->CONTEXT.  */
322
 
323
static tree
324
get_chain_decl (struct nesting_info *info)
325
{
326
  tree decl = info->chain_decl;
327
  if (!decl)
328
    {
329
      tree type;
330
 
331
      type = get_frame_type (info->outer);
332
      type = build_pointer_type (type);
333
 
334
      /* Note that this variable is *not* entered into any BIND_EXPR;
335
         the construction of this variable is handled specially in
336
         expand_function_start and initialize_inlined_parameters.
337
         Note also that it's represented as a parameter.  This is more
338
         close to the truth, since the initial value does come from
339
         the caller.  */
340
      decl = build_decl (PARM_DECL, create_tmp_var_name ("CHAIN"), type);
341
      DECL_ARTIFICIAL (decl) = 1;
342
      DECL_IGNORED_P (decl) = 1;
343
      TREE_USED (decl) = 1;
344
      DECL_CONTEXT (decl) = info->context;
345
      DECL_ARG_TYPE (decl) = type;
346
 
347
      /* Tell tree-inline.c that we never write to this variable, so
348
         it can copy-prop the replacement value immediately.  */
349
      TREE_READONLY (decl) = 1;
350
 
351
      info->chain_decl = decl;
352
    }
353
  return decl;
354
}
355
 
356
/* Build or return the field within the non-local frame state that holds
357
   the static chain for INFO->CONTEXT.  This is the way to walk back up
358
   multiple nesting levels.  */
359
 
360
static tree
361
get_chain_field (struct nesting_info *info)
362
{
363
  tree field = info->chain_field;
364
  if (!field)
365
    {
366
      tree type = build_pointer_type (get_frame_type (info->outer));
367
 
368
      field = make_node (FIELD_DECL);
369
      DECL_NAME (field) = get_identifier ("__chain");
370
      TREE_TYPE (field) = type;
371
      DECL_ALIGN (field) = TYPE_ALIGN (type);
372
      DECL_NONADDRESSABLE_P (field) = 1;
373
 
374
      insert_field_into_struct (get_frame_type (info), field);
375
 
376
      info->chain_field = field;
377
    }
378
  return field;
379
}
380
 
381
/* Copy EXP into a temporary.  Allocate the temporary in the context of
382
   INFO and insert the initialization statement before TSI.  */
383
 
384
static tree
385
init_tmp_var (struct nesting_info *info, tree exp, tree_stmt_iterator *tsi)
386
{
387
  tree t, stmt;
388
 
389
  t = create_tmp_var_for (info, TREE_TYPE (exp), NULL);
390
  stmt = build2 (MODIFY_EXPR, TREE_TYPE (t), t, exp);
391
  SET_EXPR_LOCUS (stmt, EXPR_LOCUS (tsi_stmt (*tsi)));
392
  tsi_link_before (tsi, stmt, TSI_SAME_STMT);
393
 
394
  return t;
395
}
396
 
397
/* Similarly, but only do so to force EXP to satisfy is_gimple_val.  */
398
 
399
static tree
400
tsi_gimplify_val (struct nesting_info *info, tree exp, tree_stmt_iterator *tsi)
401
{
402
  if (is_gimple_val (exp))
403
    return exp;
404
  else
405
    return init_tmp_var (info, exp, tsi);
406
}
407
 
408
/* Similarly, but copy from the temporary and insert the statement
409
   after the iterator.  */
410
 
411
static tree
412
save_tmp_var (struct nesting_info *info, tree exp,
413
              tree_stmt_iterator *tsi)
414
{
415
  tree t, stmt;
416
 
417
  t = create_tmp_var_for (info, TREE_TYPE (exp), NULL);
418
  stmt = build2 (MODIFY_EXPR, TREE_TYPE (t), exp, t);
419
  SET_EXPR_LOCUS (stmt, EXPR_LOCUS (tsi_stmt (*tsi)));
420
  tsi_link_after (tsi, stmt, TSI_SAME_STMT);
421
 
422
  return t;
423
}
424
 
425
/* Build or return the type used to represent a nested function trampoline.  */
426
 
427
static GTY(()) tree trampoline_type;
428
 
429
static tree
430
get_trampoline_type (void)
431
{
432
  tree record, t;
433
  unsigned align, size;
434
 
435
  if (trampoline_type)
436
    return trampoline_type;
437
 
438
  align = TRAMPOLINE_ALIGNMENT;
439
  size = TRAMPOLINE_SIZE;
440
 
441
  /* If we won't be able to guarantee alignment simply via TYPE_ALIGN,
442
     then allocate extra space so that we can do dynamic alignment.  */
443
  if (align > STACK_BOUNDARY)
444
    {
445
      size += ((align/BITS_PER_UNIT) - 1) & -(STACK_BOUNDARY/BITS_PER_UNIT);
446
      align = STACK_BOUNDARY;
447
    }
448
 
449
  t = build_index_type (build_int_cst (NULL_TREE, size - 1));
450
  t = build_array_type (char_type_node, t);
451
  t = build_decl (FIELD_DECL, get_identifier ("__data"), t);
452
  DECL_ALIGN (t) = align;
453
  DECL_USER_ALIGN (t) = 1;
454
 
455
  record = make_node (RECORD_TYPE);
456
  TYPE_NAME (record) = get_identifier ("__builtin_trampoline");
457
  TYPE_FIELDS (record) = t;
458
  layout_type (record);
459
 
460
  return record;
461
}
462
 
463
/* Given DECL, a nested function, find or create a field in the non-local
464
   frame structure for a trampoline for this function.  */
465
 
466
static tree
467
lookup_tramp_for_decl (struct nesting_info *info, tree decl,
468
                       enum insert_option insert)
469
{
470
  struct var_map_elt *elt, dummy;
471
  void **slot;
472
  tree field;
473
 
474
  dummy.old = decl;
475
  slot = htab_find_slot (info->var_map, &dummy, insert);
476
  if (!slot)
477
    {
478
      gcc_assert (insert != INSERT);
479
      return NULL;
480
    }
481
  elt = (struct var_map_elt *) *slot;
482
 
483
  if (!elt && insert == INSERT)
484
    {
485
      field = make_node (FIELD_DECL);
486
      DECL_NAME (field) = DECL_NAME (decl);
487
      TREE_TYPE (field) = get_trampoline_type ();
488
      TREE_ADDRESSABLE (field) = 1;
489
 
490
      insert_field_into_struct (get_frame_type (info), field);
491
 
492
      elt = GGC_NEW (struct var_map_elt);
493
      elt->old = decl;
494
      elt->new = field;
495
      *slot = elt;
496
 
497
      info->any_tramp_created = true;
498
    }
499
  else
500
    field = elt ? elt->new : NULL;
501
 
502
  return field;
503
}
504
 
505
/* Build or return the field within the non-local frame state that holds
506
   the non-local goto "jmp_buf".  The buffer itself is maintained by the
507
   rtl middle-end as dynamic stack space is allocated.  */
508
 
509
static tree
510
get_nl_goto_field (struct nesting_info *info)
511
{
512
  tree field = info->nl_goto_field;
513
  if (!field)
514
    {
515
      unsigned size;
516
      tree type;
517
 
518
      /* For __builtin_nonlocal_goto, we need N words.  The first is the
519
         frame pointer, the rest is for the target's stack pointer save
520
         area.  The number of words is controlled by STACK_SAVEAREA_MODE;
521
         not the best interface, but it'll do for now.  */
522
      if (Pmode == ptr_mode)
523
        type = ptr_type_node;
524
      else
525
        type = lang_hooks.types.type_for_mode (Pmode, 1);
526
 
527
      size = GET_MODE_SIZE (STACK_SAVEAREA_MODE (SAVE_NONLOCAL));
528
      size = size / GET_MODE_SIZE (Pmode);
529
      size = size + 1;
530
 
531
      type = build_array_type
532
        (type, build_index_type (build_int_cst (NULL_TREE, size)));
533
 
534
      field = make_node (FIELD_DECL);
535
      DECL_NAME (field) = get_identifier ("__nl_goto_buf");
536
      TREE_TYPE (field) = type;
537
      DECL_ALIGN (field) = TYPE_ALIGN (type);
538
      TREE_ADDRESSABLE (field) = 1;
539
 
540
      insert_field_into_struct (get_frame_type (info), field);
541
 
542
      info->nl_goto_field = field;
543
    }
544
 
545
  return field;
546
}
547
 
548
/* Helper function for walk_stmts.  Walk output operands of an ASM_EXPR.  */
549
 
550
static void
551
walk_asm_expr (struct walk_stmt_info *wi, tree stmt)
552
{
553
  int noutputs = list_length (ASM_OUTPUTS (stmt));
554
  const char **oconstraints
555
    = (const char **) alloca ((noutputs) * sizeof (const char *));
556
  int i;
557
  tree link;
558
  const char *constraint;
559
  bool allows_mem, allows_reg, is_inout;
560
 
561
  wi->is_lhs = true;
562
  for (i=0, link = ASM_OUTPUTS (stmt); link; ++i, link = TREE_CHAIN (link))
563
    {
564
      constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
565
      oconstraints[i] = constraint;
566
      parse_output_constraint (&constraint, i, 0, 0, &allows_mem,
567
                               &allows_reg, &is_inout);
568
 
569
      wi->val_only = (allows_reg || !allows_mem);
570
      walk_tree (&TREE_VALUE (link), wi->callback, wi, NULL);
571
    }
572
 
573
  for (link = ASM_INPUTS (stmt); link; link = TREE_CHAIN (link))
574
    {
575
      constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
576
      parse_input_constraint (&constraint, 0, 0, noutputs, 0,
577
                              oconstraints, &allows_mem, &allows_reg);
578
 
579
      wi->val_only = (allows_reg || !allows_mem);
580
      /* Although input "m" is not really a LHS, we need a lvalue.  */
581
      wi->is_lhs = !wi->val_only;
582
      walk_tree (&TREE_VALUE (link), wi->callback, wi, NULL);
583
    }
584
 
585
  wi->is_lhs = false;
586
  wi->val_only = true;
587
}
588
 
589
/* Iterate over all sub-statements of *TP calling walk_tree with
590
   WI->CALLBACK for every sub-expression in each statement found.  */
591
 
592
void
593
walk_stmts (struct walk_stmt_info *wi, tree *tp)
594
{
595
  tree t = *tp;
596
  int walk_subtrees;
597
 
598
  if (!t)
599
    return;
600
 
601
  if (wi->want_locations && EXPR_HAS_LOCATION (t))
602
    input_location = EXPR_LOCATION (t);
603
 
604
  switch (TREE_CODE (t))
605
    {
606
    case STATEMENT_LIST:
607
      {
608
        tree_stmt_iterator i;
609
        for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
610
          {
611
            wi->tsi = i;
612
            walk_stmts (wi, tsi_stmt_ptr (i));
613
          }
614
      }
615
      break;
616
 
617
    case COND_EXPR:
618
      walk_tree (&COND_EXPR_COND (t), wi->callback, wi, NULL);
619
      walk_stmts (wi, &COND_EXPR_THEN (t));
620
      walk_stmts (wi, &COND_EXPR_ELSE (t));
621
      break;
622
    case CATCH_EXPR:
623
      walk_stmts (wi, &CATCH_BODY (t));
624
      break;
625
    case EH_FILTER_EXPR:
626
      walk_stmts (wi, &EH_FILTER_FAILURE (t));
627
      break;
628
    case TRY_CATCH_EXPR:
629
    case TRY_FINALLY_EXPR:
630
      walk_stmts (wi, &TREE_OPERAND (t, 0));
631
      walk_stmts (wi, &TREE_OPERAND (t, 1));
632
      break;
633
 
634
    case BIND_EXPR:
635
      if (wi->want_bind_expr)
636
        {
637
          walk_subtrees = 1;
638
          wi->callback (tp, &walk_subtrees, wi);
639
          if (!walk_subtrees)
640
            break;
641
        }
642
      walk_stmts (wi, &BIND_EXPR_BODY (t));
643
      break;
644
 
645
    case RETURN_EXPR:
646
      if (wi->want_return_expr)
647
        {
648
          walk_subtrees = 1;
649
          wi->callback (tp, &walk_subtrees, wi);
650
          if (!walk_subtrees)
651
            break;
652
        }
653
      walk_stmts (wi, &TREE_OPERAND (t, 0));
654
      break;
655
 
656
    case MODIFY_EXPR:
657
      /* A formal temporary lhs may use a COMPONENT_REF rhs.  */
658
      wi->val_only = !is_gimple_formal_tmp_var (TREE_OPERAND (t, 0));
659
      walk_tree (&TREE_OPERAND (t, 1), wi->callback, wi, NULL);
660
 
661
      /* If the rhs is appropriate for a memory, we may use a
662
         COMPONENT_REF on the lhs.  */
663
      wi->val_only = !is_gimple_mem_rhs (TREE_OPERAND (t, 1));
664
      wi->is_lhs = true;
665
      walk_tree (&TREE_OPERAND (t, 0), wi->callback, wi, NULL);
666
 
667
      wi->val_only = true;
668
      wi->is_lhs = false;
669
      break;
670
 
671
    case ASM_EXPR:
672
      walk_asm_expr (wi, *tp);
673
      break;
674
 
675
    default:
676
      wi->val_only = true;
677
      walk_tree (tp, wi->callback, wi, NULL);
678
      break;
679
    }
680
}
681
 
682
/* Invoke CALLBACK on all statements of *STMT_P.  */
683
 
684
static void
685
walk_body (walk_tree_fn callback, struct nesting_info *info, tree *stmt_p)
686
{
687
  struct walk_stmt_info wi;
688
 
689
  memset (&wi, 0, sizeof (wi));
690
  wi.callback = callback;
691
  wi.info = info;
692
  wi.val_only = true;
693
 
694
  walk_stmts (&wi, stmt_p);
695
}
696
 
697
/* Invoke CALLBACK on all statements of INFO->CONTEXT.  */
698
 
699
static inline void
700
walk_function (walk_tree_fn callback, struct nesting_info *info)
701
{
702
  walk_body (callback, info, &DECL_SAVED_TREE (info->context));
703
}
704
 
705
/* Similarly for ROOT and all functions nested underneath, depth first.  */
706
 
707
static void
708
walk_all_functions (walk_tree_fn callback, struct nesting_info *root)
709
{
710
  do
711
    {
712
      if (root->inner)
713
        walk_all_functions (callback, root->inner);
714
      walk_function (callback, root);
715
      root = root->next;
716
    }
717
  while (root);
718
}
719
 
720
/* We have to check for a fairly pathological case.  The operands of function
721
   nested function are to be interpreted in the context of the enclosing
722
   function.  So if any are variably-sized, they will get remapped when the
723
   enclosing function is inlined.  But that remapping would also have to be
724
   done in the types of the PARM_DECLs of the nested function, meaning the
725
   argument types of that function will disagree with the arguments in the
726
   calls to that function.  So we'd either have to make a copy of the nested
727
   function corresponding to each time the enclosing function was inlined or
728
   add a VIEW_CONVERT_EXPR to each such operand for each call to the nested
729
   function.  The former is not practical.  The latter would still require
730
   detecting this case to know when to add the conversions.  So, for now at
731
   least, we don't inline such an enclosing function.
732
 
733
   We have to do that check recursively, so here return indicating whether
734
   FNDECL has such a nested function.  ORIG_FN is the function we were
735
   trying to inline to use for checking whether any argument is variably
736
   modified by anything in it.
737
 
738
   It would be better to do this in tree-inline.c so that we could give
739
   the appropriate warning for why a function can't be inlined, but that's
740
   too late since the nesting structure has already been flattened and
741
   adding a flag just to record this fact seems a waste of a flag.  */
742
 
743
static bool
744
check_for_nested_with_variably_modified (tree fndecl, tree orig_fndecl)
745
{
746
  struct cgraph_node *cgn = cgraph_node (fndecl);
747
  tree arg;
748
 
749
  for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested)
750
    {
751
      for (arg = DECL_ARGUMENTS (cgn->decl); arg; arg = TREE_CHAIN (arg))
752
        if (variably_modified_type_p (TREE_TYPE (arg), 0), orig_fndecl)
753
          return true;
754
 
755
      if (check_for_nested_with_variably_modified (cgn->decl, orig_fndecl))
756
        return true;
757
    }
758
 
759
  return false;
760
}
761
 
762
/* Construct our local datastructure describing the function nesting
763
   tree rooted by CGN.  */
764
 
765
static struct nesting_info *
766
create_nesting_tree (struct cgraph_node *cgn)
767
{
768
  struct nesting_info *info = GGC_CNEW (struct nesting_info);
769
  info->field_map = htab_create_ggc (7, var_map_hash, var_map_eq, ggc_free);
770
  info->var_map = htab_create_ggc (7, var_map_hash, var_map_eq, ggc_free);
771
  info->suppress_expansion = BITMAP_GGC_ALLOC ();
772
  info->context = cgn->decl;
773
 
774
  for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested)
775
    {
776
      struct nesting_info *sub = create_nesting_tree (cgn);
777
      sub->outer = info;
778
      sub->next = info->inner;
779
      info->inner = sub;
780
    }
781
 
782
  /* See discussion at check_for_nested_with_variably_modified for a
783
     discussion of why this has to be here.  */
784
  if (check_for_nested_with_variably_modified (info->context, info->context))
785
    DECL_UNINLINABLE (info->context) = true;
786
 
787
  return info;
788
}
789
 
790
/* Return an expression computing the static chain for TARGET_CONTEXT
791
   from INFO->CONTEXT.  Insert any necessary computations before TSI.  */
792
 
793
static tree
794
get_static_chain (struct nesting_info *info, tree target_context,
795
                  tree_stmt_iterator *tsi)
796
{
797
  struct nesting_info *i;
798
  tree x;
799
 
800
  if (info->context == target_context)
801
    {
802
      x = build_addr (info->frame_decl, target_context);
803
    }
804
  else
805
    {
806
      x = get_chain_decl (info);
807
 
808
      for (i = info->outer; i->context != target_context; i = i->outer)
809
        {
810
          tree field = get_chain_field (i);
811
 
812
          x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
813
          x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
814
          x = init_tmp_var (info, x, tsi);
815
        }
816
    }
817
 
818
  return x;
819
}
820
 
821
/* Return an expression referencing FIELD from TARGET_CONTEXT's non-local
822
   frame as seen from INFO->CONTEXT.  Insert any necessary computations
823
   before TSI.  */
824
 
825
static tree
826
get_frame_field (struct nesting_info *info, tree target_context,
827
                 tree field, tree_stmt_iterator *tsi)
828
{
829
  struct nesting_info *i;
830
  tree x;
831
 
832
  if (info->context == target_context)
833
    {
834
      /* Make sure frame_decl gets created.  */
835
      (void) get_frame_type (info);
836
      x = info->frame_decl;
837
    }
838
  else
839
    {
840
      x = get_chain_decl (info);
841
 
842
      for (i = info->outer; i->context != target_context; i = i->outer)
843
        {
844
          tree field = get_chain_field (i);
845
 
846
          x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
847
          x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
848
          x = init_tmp_var (info, x, tsi);
849
        }
850
 
851
      x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
852
    }
853
 
854
  x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
855
  return x;
856
}
857
 
858
/* A subroutine of convert_nonlocal_reference.  Create a local variable
859
   in the nested function with DECL_VALUE_EXPR set to reference the true
860
   variable in the parent function.  This is used both for debug info
861
   and in OpenMP lowering.  */
862
 
863
static tree
864
get_nonlocal_debug_decl (struct nesting_info *info, tree decl)
865
{
866
  struct var_map_elt *elt, dummy;
867
  tree target_context;
868
  struct nesting_info *i;
869
  tree x, field, new_decl;
870
  void **slot;
871
 
872
  dummy.old = decl;
873
  slot = htab_find_slot (info->var_map, &dummy, INSERT);
874
  elt = *slot;
875
 
876
  if (elt)
877
    return elt->new;
878
 
879
  target_context = decl_function_context (decl);
880
 
881
  /* A copy of the code in get_frame_field, but without the temporaries.  */
882
  if (info->context == target_context)
883
    {
884
      /* Make sure frame_decl gets created.  */
885
      (void) get_frame_type (info);
886
      x = info->frame_decl;
887
      i = info;
888
    }
889
  else
890
    {
891
      x = get_chain_decl (info);
892
      for (i = info->outer; i->context != target_context; i = i->outer)
893
        {
894
          field = get_chain_field (i);
895
          x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
896
          x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
897
        }
898
      x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
899
    }
900
 
901
  field = lookup_field_for_decl (i, decl, INSERT);
902
  x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
903
  if (use_pointer_in_frame (decl))
904
    x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
905
 
906
  /* ??? We should be remapping types as well, surely.  */
907
  new_decl = build_decl (VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
908
  DECL_CONTEXT (new_decl) = info->context;
909
  DECL_SOURCE_LOCATION (new_decl) = DECL_SOURCE_LOCATION (decl);
910
  DECL_ARTIFICIAL (new_decl) = DECL_ARTIFICIAL (decl);
911
  DECL_IGNORED_P (new_decl) = DECL_IGNORED_P (decl);
912
  TREE_THIS_VOLATILE (new_decl) = TREE_THIS_VOLATILE (decl);
913
  TREE_SIDE_EFFECTS (new_decl) = TREE_SIDE_EFFECTS (decl);
914
  TREE_READONLY (new_decl) = TREE_READONLY (decl);
915
  TREE_ADDRESSABLE (new_decl) = TREE_ADDRESSABLE (decl);
916
  DECL_SEEN_IN_BIND_EXPR_P (new_decl) = 1;
917
 
918
  SET_DECL_VALUE_EXPR (new_decl, x);
919
  DECL_HAS_VALUE_EXPR_P (new_decl) = 1;
920
 
921
  elt = ggc_alloc (sizeof (*elt));
922
  elt->old = decl;
923
  elt->new = new_decl;
924
  *slot = elt;
925
 
926
  TREE_CHAIN (new_decl) = info->debug_var_chain;
927
  info->debug_var_chain = new_decl;
928
 
929
  return new_decl;
930
}
931
 
932
/* Called via walk_function+walk_tree, rewrite all references to VAR
933
   and PARM_DECLs that belong to outer functions.
934
 
935
   The rewrite will involve some number of structure accesses back up
936
   the static chain.  E.g. for a variable FOO up one nesting level it'll
937
   be CHAIN->FOO.  For two levels it'll be CHAIN->__chain->FOO.  Further
938
   indirections apply to decls for which use_pointer_in_frame is true.  */
939
 
940
static bool convert_nonlocal_omp_clauses (tree *, struct walk_stmt_info *);
941
 
942
static tree
943
convert_nonlocal_reference (tree *tp, int *walk_subtrees, void *data)
944
{
945
  struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
946
  struct nesting_info *info = wi->info;
947
  tree t = *tp;
948
  tree save_local_var_chain;
949
  bitmap save_suppress;
950
 
951
  *walk_subtrees = 0;
952
  switch (TREE_CODE (t))
953
    {
954
    case VAR_DECL:
955
      /* Non-automatic variables are never processed.  */
956
      if (TREE_STATIC (t) || DECL_EXTERNAL (t))
957
        break;
958
      /* FALLTHRU */
959
 
960
    case PARM_DECL:
961
      if (decl_function_context (t) != info->context)
962
        {
963
          tree x;
964
          wi->changed = true;
965
 
966
          x = get_nonlocal_debug_decl (info, t);
967
          if (!bitmap_bit_p (info->suppress_expansion, DECL_UID (t)))
968
            {
969
              tree target_context = decl_function_context (t);
970
              struct nesting_info *i;
971
              for (i = info->outer; i->context != target_context; i = i->outer)
972
                continue;
973
              x = lookup_field_for_decl (i, t, INSERT);
974
              x = get_frame_field (info, target_context, x, &wi->tsi);
975
              if (use_pointer_in_frame (t))
976
                {
977
                  x = init_tmp_var (info, x, &wi->tsi);
978
                  x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
979
                }
980
            }
981
 
982
          if (wi->val_only)
983
            {
984
              if (wi->is_lhs)
985
                x = save_tmp_var (info, x, &wi->tsi);
986
              else
987
                x = init_tmp_var (info, x, &wi->tsi);
988
            }
989
 
990
          *tp = x;
991
        }
992
      break;
993
 
994
    case GOTO_EXPR:
995
      /* Don't walk non-local gotos for now.  */
996
      if (TREE_CODE (GOTO_DESTINATION (t)) != LABEL_DECL)
997
        {
998
          *walk_subtrees = 1;
999
          wi->val_only = true;
1000
          wi->is_lhs = false;
1001
        }
1002
      break;
1003
 
1004
    case LABEL_DECL:
1005
      /* We're taking the address of a label from a parent function, but
1006
         this is not itself a non-local goto.  Mark the label such that it
1007
         will not be deleted, much as we would with a label address in
1008
         static storage.  */
1009
      if (decl_function_context (t) != info->context)
1010
        FORCED_LABEL (t) = 1;
1011
      break;
1012
 
1013
    case ADDR_EXPR:
1014
      {
1015
        bool save_val_only = wi->val_only;
1016
 
1017
        wi->val_only = false;
1018
        wi->is_lhs = false;
1019
        wi->changed = false;
1020
        walk_tree (&TREE_OPERAND (t, 0), convert_nonlocal_reference, wi, NULL);
1021
        wi->val_only = true;
1022
 
1023
        if (wi->changed)
1024
          {
1025
            tree save_context;
1026
 
1027
            /* If we changed anything, then TREE_INVARIANT is be wrong,
1028
               since we're no longer directly referencing a decl.  */
1029
            save_context = current_function_decl;
1030
            current_function_decl = info->context;
1031
            recompute_tree_invariant_for_addr_expr (t);
1032
            current_function_decl = save_context;
1033
 
1034
            /* If the callback converted the address argument in a context
1035
               where we only accept variables (and min_invariant, presumably),
1036
               then compute the address into a temporary.  */
1037
            if (save_val_only)
1038
              *tp = tsi_gimplify_val (wi->info, t, &wi->tsi);
1039
          }
1040
      }
1041
      break;
1042
 
1043
    case REALPART_EXPR:
1044
    case IMAGPART_EXPR:
1045
    case COMPONENT_REF:
1046
    case ARRAY_REF:
1047
    case ARRAY_RANGE_REF:
1048
    case BIT_FIELD_REF:
1049
      /* Go down this entire nest and just look at the final prefix and
1050
         anything that describes the references.  Otherwise, we lose track
1051
         of whether a NOP_EXPR or VIEW_CONVERT_EXPR needs a simple value.  */
1052
      wi->val_only = true;
1053
      wi->is_lhs = false;
1054
      for (; handled_component_p (t); tp = &TREE_OPERAND (t, 0), t = *tp)
1055
        {
1056
          if (TREE_CODE (t) == COMPONENT_REF)
1057
            walk_tree (&TREE_OPERAND (t, 2), convert_nonlocal_reference, wi,
1058
                       NULL);
1059
          else if (TREE_CODE (t) == ARRAY_REF
1060
                   || TREE_CODE (t) == ARRAY_RANGE_REF)
1061
            {
1062
              walk_tree (&TREE_OPERAND (t, 1), convert_nonlocal_reference, wi,
1063
                         NULL);
1064
              walk_tree (&TREE_OPERAND (t, 2), convert_nonlocal_reference, wi,
1065
                         NULL);
1066
              walk_tree (&TREE_OPERAND (t, 3), convert_nonlocal_reference, wi,
1067
                         NULL);
1068
            }
1069
          else if (TREE_CODE (t) == BIT_FIELD_REF)
1070
            {
1071
              walk_tree (&TREE_OPERAND (t, 1), convert_nonlocal_reference, wi,
1072
                         NULL);
1073
              walk_tree (&TREE_OPERAND (t, 2), convert_nonlocal_reference, wi,
1074
                         NULL);
1075
            }
1076
        }
1077
      wi->val_only = false;
1078
      walk_tree (tp, convert_nonlocal_reference, wi, NULL);
1079
      break;
1080
 
1081
    case OMP_PARALLEL:
1082
      save_suppress = info->suppress_expansion;
1083
      if (convert_nonlocal_omp_clauses (&OMP_PARALLEL_CLAUSES (t), wi))
1084
        {
1085
          tree c, decl;
1086
          decl = get_chain_decl (info);
1087
          c = build_omp_clause (OMP_CLAUSE_FIRSTPRIVATE);
1088
          OMP_CLAUSE_DECL (c) = decl;
1089
          OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (t);
1090
          OMP_PARALLEL_CLAUSES (t) = c;
1091
        }
1092
 
1093
      save_local_var_chain = info->new_local_var_chain;
1094
      info->new_local_var_chain = NULL;
1095
 
1096
      walk_body (convert_nonlocal_reference, info, &OMP_PARALLEL_BODY (t));
1097
 
1098
      if (info->new_local_var_chain)
1099
        declare_vars (info->new_local_var_chain, OMP_PARALLEL_BODY (t), false);
1100
      info->new_local_var_chain = save_local_var_chain;
1101
      info->suppress_expansion = save_suppress;
1102
      break;
1103
 
1104
    case OMP_FOR:
1105
    case OMP_SECTIONS:
1106
    case OMP_SINGLE:
1107
      save_suppress = info->suppress_expansion;
1108
      convert_nonlocal_omp_clauses (&OMP_CLAUSES (t), wi);
1109
      walk_body (convert_nonlocal_reference, info, &OMP_BODY (t));
1110
      info->suppress_expansion = save_suppress;
1111
      break;
1112
 
1113
    case OMP_SECTION:
1114
    case OMP_MASTER:
1115
    case OMP_ORDERED:
1116
      walk_body (convert_nonlocal_reference, info, &OMP_BODY (t));
1117
      break;
1118
 
1119
    default:
1120
      if (!IS_TYPE_OR_DECL_P (t))
1121
        {
1122
          *walk_subtrees = 1;
1123
          wi->val_only = true;
1124
          wi->is_lhs = false;
1125
        }
1126
      break;
1127
    }
1128
 
1129
  return NULL_TREE;
1130
}
1131
 
1132
static bool
1133
convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
1134
{
1135
  struct nesting_info *info = wi->info;
1136
  bool need_chain = false;
1137
  tree clause, decl;
1138
  int dummy;
1139
  bitmap new_suppress;
1140
 
1141
  new_suppress = BITMAP_GGC_ALLOC ();
1142
  bitmap_copy (new_suppress, info->suppress_expansion);
1143
 
1144
  for (clause = *pclauses; clause ; clause = OMP_CLAUSE_CHAIN (clause))
1145
    {
1146
      switch (OMP_CLAUSE_CODE (clause))
1147
        {
1148
        case OMP_CLAUSE_PRIVATE:
1149
        case OMP_CLAUSE_FIRSTPRIVATE:
1150
        case OMP_CLAUSE_LASTPRIVATE:
1151
        case OMP_CLAUSE_REDUCTION:
1152
        case OMP_CLAUSE_COPYPRIVATE:
1153
        case OMP_CLAUSE_SHARED:
1154
          decl = OMP_CLAUSE_DECL (clause);
1155
          if (decl_function_context (decl) != info->context)
1156
            {
1157
              bitmap_set_bit (new_suppress, DECL_UID (decl));
1158
              OMP_CLAUSE_DECL (clause) = get_nonlocal_debug_decl (info, decl);
1159
              need_chain = true;
1160
            }
1161
          break;
1162
 
1163
        case OMP_CLAUSE_SCHEDULE:
1164
          if (OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (clause) == NULL)
1165
            break;
1166
          /* FALLTHRU */
1167
        case OMP_CLAUSE_IF:
1168
        case OMP_CLAUSE_NUM_THREADS:
1169
          wi->val_only = true;
1170
          wi->is_lhs = false;
1171
          convert_nonlocal_reference (&OMP_CLAUSE_OPERAND (clause, 0), &dummy,
1172
                                      wi);
1173
          break;
1174
 
1175
        case OMP_CLAUSE_NOWAIT:
1176
        case OMP_CLAUSE_ORDERED:
1177
        case OMP_CLAUSE_DEFAULT:
1178
        case OMP_CLAUSE_COPYIN:
1179
          break;
1180
 
1181
        default:
1182
          gcc_unreachable ();
1183
        }
1184
    }
1185
 
1186
  info->suppress_expansion = new_suppress;
1187
 
1188
  return need_chain;
1189
}
1190
 
1191
/* A subroutine of convert_local_reference.  Create a local variable
1192
   in the parent function with DECL_VALUE_EXPR set to reference the
1193
   field in FRAME.  This is used both for debug info and in OpenMP
1194
   lowering.  */
1195
 
1196
static tree
1197
get_local_debug_decl (struct nesting_info *info, tree decl, tree field)
1198
{
1199
  struct var_map_elt *elt, dummy;
1200
  tree x, new_decl;
1201
  void **slot;
1202
 
1203
  dummy.old = decl;
1204
  slot = htab_find_slot (info->var_map, &dummy, INSERT);
1205
  elt = *slot;
1206
 
1207
  if (elt)
1208
    return elt->new;
1209
 
1210
  /* Make sure frame_decl gets created.  */
1211
  (void) get_frame_type (info);
1212
  x = info->frame_decl;
1213
  x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
1214
 
1215
  new_decl = build_decl (VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
1216
  DECL_CONTEXT (new_decl) = info->context;
1217
  DECL_SOURCE_LOCATION (new_decl) = DECL_SOURCE_LOCATION (decl);
1218
  DECL_ARTIFICIAL (new_decl) = DECL_ARTIFICIAL (decl);
1219
  DECL_IGNORED_P (new_decl) = DECL_IGNORED_P (decl);
1220
  TREE_THIS_VOLATILE (new_decl) = TREE_THIS_VOLATILE (decl);
1221
  TREE_SIDE_EFFECTS (new_decl) = TREE_SIDE_EFFECTS (decl);
1222
  TREE_READONLY (new_decl) = TREE_READONLY (decl);
1223
  TREE_ADDRESSABLE (new_decl) = TREE_ADDRESSABLE (decl);
1224
  DECL_SEEN_IN_BIND_EXPR_P (new_decl) = 1;
1225
 
1226
  SET_DECL_VALUE_EXPR (new_decl, x);
1227
  DECL_HAS_VALUE_EXPR_P (new_decl) = 1;
1228
 
1229
  elt = ggc_alloc (sizeof (*elt));
1230
  elt->old = decl;
1231
  elt->new = new_decl;
1232
  *slot = elt;
1233
 
1234
  TREE_CHAIN (new_decl) = info->debug_var_chain;
1235
  info->debug_var_chain = new_decl;
1236
 
1237
  /* Do not emit debug info twice.  */
1238
  DECL_IGNORED_P (decl) = 1;
1239
 
1240
  return new_decl;
1241
}
1242
 
1243
/* Called via walk_function+walk_tree, rewrite all references to VAR
1244
   and PARM_DECLs that were referenced by inner nested functions.
1245
   The rewrite will be a structure reference to the local frame variable.  */
1246
 
1247
static bool convert_local_omp_clauses (tree *, struct walk_stmt_info *);
1248
 
1249
static tree
1250
convert_local_reference (tree *tp, int *walk_subtrees, void *data)
1251
{
1252
  struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
1253
  struct nesting_info *info = wi->info;
1254
  tree t = *tp, field, x;
1255
  bool save_val_only;
1256
  tree save_local_var_chain;
1257
  bitmap save_suppress;
1258
 
1259
  *walk_subtrees = 0;
1260
  switch (TREE_CODE (t))
1261
    {
1262
    case VAR_DECL:
1263
      /* Non-automatic variables are never processed.  */
1264
      if (TREE_STATIC (t) || DECL_EXTERNAL (t))
1265
        break;
1266
      /* FALLTHRU */
1267
 
1268
    case PARM_DECL:
1269
      if (decl_function_context (t) == info->context)
1270
        {
1271
          /* If we copied a pointer to the frame, then the original decl
1272
             is used unchanged in the parent function.  */
1273
          if (use_pointer_in_frame (t))
1274
            break;
1275
 
1276
          /* No need to transform anything if no child references the
1277
             variable.  */
1278
          field = lookup_field_for_decl (info, t, NO_INSERT);
1279
          if (!field)
1280
            break;
1281
          wi->changed = true;
1282
 
1283
          x = get_local_debug_decl (info, t, field);
1284
          if (!bitmap_bit_p (info->suppress_expansion, DECL_UID (t)))
1285
            x = get_frame_field (info, info->context, field, &wi->tsi);
1286
 
1287
          if (wi->val_only)
1288
            {
1289
              if (wi->is_lhs)
1290
                x = save_tmp_var (info, x, &wi->tsi);
1291
              else
1292
                x = init_tmp_var (info, x, &wi->tsi);
1293
            }
1294
 
1295
          *tp = x;
1296
        }
1297
      break;
1298
 
1299
    case ADDR_EXPR:
1300
      save_val_only = wi->val_only;
1301
      wi->val_only = false;
1302
      wi->is_lhs = false;
1303
      wi->changed = false;
1304
      walk_tree (&TREE_OPERAND (t, 0), convert_local_reference, wi, NULL);
1305
      wi->val_only = save_val_only;
1306
 
1307
      /* If we converted anything ... */
1308
      if (wi->changed)
1309
        {
1310
          tree save_context;
1311
 
1312
          /* Then the frame decl is now addressable.  */
1313
          TREE_ADDRESSABLE (info->frame_decl) = 1;
1314
 
1315
          save_context = current_function_decl;
1316
          current_function_decl = info->context;
1317
          recompute_tree_invariant_for_addr_expr (t);
1318
          current_function_decl = save_context;
1319
 
1320
          /* If we are in a context where we only accept values, then
1321
             compute the address into a temporary.  */
1322
          if (save_val_only)
1323
            *tp = tsi_gimplify_val (wi->info, t, &wi->tsi);
1324
        }
1325
      break;
1326
 
1327
    case REALPART_EXPR:
1328
    case IMAGPART_EXPR:
1329
    case COMPONENT_REF:
1330
    case ARRAY_REF:
1331
    case ARRAY_RANGE_REF:
1332
    case BIT_FIELD_REF:
1333
      /* Go down this entire nest and just look at the final prefix and
1334
         anything that describes the references.  Otherwise, we lose track
1335
         of whether a NOP_EXPR or VIEW_CONVERT_EXPR needs a simple value.  */
1336
      save_val_only = wi->val_only;
1337
      wi->val_only = true;
1338
      wi->is_lhs = false;
1339
      for (; handled_component_p (t); tp = &TREE_OPERAND (t, 0), t = *tp)
1340
        {
1341
          if (TREE_CODE (t) == COMPONENT_REF)
1342
            walk_tree (&TREE_OPERAND (t, 2), convert_local_reference, wi,
1343
                       NULL);
1344
          else if (TREE_CODE (t) == ARRAY_REF
1345
                   || TREE_CODE (t) == ARRAY_RANGE_REF)
1346
            {
1347
              walk_tree (&TREE_OPERAND (t, 1), convert_local_reference, wi,
1348
                         NULL);
1349
              walk_tree (&TREE_OPERAND (t, 2), convert_local_reference, wi,
1350
                         NULL);
1351
              walk_tree (&TREE_OPERAND (t, 3), convert_local_reference, wi,
1352
                         NULL);
1353
            }
1354
          else if (TREE_CODE (t) == BIT_FIELD_REF)
1355
            {
1356
              walk_tree (&TREE_OPERAND (t, 1), convert_local_reference, wi,
1357
                         NULL);
1358
              walk_tree (&TREE_OPERAND (t, 2), convert_local_reference, wi,
1359
                         NULL);
1360
            }
1361
        }
1362
      wi->val_only = false;
1363
      walk_tree (tp, convert_local_reference, wi, NULL);
1364
      wi->val_only = save_val_only;
1365
      break;
1366
 
1367
    case OMP_PARALLEL:
1368
      save_suppress = info->suppress_expansion;
1369
      if (convert_local_omp_clauses (&OMP_PARALLEL_CLAUSES (t), wi))
1370
        {
1371
          tree c;
1372
          (void) get_frame_type (info);
1373
          c = build_omp_clause (OMP_CLAUSE_SHARED);
1374
          OMP_CLAUSE_DECL (c) = info->frame_decl;
1375
          OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (t);
1376
          OMP_PARALLEL_CLAUSES (t) = c;
1377
        }
1378
 
1379
      save_local_var_chain = info->new_local_var_chain;
1380
      info->new_local_var_chain = NULL;
1381
 
1382
      walk_body (convert_local_reference, info, &OMP_PARALLEL_BODY (t));
1383
 
1384
      if (info->new_local_var_chain)
1385
        declare_vars (info->new_local_var_chain, OMP_PARALLEL_BODY (t), false);
1386
      info->new_local_var_chain = save_local_var_chain;
1387
      info->suppress_expansion = save_suppress;
1388
      break;
1389
 
1390
    case OMP_FOR:
1391
    case OMP_SECTIONS:
1392
    case OMP_SINGLE:
1393
      save_suppress = info->suppress_expansion;
1394
      convert_local_omp_clauses (&OMP_CLAUSES (t), wi);
1395
      walk_body (convert_local_reference, info, &OMP_BODY (t));
1396
      info->suppress_expansion = save_suppress;
1397
      break;
1398
 
1399
    case OMP_SECTION:
1400
    case OMP_MASTER:
1401
    case OMP_ORDERED:
1402
      walk_body (convert_local_reference, info, &OMP_BODY (t));
1403
      break;
1404
 
1405
    default:
1406
      if (!IS_TYPE_OR_DECL_P (t))
1407
        {
1408
          *walk_subtrees = 1;
1409
          wi->val_only = true;
1410
          wi->is_lhs = false;
1411
        }
1412
      break;
1413
    }
1414
 
1415
  return NULL_TREE;
1416
}
1417
 
1418
static bool
1419
convert_local_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
1420
{
1421
  struct nesting_info *info = wi->info;
1422
  bool need_frame = false;
1423
  tree clause, decl;
1424
  int dummy;
1425
  bitmap new_suppress;
1426
 
1427
  new_suppress = BITMAP_GGC_ALLOC ();
1428
  bitmap_copy (new_suppress, info->suppress_expansion);
1429
 
1430
  for (clause = *pclauses; clause ; clause = OMP_CLAUSE_CHAIN (clause))
1431
    {
1432
      switch (OMP_CLAUSE_CODE (clause))
1433
        {
1434
        case OMP_CLAUSE_PRIVATE:
1435
        case OMP_CLAUSE_FIRSTPRIVATE:
1436
        case OMP_CLAUSE_LASTPRIVATE:
1437
        case OMP_CLAUSE_REDUCTION:
1438
        case OMP_CLAUSE_COPYPRIVATE:
1439
        case OMP_CLAUSE_SHARED:
1440
          decl = OMP_CLAUSE_DECL (clause);
1441
          if (decl_function_context (decl) == info->context
1442
              && !use_pointer_in_frame (decl))
1443
            {
1444
              tree field = lookup_field_for_decl (info, decl, NO_INSERT);
1445
              if (field)
1446
                {
1447
                  bitmap_set_bit (new_suppress, DECL_UID (decl));
1448
                  OMP_CLAUSE_DECL (clause)
1449
                    = get_local_debug_decl (info, decl, field);
1450
                  need_frame = true;
1451
                }
1452
            }
1453
          break;
1454
 
1455
        case OMP_CLAUSE_SCHEDULE:
1456
          if (OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (clause) == NULL)
1457
            break;
1458
          /* FALLTHRU */
1459
        case OMP_CLAUSE_IF:
1460
        case OMP_CLAUSE_NUM_THREADS:
1461
          wi->val_only = true;
1462
          wi->is_lhs = false;
1463
          convert_local_reference (&OMP_CLAUSE_OPERAND (clause, 0), &dummy, wi);
1464
          break;
1465
 
1466
        case OMP_CLAUSE_NOWAIT:
1467
        case OMP_CLAUSE_ORDERED:
1468
        case OMP_CLAUSE_DEFAULT:
1469
        case OMP_CLAUSE_COPYIN:
1470
          break;
1471
 
1472
        default:
1473
          gcc_unreachable ();
1474
        }
1475
    }
1476
 
1477
  info->suppress_expansion = new_suppress;
1478
 
1479
  return need_frame;
1480
}
1481
 
1482
/* Called via walk_function+walk_tree, rewrite all GOTO_EXPRs that
1483
   reference labels from outer functions.  The rewrite will be a
1484
   call to __builtin_nonlocal_goto.  */
1485
 
1486
static tree
1487
convert_nl_goto_reference (tree *tp, int *walk_subtrees, void *data)
1488
{
1489
  struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
1490
  struct nesting_info *info = wi->info, *i;
1491
  tree t = *tp, label, new_label, target_context, x, arg, field;
1492
  struct var_map_elt *elt, dummy;
1493
  void **slot;
1494
 
1495
  *walk_subtrees = 0;
1496
  if (TREE_CODE (t) != GOTO_EXPR)
1497
    return NULL_TREE;
1498
  label = GOTO_DESTINATION (t);
1499
  if (TREE_CODE (label) != LABEL_DECL)
1500
    return NULL_TREE;
1501
  target_context = decl_function_context (label);
1502
  if (target_context == info->context)
1503
    return NULL_TREE;
1504
 
1505
  for (i = info->outer; target_context != i->context; i = i->outer)
1506
    continue;
1507
 
1508
  /* The original user label may also be use for a normal goto, therefore
1509
     we must create a new label that will actually receive the abnormal
1510
     control transfer.  This new label will be marked LABEL_NONLOCAL; this
1511
     mark will trigger proper behavior in the cfg, as well as cause the
1512
     (hairy target-specific) non-local goto receiver code to be generated
1513
     when we expand rtl.  Enter this association into var_map so that we
1514
     can insert the new label into the IL during a second pass.  */
1515
  dummy.old = label;
1516
  slot = htab_find_slot (i->var_map, &dummy, INSERT);
1517
  elt = (struct var_map_elt *) *slot;
1518
  if (elt == NULL)
1519
    {
1520
      new_label = create_artificial_label ();
1521
      DECL_NONLOCAL (new_label) = 1;
1522
 
1523
      elt = GGC_NEW (struct var_map_elt);
1524
      elt->old = label;
1525
      elt->new = new_label;
1526
      *slot = elt;
1527
    }
1528
  else
1529
    new_label = elt->new;
1530
 
1531
  /* Build: __builtin_nl_goto(new_label, &chain->nl_goto_field).  */
1532
  field = get_nl_goto_field (i);
1533
  x = get_frame_field (info, target_context, field, &wi->tsi);
1534
  x = build_addr (x, target_context);
1535
  x = tsi_gimplify_val (info, x, &wi->tsi);
1536
  arg = tree_cons (NULL, x, NULL);
1537
  x = build_addr (new_label, target_context);
1538
  arg = tree_cons (NULL, x, arg);
1539
  x = implicit_built_in_decls[BUILT_IN_NONLOCAL_GOTO];
1540
  x = build_function_call_expr (x, arg);
1541
 
1542
  SET_EXPR_LOCUS (x, EXPR_LOCUS (tsi_stmt (wi->tsi)));
1543
  *tsi_stmt_ptr (wi->tsi) = x;
1544
 
1545
  return NULL_TREE;
1546
}
1547
 
1548
/* Called via walk_function+walk_tree, rewrite all LABEL_EXPRs that
1549
   are referenced via nonlocal goto from a nested function.  The rewrite
1550
   will involve installing a newly generated DECL_NONLOCAL label, and
1551
   (potentially) a branch around the rtl gunk that is assumed to be
1552
   attached to such a label.  */
1553
 
1554
static tree
1555
convert_nl_goto_receiver (tree *tp, int *walk_subtrees, void *data)
1556
{
1557
  struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
1558
  struct nesting_info *info = wi->info;
1559
  tree t = *tp, label, new_label, x;
1560
  struct var_map_elt *elt, dummy;
1561
  tree_stmt_iterator tmp_tsi;
1562
 
1563
  *walk_subtrees = 0;
1564
  if (TREE_CODE (t) != LABEL_EXPR)
1565
    return NULL_TREE;
1566
  label = LABEL_EXPR_LABEL (t);
1567
 
1568
  dummy.old = label;
1569
  elt = (struct var_map_elt *) htab_find (info->var_map, &dummy);
1570
  if (!elt)
1571
    return NULL_TREE;
1572
  new_label = elt->new;
1573
 
1574
  /* If there's any possibility that the previous statement falls through,
1575
     then we must branch around the new non-local label.  */
1576
  tmp_tsi = wi->tsi;
1577
  tsi_prev (&tmp_tsi);
1578
  if (tsi_end_p (tmp_tsi) || block_may_fallthru (tsi_stmt (tmp_tsi)))
1579
    {
1580
      x = build1 (GOTO_EXPR, void_type_node, label);
1581
      tsi_link_before (&wi->tsi, x, TSI_SAME_STMT);
1582
    }
1583
  x = build1 (LABEL_EXPR, void_type_node, new_label);
1584
  tsi_link_before (&wi->tsi, x, TSI_SAME_STMT);
1585
 
1586
  return NULL_TREE;
1587
}
1588
 
1589
/* Called via walk_function+walk_tree, rewrite all references to addresses
1590
   of nested functions that require the use of trampolines.  The rewrite
1591
   will involve a reference a trampoline generated for the occasion.  */
1592
 
1593
static tree
1594
convert_tramp_reference (tree *tp, int *walk_subtrees, void *data)
1595
{
1596
  struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
1597
  struct nesting_info *info = wi->info, *i;
1598
  tree t = *tp, decl, target_context, x, arg;
1599
 
1600
  *walk_subtrees = 0;
1601
  switch (TREE_CODE (t))
1602
    {
1603
    case ADDR_EXPR:
1604
      /* Build
1605
           T.1 = &CHAIN->tramp;
1606
           T.2 = __builtin_adjust_trampoline (T.1);
1607
           T.3 = (func_type)T.2;
1608
      */
1609
 
1610
      decl = TREE_OPERAND (t, 0);
1611
      if (TREE_CODE (decl) != FUNCTION_DECL)
1612
        break;
1613
 
1614
      /* Only need to process nested functions.  */
1615
      target_context = decl_function_context (decl);
1616
      if (!target_context)
1617
        break;
1618
 
1619
      /* If the nested function doesn't use a static chain, then
1620
         it doesn't need a trampoline.  */
1621
      if (DECL_NO_STATIC_CHAIN (decl))
1622
        break;
1623
 
1624
      /* Lookup the immediate parent of the callee, as that's where
1625
         we need to insert the trampoline.  */
1626
      for (i = info; i->context != target_context; i = i->outer)
1627
        continue;
1628
      x = lookup_tramp_for_decl (i, decl, INSERT);
1629
 
1630
      /* Compute the address of the field holding the trampoline.  */
1631
      x = get_frame_field (info, target_context, x, &wi->tsi);
1632
      x = build_addr (x, target_context);
1633
      x = tsi_gimplify_val (info, x, &wi->tsi);
1634
      arg = tree_cons (NULL, x, NULL);
1635
 
1636
      /* Do machine-specific ugliness.  Normally this will involve
1637
         computing extra alignment, but it can really be anything.  */
1638
      x = implicit_built_in_decls[BUILT_IN_ADJUST_TRAMPOLINE];
1639
      x = build_function_call_expr (x, arg);
1640
      x = init_tmp_var (info, x, &wi->tsi);
1641
 
1642
      /* Cast back to the proper function type.  */
1643
      x = build1 (NOP_EXPR, TREE_TYPE (t), x);
1644
      x = init_tmp_var (info, x, &wi->tsi);
1645
 
1646
      *tp = x;
1647
      break;
1648
 
1649
    case CALL_EXPR:
1650
      /* Only walk call arguments, lest we generate trampolines for
1651
         direct calls.  */
1652
      walk_tree (&TREE_OPERAND (t, 1), convert_tramp_reference, wi, NULL);
1653
      break;
1654
 
1655
    default:
1656
      if (!IS_TYPE_OR_DECL_P (t))
1657
        *walk_subtrees = 1;
1658
      break;
1659
    }
1660
 
1661
  return NULL_TREE;
1662
}
1663
 
1664
/* Called via walk_function+walk_tree, rewrite all CALL_EXPRs that
1665
   reference nested functions to make sure that the static chain is
1666
   set up properly for the call.  */
1667
 
1668
static tree
1669
convert_call_expr (tree *tp, int *walk_subtrees, void *data)
1670
{
1671
  struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
1672
  struct nesting_info *info = wi->info;
1673
  tree t = *tp, decl, target_context;
1674
  char save_static_chain_added;
1675
  int i;
1676
 
1677
  *walk_subtrees = 0;
1678
  switch (TREE_CODE (t))
1679
    {
1680
    case CALL_EXPR:
1681
      decl = get_callee_fndecl (t);
1682
      if (!decl)
1683
        break;
1684
      target_context = decl_function_context (decl);
1685
      if (target_context && !DECL_NO_STATIC_CHAIN (decl))
1686
        {
1687
          TREE_OPERAND (t, 2)
1688
            = get_static_chain (info, target_context, &wi->tsi);
1689
          info->static_chain_added
1690
            |= (1 << (info->context != target_context));
1691
        }
1692
      break;
1693
 
1694
    case RETURN_EXPR:
1695
    case MODIFY_EXPR:
1696
    case WITH_SIZE_EXPR:
1697
      /* Only return modify and with_size_expr may contain calls.  */
1698
      *walk_subtrees = 1;
1699
      break;
1700
 
1701
    case OMP_PARALLEL:
1702
      save_static_chain_added = info->static_chain_added;
1703
      info->static_chain_added = 0;
1704
      walk_body (convert_call_expr, info, &OMP_PARALLEL_BODY (t));
1705
      for (i = 0; i < 2; i++)
1706
        {
1707
          tree c, decl;
1708
          if ((info->static_chain_added & (1 << i)) == 0)
1709
            continue;
1710
          decl = i ? get_chain_decl (info) : info->frame_decl;
1711
          /* Don't add CHAIN.* or FRAME.* twice.  */
1712
          for (c = OMP_PARALLEL_CLAUSES (t); c; c = OMP_CLAUSE_CHAIN (c))
1713
            if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
1714
                 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED)
1715
                && OMP_CLAUSE_DECL (c) == decl)
1716
              break;
1717
          if (c == NULL)
1718
            {
1719
              c = build_omp_clause (OMP_CLAUSE_FIRSTPRIVATE);
1720
              OMP_CLAUSE_DECL (c) = decl;
1721
              OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (t);
1722
              OMP_PARALLEL_CLAUSES (t) = c;
1723
            }
1724
        }
1725
      info->static_chain_added |= save_static_chain_added;
1726
      break;
1727
 
1728
    case OMP_FOR:
1729
    case OMP_SECTIONS:
1730
    case OMP_SECTION:
1731
    case OMP_SINGLE:
1732
    case OMP_MASTER:
1733
    case OMP_ORDERED:
1734
    case OMP_CRITICAL:
1735
      walk_body (convert_call_expr, info, &OMP_BODY (t));
1736
      break;
1737
 
1738
    default:
1739
      break;
1740
    }
1741
 
1742
  return NULL_TREE;
1743
}
1744
 
1745
/* Walk the nesting tree starting with ROOT, depth first.  Convert all
1746
   trampolines and call expressions.  On the way back up, determine if
1747
   a nested function actually uses its static chain; if not, remember that.  */
1748
 
1749
static void
1750
convert_all_function_calls (struct nesting_info *root)
1751
{
1752
  do
1753
    {
1754
      if (root->inner)
1755
        convert_all_function_calls (root->inner);
1756
 
1757
      walk_function (convert_tramp_reference, root);
1758
      walk_function (convert_call_expr, root);
1759
 
1760
      /* If the function does not use a static chain, then remember that.  */
1761
      if (root->outer && !root->chain_decl && !root->chain_field)
1762
        DECL_NO_STATIC_CHAIN (root->context) = 1;
1763
      else
1764
        gcc_assert (!DECL_NO_STATIC_CHAIN (root->context));
1765
 
1766
      root = root->next;
1767
    }
1768
  while (root);
1769
}
1770
 
1771
/* Do "everything else" to clean up or complete state collected by the
1772
   various walking passes -- lay out the types and decls, generate code
1773
   to initialize the frame decl, store critical expressions in the
1774
   struct function for rtl to find.  */
1775
 
1776
static void
1777
finalize_nesting_tree_1 (struct nesting_info *root)
1778
{
1779
  tree stmt_list = NULL;
1780
  tree context = root->context;
1781
  struct function *sf;
1782
 
1783
  /* If we created a non-local frame type or decl, we need to lay them
1784
     out at this time.  */
1785
  if (root->frame_type)
1786
    {
1787
      /* In some cases the frame type will trigger the -Wpadded warning.
1788
         This is not helpful; suppress it. */
1789
      int save_warn_padded = warn_padded;
1790
      warn_padded = 0;
1791
      layout_type (root->frame_type);
1792
      warn_padded = save_warn_padded;
1793
      layout_decl (root->frame_decl, 0);
1794
    }
1795
 
1796
  /* If any parameters were referenced non-locally, then we need to
1797
     insert a copy.  Likewise, if any variables were referenced by
1798
     pointer, we need to initialize the address.  */
1799
  if (root->any_parm_remapped)
1800
    {
1801
      tree p;
1802
      for (p = DECL_ARGUMENTS (context); p ; p = TREE_CHAIN (p))
1803
        {
1804
          tree field, x, y;
1805
 
1806
          field = lookup_field_for_decl (root, p, NO_INSERT);
1807
          if (!field)
1808
            continue;
1809
 
1810
          if (use_pointer_in_frame (p))
1811
            x = build_addr (p, context);
1812
          else
1813
            x = p;
1814
 
1815
          y = build3 (COMPONENT_REF, TREE_TYPE (field),
1816
                      root->frame_decl, field, NULL_TREE);
1817
          x = build2 (MODIFY_EXPR, TREE_TYPE (field), y, x);
1818
          append_to_statement_list (x, &stmt_list);
1819
        }
1820
    }
1821
 
1822
  /* If a chain_field was created, then it needs to be initialized
1823
     from chain_decl.  */
1824
  if (root->chain_field)
1825
    {
1826
      tree x = build3 (COMPONENT_REF, TREE_TYPE (root->chain_field),
1827
                       root->frame_decl, root->chain_field, NULL_TREE);
1828
      x = build2 (MODIFY_EXPR, TREE_TYPE (x), x, get_chain_decl (root));
1829
      append_to_statement_list (x, &stmt_list);
1830
    }
1831
 
1832
  /* If trampolines were created, then we need to initialize them.  */
1833
  if (root->any_tramp_created)
1834
    {
1835
      struct nesting_info *i;
1836
      for (i = root->inner; i ; i = i->next)
1837
        {
1838
          tree arg, x, field;
1839
 
1840
          field = lookup_tramp_for_decl (root, i->context, NO_INSERT);
1841
          if (!field)
1842
            continue;
1843
 
1844
          if (DECL_NO_STATIC_CHAIN (i->context))
1845
            x = null_pointer_node;
1846
          else
1847
            x = build_addr (root->frame_decl, context);
1848
          arg = tree_cons (NULL, x, NULL);
1849
 
1850
          x = build_addr (i->context, context);
1851
          arg = tree_cons (NULL, x, arg);
1852
 
1853
          x = build3 (COMPONENT_REF, TREE_TYPE (field),
1854
                      root->frame_decl, field, NULL_TREE);
1855
          x = build_addr (x, context);
1856
          arg = tree_cons (NULL, x, arg);
1857
 
1858
          x = implicit_built_in_decls[BUILT_IN_INIT_TRAMPOLINE];
1859
          x = build_function_call_expr (x, arg);
1860
 
1861
          append_to_statement_list (x, &stmt_list);
1862
        }
1863
    }
1864
 
1865
  /* If we created initialization statements, insert them.  */
1866
  if (stmt_list)
1867
    {
1868
      annotate_all_with_locus (&stmt_list,
1869
                               DECL_SOURCE_LOCATION (context));
1870
      append_to_statement_list (BIND_EXPR_BODY (DECL_SAVED_TREE (context)),
1871
                                &stmt_list);
1872
      BIND_EXPR_BODY (DECL_SAVED_TREE (context)) = stmt_list;
1873
    }
1874
 
1875
  /* If a chain_decl was created, then it needs to be registered with
1876
     struct function so that it gets initialized from the static chain
1877
     register at the beginning of the function.  */
1878
  sf = DECL_STRUCT_FUNCTION (root->context);
1879
  sf->static_chain_decl = root->chain_decl;
1880
 
1881
  /* Similarly for the non-local goto save area.  */
1882
  if (root->nl_goto_field)
1883
    {
1884
      sf->nonlocal_goto_save_area
1885
        = get_frame_field (root, context, root->nl_goto_field, NULL);
1886
      sf->has_nonlocal_label = 1;
1887
    }
1888
 
1889
  /* Make sure all new local variables get inserted into the
1890
     proper BIND_EXPR.  */
1891
  if (root->new_local_var_chain)
1892
    declare_vars (root->new_local_var_chain, DECL_SAVED_TREE (root->context),
1893
                  false);
1894
  if (root->debug_var_chain)
1895
    declare_vars (root->debug_var_chain, DECL_SAVED_TREE (root->context),
1896
                  true);
1897
 
1898
  /* Dump the translated tree function.  */
1899
  dump_function (TDI_nested, root->context);
1900
}
1901
 
1902
static void
1903
finalize_nesting_tree (struct nesting_info *root)
1904
{
1905
  do
1906
    {
1907
      if (root->inner)
1908
        finalize_nesting_tree (root->inner);
1909
      finalize_nesting_tree_1 (root);
1910
      root = root->next;
1911
    }
1912
  while (root);
1913
}
1914
 
1915
/* Unnest the nodes and pass them to cgraph.  */
1916
 
1917
static void
1918
unnest_nesting_tree_1 (struct nesting_info *root)
1919
{
1920
  struct cgraph_node *node = cgraph_node (root->context);
1921
 
1922
  /* For nested functions update the cgraph to reflect unnesting.
1923
     We also delay finalizing of these functions up to this point.  */
1924
  if (node->origin)
1925
    {
1926
       cgraph_unnest_node (cgraph_node (root->context));
1927
       cgraph_finalize_function (root->context, true);
1928
    }
1929
}
1930
 
1931
static void
1932
unnest_nesting_tree (struct nesting_info *root)
1933
{
1934
  do
1935
    {
1936
      if (root->inner)
1937
        unnest_nesting_tree (root->inner);
1938
      unnest_nesting_tree_1 (root);
1939
      root = root->next;
1940
    }
1941
  while (root);
1942
}
1943
 
1944
/* Free the data structures allocated during this pass.  */
1945
 
1946
static void
1947
free_nesting_tree (struct nesting_info *root)
1948
{
1949
  struct nesting_info *next;
1950
  do
1951
    {
1952
      if (root->inner)
1953
        free_nesting_tree (root->inner);
1954
      htab_delete (root->var_map);
1955
      next = root->next;
1956
      ggc_free (root);
1957
      root = next;
1958
    }
1959
  while (root);
1960
}
1961
 
1962
static GTY(()) struct nesting_info *root;
1963
 
1964
/* Main entry point for this pass.  Process FNDECL and all of its nested
1965
   subroutines and turn them into something less tightly bound.  */
1966
 
1967
void
1968
lower_nested_functions (tree fndecl)
1969
{
1970
  struct cgraph_node *cgn;
1971
 
1972
  /* If there are no nested functions, there's nothing to do.  */
1973
  cgn = cgraph_node (fndecl);
1974
  if (!cgn->nested)
1975
    return;
1976
 
1977
  root = create_nesting_tree (cgn);
1978
  walk_all_functions (convert_nonlocal_reference, root);
1979
  walk_all_functions (convert_local_reference, root);
1980
  walk_all_functions (convert_nl_goto_reference, root);
1981
  walk_all_functions (convert_nl_goto_receiver, root);
1982
  convert_all_function_calls (root);
1983
  finalize_nesting_tree (root);
1984
  unnest_nesting_tree (root);
1985
  free_nesting_tree (root);
1986
  root = NULL;
1987
}
1988
 
1989
#include "gt-tree-nested.h"

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.