1 /* Nested function decomposition for trees.
2 Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
4 This file is part of GCC.
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 2, or (at your option)
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.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING. If not, write to
18 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA. */
23 #include "coretypes.h"
29 #include "tree-dump.h"
30 #include "tree-inline.h"
31 #include "tree-gimple.h"
32 #include "tree-iterator.h"
33 #include "tree-flow.h"
36 #include "langhooks.h"
37 #include "pointer-set.h"
41 /* The object of this pass is to lower the representation of a set of nested
42 functions in order to expose all of the gory details of the various
43 nonlocal references. We want to do this sooner rather than later, in
44 order to give us more freedom in emitting all of the functions in question.
46 Back in olden times, when gcc was young, we developed an insanely
47 complicated scheme whereby variables which were referenced nonlocally
48 were forced to live in the stack of the declaring function, and then
49 the nested functions magically discovered where these variables were
50 placed. In order for this scheme to function properly, it required
51 that the outer function be partially expanded, then we switch to
52 compiling the inner function, and once done with those we switch back
53 to compiling the outer function. Such delicate ordering requirements
54 makes it difficult to do whole translation unit optimizations
55 involving such functions.
57 The implementation here is much more direct. Everything that can be
58 referenced by an inner function is a member of an explicitly created
59 structure herein called the "nonlocal frame struct". The incoming
60 static chain for a nested function is a pointer to this struct in
61 the parent. In this way, we settle on known offsets from a known
62 base, and so are decoupled from the logic that places objects in the
63 function's stack frame. More importantly, we don't have to wait for
64 that to happen -- since the compilation of the inner function is no
65 longer tied to a real stack frame, the nonlocal frame struct can be
66 allocated anywhere. Which means that the outer function is now
69 Theory of operation here is very simple. Iterate over all the
70 statements in all the functions (depth first) several times,
71 allocating structures and fields on demand. In general we want to
72 examine inner functions first, so that we can avoid making changes
73 to outer functions which are unnecessary.
75 The order of the passes matters a bit, in that later passes will be
76 skipped if it is discovered that the functions don't actually interact
77 at all. That is, they're nested in the lexical sense but could have
78 been written as independent functions without change. */
83 struct nesting_info
*outer
;
84 struct nesting_info
*inner
;
85 struct nesting_info
*next
;
87 struct pointer_map_t
*field_map
;
88 struct pointer_map_t
*var_map
;
89 bitmap suppress_expansion
;
92 tree new_local_var_chain
;
100 bool any_parm_remapped
;
101 bool any_tramp_created
;
102 char static_chain_added
;
106 /* Obstack used for the bitmaps in the struct above. */
107 static struct bitmap_obstack nesting_info_bitmap_obstack
;
110 /* We're working in so many different function contexts simultaneously,
111 that create_tmp_var is dangerous. Prevent mishap. */
112 #define create_tmp_var cant_use_create_tmp_var_here_dummy
114 /* Like create_tmp_var, except record the variable for registration at
115 the given nesting level. */
118 create_tmp_var_for (struct nesting_info
*info
, tree type
, const char *prefix
)
122 /* If the type is of variable size or a type which must be created by the
123 frontend, something is wrong. Note that we explicitly allow
124 incomplete types here, since we create them ourselves here. */
125 gcc_assert (!TREE_ADDRESSABLE (type
));
126 gcc_assert (!TYPE_SIZE_UNIT (type
)
127 || TREE_CODE (TYPE_SIZE_UNIT (type
)) == INTEGER_CST
);
129 tmp_var
= create_tmp_var_raw (type
, prefix
);
130 DECL_CONTEXT (tmp_var
) = info
->context
;
131 TREE_CHAIN (tmp_var
) = info
->new_local_var_chain
;
132 DECL_SEEN_IN_BIND_EXPR_P (tmp_var
) = 1;
133 if (TREE_CODE (type
) == COMPLEX_TYPE
134 || TREE_CODE (type
) == VECTOR_TYPE
)
135 DECL_GIMPLE_REG_P (tmp_var
) = 1;
137 info
->new_local_var_chain
= tmp_var
;
142 /* Take the address of EXP to be used within function CONTEXT.
143 Mark it for addressability as necessary. */
146 build_addr (tree exp
, tree context
)
152 while (handled_component_p (base
))
153 base
= TREE_OPERAND (base
, 0);
156 TREE_ADDRESSABLE (base
) = 1;
158 /* Building the ADDR_EXPR will compute a set of properties for
159 that ADDR_EXPR. Those properties are unfortunately context
160 specific. ie, they are dependent on CURRENT_FUNCTION_DECL.
162 Temporarily set CURRENT_FUNCTION_DECL to the desired context,
163 build the ADDR_EXPR, then restore CURRENT_FUNCTION_DECL. That
164 way the properties are for the ADDR_EXPR are computed properly. */
165 save_context
= current_function_decl
;
166 current_function_decl
= context
;
167 retval
= build1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (exp
)), exp
);
168 current_function_decl
= save_context
;
172 /* Insert FIELD into TYPE, sorted by alignment requirements. */
175 insert_field_into_struct (tree type
, tree field
)
179 DECL_CONTEXT (field
) = type
;
181 for (p
= &TYPE_FIELDS (type
); *p
; p
= &TREE_CHAIN (*p
))
182 if (DECL_ALIGN (field
) >= DECL_ALIGN (*p
))
185 TREE_CHAIN (field
) = *p
;
189 /* Build or return the RECORD_TYPE that describes the frame state that is
190 shared between INFO->CONTEXT and its nested functions. This record will
191 not be complete until finalize_nesting_tree; up until that point we'll
192 be adding fields as necessary.
194 We also build the DECL that represents this frame in the function. */
197 get_frame_type (struct nesting_info
*info
)
199 tree type
= info
->frame_type
;
204 type
= make_node (RECORD_TYPE
);
206 name
= concat ("FRAME.",
207 IDENTIFIER_POINTER (DECL_NAME (info
->context
)),
209 TYPE_NAME (type
) = get_identifier (name
);
212 info
->frame_type
= type
;
213 info
->frame_decl
= create_tmp_var_for (info
, type
, "FRAME");
215 /* ??? Always make it addressable for now, since it is meant to
216 be pointed to by the static chain pointer. This pessimizes
217 when it turns out that no static chains are needed because
218 the nested functions referencing non-local variables are not
219 reachable, but the true pessimization is to create the non-
220 local frame structure in the first place. */
221 TREE_ADDRESSABLE (info
->frame_decl
) = 1;
226 /* Return true if DECL should be referenced by pointer in the non-local
230 use_pointer_in_frame (tree decl
)
232 if (TREE_CODE (decl
) == PARM_DECL
)
234 /* It's illegal to copy TREE_ADDRESSABLE, impossible to copy variable
235 sized decls, and inefficient to copy large aggregates. Don't bother
236 moving anything but scalar variables. */
237 return AGGREGATE_TYPE_P (TREE_TYPE (decl
));
241 /* Variable sized types make things "interesting" in the frame. */
242 return DECL_SIZE (decl
) == NULL
|| !TREE_CONSTANT (DECL_SIZE (decl
));
246 /* Given DECL, a non-locally accessed variable, find or create a field
247 in the non-local frame structure for the given nesting context. */
250 lookup_field_for_decl (struct nesting_info
*info
, tree decl
,
251 enum insert_option insert
)
255 if (insert
== NO_INSERT
)
257 slot
= pointer_map_contains (info
->field_map
, decl
);
258 return slot
? *slot
: NULL
;
261 slot
= pointer_map_insert (info
->field_map
, decl
);
264 tree field
= make_node (FIELD_DECL
);
265 DECL_NAME (field
) = DECL_NAME (decl
);
267 if (use_pointer_in_frame (decl
))
269 TREE_TYPE (field
) = build_pointer_type (TREE_TYPE (decl
));
270 DECL_ALIGN (field
) = TYPE_ALIGN (TREE_TYPE (field
));
271 DECL_NONADDRESSABLE_P (field
) = 1;
275 TREE_TYPE (field
) = TREE_TYPE (decl
);
276 DECL_SOURCE_LOCATION (field
) = DECL_SOURCE_LOCATION (decl
);
277 DECL_ALIGN (field
) = DECL_ALIGN (decl
);
278 DECL_USER_ALIGN (field
) = DECL_USER_ALIGN (decl
);
279 TREE_ADDRESSABLE (field
) = TREE_ADDRESSABLE (decl
);
280 DECL_NONADDRESSABLE_P (field
) = !TREE_ADDRESSABLE (decl
);
281 TREE_THIS_VOLATILE (field
) = TREE_THIS_VOLATILE (decl
);
284 insert_field_into_struct (get_frame_type (info
), field
);
287 if (TREE_CODE (decl
) == PARM_DECL
)
288 info
->any_parm_remapped
= true;
294 /* Build or return the variable that holds the static chain within
295 INFO->CONTEXT. This variable may only be used within INFO->CONTEXT. */
298 get_chain_decl (struct nesting_info
*info
)
300 tree decl
= info
->chain_decl
;
305 type
= get_frame_type (info
->outer
);
306 type
= build_pointer_type (type
);
308 /* Note that this variable is *not* entered into any BIND_EXPR;
309 the construction of this variable is handled specially in
310 expand_function_start and initialize_inlined_parameters.
311 Note also that it's represented as a parameter. This is more
312 close to the truth, since the initial value does come from
314 decl
= build_decl (PARM_DECL
, create_tmp_var_name ("CHAIN"), type
);
315 DECL_ARTIFICIAL (decl
) = 1;
316 DECL_IGNORED_P (decl
) = 1;
317 TREE_USED (decl
) = 1;
318 DECL_CONTEXT (decl
) = info
->context
;
319 DECL_ARG_TYPE (decl
) = type
;
321 /* Tell tree-inline.c that we never write to this variable, so
322 it can copy-prop the replacement value immediately. */
323 TREE_READONLY (decl
) = 1;
325 info
->chain_decl
= decl
;
330 /* Build or return the field within the non-local frame state that holds
331 the static chain for INFO->CONTEXT. This is the way to walk back up
332 multiple nesting levels. */
335 get_chain_field (struct nesting_info
*info
)
337 tree field
= info
->chain_field
;
340 tree type
= build_pointer_type (get_frame_type (info
->outer
));
342 field
= make_node (FIELD_DECL
);
343 DECL_NAME (field
) = get_identifier ("__chain");
344 TREE_TYPE (field
) = type
;
345 DECL_ALIGN (field
) = TYPE_ALIGN (type
);
346 DECL_NONADDRESSABLE_P (field
) = 1;
348 insert_field_into_struct (get_frame_type (info
), field
);
350 info
->chain_field
= field
;
355 /* Copy EXP into a temporary. Allocate the temporary in the context of
356 INFO and insert the initialization statement before TSI. */
359 init_tmp_var (struct nesting_info
*info
, tree exp
, tree_stmt_iterator
*tsi
)
363 t
= create_tmp_var_for (info
, TREE_TYPE (exp
), NULL
);
364 stmt
= build2 (GIMPLE_MODIFY_STMT
, TREE_TYPE (t
), t
, exp
);
365 SET_EXPR_LOCUS (stmt
, EXPR_LOCUS (tsi_stmt (*tsi
)));
366 tsi_link_before (tsi
, stmt
, TSI_SAME_STMT
);
371 /* Similarly, but only do so to force EXP to satisfy is_gimple_val. */
374 tsi_gimplify_val (struct nesting_info
*info
, tree exp
, tree_stmt_iterator
*tsi
)
376 if (is_gimple_val (exp
))
379 return init_tmp_var (info
, exp
, tsi
);
382 /* Similarly, but copy from the temporary and insert the statement
383 after the iterator. */
386 save_tmp_var (struct nesting_info
*info
, tree exp
,
387 tree_stmt_iterator
*tsi
)
391 t
= create_tmp_var_for (info
, TREE_TYPE (exp
), NULL
);
392 stmt
= build2 (GIMPLE_MODIFY_STMT
, TREE_TYPE (t
), exp
, t
);
393 SET_EXPR_LOCUS (stmt
, EXPR_LOCUS (tsi_stmt (*tsi
)));
394 tsi_link_after (tsi
, stmt
, TSI_SAME_STMT
);
399 /* Build or return the type used to represent a nested function trampoline. */
401 static GTY(()) tree trampoline_type
;
404 get_trampoline_type (void)
407 unsigned align
, size
;
410 return trampoline_type
;
412 align
= TRAMPOLINE_ALIGNMENT
;
413 size
= TRAMPOLINE_SIZE
;
415 /* If we won't be able to guarantee alignment simply via TYPE_ALIGN,
416 then allocate extra space so that we can do dynamic alignment. */
417 if (align
> STACK_BOUNDARY
)
419 size
+= ((align
/BITS_PER_UNIT
) - 1) & -(STACK_BOUNDARY
/BITS_PER_UNIT
);
420 align
= STACK_BOUNDARY
;
423 t
= build_index_type (build_int_cst (NULL_TREE
, size
- 1));
424 t
= build_array_type (char_type_node
, t
);
425 t
= build_decl (FIELD_DECL
, get_identifier ("__data"), t
);
426 DECL_ALIGN (t
) = align
;
427 DECL_USER_ALIGN (t
) = 1;
429 record
= make_node (RECORD_TYPE
);
430 TYPE_NAME (record
) = get_identifier ("__builtin_trampoline");
431 TYPE_FIELDS (record
) = t
;
432 layout_type (record
);
437 /* Given DECL, a nested function, find or create a field in the non-local
438 frame structure for a trampoline for this function. */
441 lookup_tramp_for_decl (struct nesting_info
*info
, tree decl
,
442 enum insert_option insert
)
446 if (insert
== NO_INSERT
)
448 slot
= pointer_map_contains (info
->var_map
, decl
);
449 return slot
? *slot
: NULL
;
452 slot
= pointer_map_insert (info
->var_map
, decl
);
455 tree field
= make_node (FIELD_DECL
);
456 DECL_NAME (field
) = DECL_NAME (decl
);
457 TREE_TYPE (field
) = get_trampoline_type ();
458 TREE_ADDRESSABLE (field
) = 1;
460 insert_field_into_struct (get_frame_type (info
), field
);
463 info
->any_tramp_created
= true;
469 /* Build or return the field within the non-local frame state that holds
470 the non-local goto "jmp_buf". The buffer itself is maintained by the
471 rtl middle-end as dynamic stack space is allocated. */
474 get_nl_goto_field (struct nesting_info
*info
)
476 tree field
= info
->nl_goto_field
;
482 /* For __builtin_nonlocal_goto, we need N words. The first is the
483 frame pointer, the rest is for the target's stack pointer save
484 area. The number of words is controlled by STACK_SAVEAREA_MODE;
485 not the best interface, but it'll do for now. */
486 if (Pmode
== ptr_mode
)
487 type
= ptr_type_node
;
489 type
= lang_hooks
.types
.type_for_mode (Pmode
, 1);
491 size
= GET_MODE_SIZE (STACK_SAVEAREA_MODE (SAVE_NONLOCAL
));
492 size
= size
/ GET_MODE_SIZE (Pmode
);
495 type
= build_array_type
496 (type
, build_index_type (build_int_cst (NULL_TREE
, size
)));
498 field
= make_node (FIELD_DECL
);
499 DECL_NAME (field
) = get_identifier ("__nl_goto_buf");
500 TREE_TYPE (field
) = type
;
501 DECL_ALIGN (field
) = TYPE_ALIGN (type
);
502 TREE_ADDRESSABLE (field
) = 1;
504 insert_field_into_struct (get_frame_type (info
), field
);
506 info
->nl_goto_field
= field
;
512 /* Helper function for walk_stmts. Walk output operands of an ASM_EXPR. */
515 walk_asm_expr (struct walk_stmt_info
*wi
, tree stmt
)
517 int noutputs
= list_length (ASM_OUTPUTS (stmt
));
518 const char **oconstraints
519 = (const char **) alloca ((noutputs
) * sizeof (const char *));
522 const char *constraint
;
523 bool allows_mem
, allows_reg
, is_inout
;
526 for (i
=0, link
= ASM_OUTPUTS (stmt
); link
; ++i
, link
= TREE_CHAIN (link
))
528 constraint
= TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link
)));
529 oconstraints
[i
] = constraint
;
530 parse_output_constraint (&constraint
, i
, 0, 0, &allows_mem
,
531 &allows_reg
, &is_inout
);
533 wi
->val_only
= (allows_reg
|| !allows_mem
);
534 walk_tree (&TREE_VALUE (link
), wi
->callback
, wi
, NULL
);
537 for (link
= ASM_INPUTS (stmt
); link
; link
= TREE_CHAIN (link
))
539 constraint
= TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link
)));
540 parse_input_constraint (&constraint
, 0, 0, noutputs
, 0,
541 oconstraints
, &allows_mem
, &allows_reg
);
543 wi
->val_only
= (allows_reg
|| !allows_mem
);
544 /* Although input "m" is not really a LHS, we need a lvalue. */
545 wi
->is_lhs
= !wi
->val_only
;
546 walk_tree (&TREE_VALUE (link
), wi
->callback
, wi
, NULL
);
553 /* Iterate over all sub-statements of *TP calling walk_tree with
554 WI->CALLBACK for every sub-expression in each statement found. */
557 walk_stmts (struct walk_stmt_info
*wi
, tree
*tp
)
565 if (wi
->want_locations
&& EXPR_HAS_LOCATION (t
))
566 input_location
= EXPR_LOCATION (t
);
568 switch (TREE_CODE (t
))
572 tree_stmt_iterator i
;
573 for (i
= tsi_start (t
); !tsi_end_p (i
); tsi_next (&i
))
576 walk_stmts (wi
, tsi_stmt_ptr (i
));
582 walk_tree (&COND_EXPR_COND (t
), wi
->callback
, wi
, NULL
);
583 walk_stmts (wi
, &COND_EXPR_THEN (t
));
584 walk_stmts (wi
, &COND_EXPR_ELSE (t
));
587 walk_stmts (wi
, &CATCH_BODY (t
));
590 walk_stmts (wi
, &EH_FILTER_FAILURE (t
));
593 case TRY_FINALLY_EXPR
:
594 walk_stmts (wi
, &TREE_OPERAND (t
, 0));
595 walk_stmts (wi
, &TREE_OPERAND (t
, 1));
599 if (wi
->want_bind_expr
)
602 wi
->callback (tp
, &walk_subtrees
, wi
);
606 walk_stmts (wi
, &BIND_EXPR_BODY (t
));
610 if (wi
->want_return_expr
)
613 wi
->callback (tp
, &walk_subtrees
, wi
);
617 walk_stmts (wi
, &TREE_OPERAND (t
, 0));
620 case GIMPLE_MODIFY_STMT
:
621 /* A formal temporary lhs may use a COMPONENT_REF rhs. */
622 wi
->val_only
= !is_gimple_formal_tmp_var (GIMPLE_STMT_OPERAND (t
, 0));
623 walk_tree (&GIMPLE_STMT_OPERAND (t
, 1), wi
->callback
, wi
, NULL
);
625 /* If the rhs is appropriate for a memory, we may use a
626 COMPONENT_REF on the lhs. */
627 wi
->val_only
= !is_gimple_mem_rhs (GIMPLE_STMT_OPERAND (t
, 1));
629 walk_tree (&GIMPLE_STMT_OPERAND (t
, 0), wi
->callback
, wi
, NULL
);
636 walk_asm_expr (wi
, *tp
);
641 walk_tree (tp
, wi
->callback
, wi
, NULL
);
646 /* Invoke CALLBACK on all statements of *STMT_P. */
649 walk_body (walk_tree_fn callback
, struct nesting_info
*info
, tree
*stmt_p
)
651 struct walk_stmt_info wi
;
653 memset (&wi
, 0, sizeof (wi
));
654 wi
.callback
= callback
;
658 walk_stmts (&wi
, stmt_p
);
661 /* Invoke CALLBACK on all statements of INFO->CONTEXT. */
664 walk_function (walk_tree_fn callback
, struct nesting_info
*info
)
666 walk_body (callback
, info
, &DECL_SAVED_TREE (info
->context
));
669 /* Similarly for ROOT and all functions nested underneath, depth first. */
672 walk_all_functions (walk_tree_fn callback
, struct nesting_info
*root
)
677 walk_all_functions (callback
, root
->inner
);
678 walk_function (callback
, root
);
684 /* We have to check for a fairly pathological case. The operands of function
685 nested function are to be interpreted in the context of the enclosing
686 function. So if any are variably-sized, they will get remapped when the
687 enclosing function is inlined. But that remapping would also have to be
688 done in the types of the PARM_DECLs of the nested function, meaning the
689 argument types of that function will disagree with the arguments in the
690 calls to that function. So we'd either have to make a copy of the nested
691 function corresponding to each time the enclosing function was inlined or
692 add a VIEW_CONVERT_EXPR to each such operand for each call to the nested
693 function. The former is not practical. The latter would still require
694 detecting this case to know when to add the conversions. So, for now at
695 least, we don't inline such an enclosing function.
697 We have to do that check recursively, so here return indicating whether
698 FNDECL has such a nested function. ORIG_FN is the function we were
699 trying to inline to use for checking whether any argument is variably
700 modified by anything in it.
702 It would be better to do this in tree-inline.c so that we could give
703 the appropriate warning for why a function can't be inlined, but that's
704 too late since the nesting structure has already been flattened and
705 adding a flag just to record this fact seems a waste of a flag. */
708 check_for_nested_with_variably_modified (tree fndecl
, tree orig_fndecl
)
710 struct cgraph_node
*cgn
= cgraph_node (fndecl
);
713 for (cgn
= cgn
->nested
; cgn
; cgn
= cgn
->next_nested
)
715 for (arg
= DECL_ARGUMENTS (cgn
->decl
); arg
; arg
= TREE_CHAIN (arg
))
716 if (variably_modified_type_p (TREE_TYPE (arg
), 0), orig_fndecl
)
719 if (check_for_nested_with_variably_modified (cgn
->decl
, orig_fndecl
))
726 /* Construct our local datastructure describing the function nesting
727 tree rooted by CGN. */
729 static struct nesting_info
*
730 create_nesting_tree (struct cgraph_node
*cgn
)
732 struct nesting_info
*info
= XCNEW (struct nesting_info
);
733 info
->field_map
= pointer_map_create ();
734 info
->var_map
= pointer_map_create ();
735 info
->suppress_expansion
= BITMAP_ALLOC (&nesting_info_bitmap_obstack
);
736 info
->context
= cgn
->decl
;
738 for (cgn
= cgn
->nested
; cgn
; cgn
= cgn
->next_nested
)
740 struct nesting_info
*sub
= create_nesting_tree (cgn
);
742 sub
->next
= info
->inner
;
746 /* See discussion at check_for_nested_with_variably_modified for a
747 discussion of why this has to be here. */
748 if (check_for_nested_with_variably_modified (info
->context
, info
->context
))
749 DECL_UNINLINABLE (info
->context
) = true;
754 /* Return an expression computing the static chain for TARGET_CONTEXT
755 from INFO->CONTEXT. Insert any necessary computations before TSI. */
758 get_static_chain (struct nesting_info
*info
, tree target_context
,
759 tree_stmt_iterator
*tsi
)
761 struct nesting_info
*i
;
764 if (info
->context
== target_context
)
766 x
= build_addr (info
->frame_decl
, target_context
);
770 x
= get_chain_decl (info
);
772 for (i
= info
->outer
; i
->context
!= target_context
; i
= i
->outer
)
774 tree field
= get_chain_field (i
);
776 x
= build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (x
)), x
);
777 x
= build3 (COMPONENT_REF
, TREE_TYPE (field
), x
, field
, NULL_TREE
);
778 x
= init_tmp_var (info
, x
, tsi
);
785 /* Return an expression referencing FIELD from TARGET_CONTEXT's non-local
786 frame as seen from INFO->CONTEXT. Insert any necessary computations
790 get_frame_field (struct nesting_info
*info
, tree target_context
,
791 tree field
, tree_stmt_iterator
*tsi
)
793 struct nesting_info
*i
;
796 if (info
->context
== target_context
)
798 /* Make sure frame_decl gets created. */
799 (void) get_frame_type (info
);
800 x
= info
->frame_decl
;
804 x
= get_chain_decl (info
);
806 for (i
= info
->outer
; i
->context
!= target_context
; i
= i
->outer
)
808 tree field
= get_chain_field (i
);
810 x
= build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (x
)), x
);
811 x
= build3 (COMPONENT_REF
, TREE_TYPE (field
), x
, field
, NULL_TREE
);
812 x
= init_tmp_var (info
, x
, tsi
);
815 x
= build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (x
)), x
);
818 x
= build3 (COMPONENT_REF
, TREE_TYPE (field
), x
, field
, NULL_TREE
);
822 /* A subroutine of convert_nonlocal_reference. Create a local variable
823 in the nested function with DECL_VALUE_EXPR set to reference the true
824 variable in the parent function. This is used both for debug info
825 and in OpenMP lowering. */
828 get_nonlocal_debug_decl (struct nesting_info
*info
, tree decl
)
831 struct nesting_info
*i
;
832 tree x
, field
, new_decl
;
835 slot
= pointer_map_insert (info
->var_map
, decl
);
840 target_context
= decl_function_context (decl
);
842 /* A copy of the code in get_frame_field, but without the temporaries. */
843 if (info
->context
== target_context
)
845 /* Make sure frame_decl gets created. */
846 (void) get_frame_type (info
);
847 x
= info
->frame_decl
;
852 x
= get_chain_decl (info
);
853 for (i
= info
->outer
; i
->context
!= target_context
; i
= i
->outer
)
855 field
= get_chain_field (i
);
856 x
= build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (x
)), x
);
857 x
= build3 (COMPONENT_REF
, TREE_TYPE (field
), x
, field
, NULL_TREE
);
859 x
= build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (x
)), x
);
862 field
= lookup_field_for_decl (i
, decl
, INSERT
);
863 x
= build3 (COMPONENT_REF
, TREE_TYPE (field
), x
, field
, NULL_TREE
);
864 if (use_pointer_in_frame (decl
))
865 x
= build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (x
)), x
);
867 /* ??? We should be remapping types as well, surely. */
868 new_decl
= build_decl (VAR_DECL
, DECL_NAME (decl
), TREE_TYPE (decl
));
869 DECL_CONTEXT (new_decl
) = info
->context
;
870 DECL_SOURCE_LOCATION (new_decl
) = DECL_SOURCE_LOCATION (decl
);
871 DECL_ARTIFICIAL (new_decl
) = DECL_ARTIFICIAL (decl
);
872 DECL_IGNORED_P (new_decl
) = DECL_IGNORED_P (decl
);
873 TREE_THIS_VOLATILE (new_decl
) = TREE_THIS_VOLATILE (decl
);
874 TREE_SIDE_EFFECTS (new_decl
) = TREE_SIDE_EFFECTS (decl
);
875 TREE_READONLY (new_decl
) = TREE_READONLY (decl
);
876 TREE_ADDRESSABLE (new_decl
) = TREE_ADDRESSABLE (decl
);
877 DECL_SEEN_IN_BIND_EXPR_P (new_decl
) = 1;
879 SET_DECL_VALUE_EXPR (new_decl
, x
);
880 DECL_HAS_VALUE_EXPR_P (new_decl
) = 1;
883 TREE_CHAIN (new_decl
) = info
->debug_var_chain
;
884 info
->debug_var_chain
= new_decl
;
889 /* Called via walk_function+walk_tree, rewrite all references to VAR
890 and PARM_DECLs that belong to outer functions.
892 The rewrite will involve some number of structure accesses back up
893 the static chain. E.g. for a variable FOO up one nesting level it'll
894 be CHAIN->FOO. For two levels it'll be CHAIN->__chain->FOO. Further
895 indirections apply to decls for which use_pointer_in_frame is true. */
897 static bool convert_nonlocal_omp_clauses (tree
*, struct walk_stmt_info
*);
900 convert_nonlocal_reference (tree
*tp
, int *walk_subtrees
, void *data
)
902 struct walk_stmt_info
*wi
= (struct walk_stmt_info
*) data
;
903 struct nesting_info
*info
= wi
->info
;
905 tree save_local_var_chain
;
906 bitmap save_suppress
;
909 switch (TREE_CODE (t
))
912 /* Non-automatic variables are never processed. */
913 if (TREE_STATIC (t
) || DECL_EXTERNAL (t
))
918 if (decl_function_context (t
) != info
->context
)
923 x
= get_nonlocal_debug_decl (info
, t
);
924 if (!bitmap_bit_p (info
->suppress_expansion
, DECL_UID (t
)))
926 tree target_context
= decl_function_context (t
);
927 struct nesting_info
*i
;
928 for (i
= info
->outer
; i
->context
!= target_context
; i
= i
->outer
)
930 x
= lookup_field_for_decl (i
, t
, INSERT
);
931 x
= get_frame_field (info
, target_context
, x
, &wi
->tsi
);
932 if (use_pointer_in_frame (t
))
934 x
= init_tmp_var (info
, x
, &wi
->tsi
);
935 x
= build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (x
)), x
);
942 x
= save_tmp_var (info
, x
, &wi
->tsi
);
944 x
= init_tmp_var (info
, x
, &wi
->tsi
);
952 /* Don't walk non-local gotos for now. */
953 if (TREE_CODE (GOTO_DESTINATION (t
)) != LABEL_DECL
)
962 /* We're taking the address of a label from a parent function, but
963 this is not itself a non-local goto. Mark the label such that it
964 will not be deleted, much as we would with a label address in
966 if (decl_function_context (t
) != info
->context
)
967 FORCED_LABEL (t
) = 1;
972 bool save_val_only
= wi
->val_only
;
974 wi
->val_only
= false;
977 walk_tree (&TREE_OPERAND (t
, 0), convert_nonlocal_reference
, wi
, NULL
);
984 /* If we changed anything, then TREE_INVARIANT is be wrong,
985 since we're no longer directly referencing a decl. */
986 save_context
= current_function_decl
;
987 current_function_decl
= info
->context
;
988 recompute_tree_invariant_for_addr_expr (t
);
989 current_function_decl
= save_context
;
991 /* If the callback converted the address argument in a context
992 where we only accept variables (and min_invariant, presumably),
993 then compute the address into a temporary. */
995 *tp
= tsi_gimplify_val (wi
->info
, t
, &wi
->tsi
);
1004 case ARRAY_RANGE_REF
:
1006 /* Go down this entire nest and just look at the final prefix and
1007 anything that describes the references. Otherwise, we lose track
1008 of whether a NOP_EXPR or VIEW_CONVERT_EXPR needs a simple value. */
1009 wi
->val_only
= true;
1011 for (; handled_component_p (t
); tp
= &TREE_OPERAND (t
, 0), t
= *tp
)
1013 if (TREE_CODE (t
) == COMPONENT_REF
)
1014 walk_tree (&TREE_OPERAND (t
, 2), convert_nonlocal_reference
, wi
,
1016 else if (TREE_CODE (t
) == ARRAY_REF
1017 || TREE_CODE (t
) == ARRAY_RANGE_REF
)
1019 walk_tree (&TREE_OPERAND (t
, 1), convert_nonlocal_reference
, wi
,
1021 walk_tree (&TREE_OPERAND (t
, 2), convert_nonlocal_reference
, wi
,
1023 walk_tree (&TREE_OPERAND (t
, 3), convert_nonlocal_reference
, wi
,
1026 else if (TREE_CODE (t
) == BIT_FIELD_REF
)
1028 walk_tree (&TREE_OPERAND (t
, 1), convert_nonlocal_reference
, wi
,
1030 walk_tree (&TREE_OPERAND (t
, 2), convert_nonlocal_reference
, wi
,
1034 wi
->val_only
= false;
1035 walk_tree (tp
, convert_nonlocal_reference
, wi
, NULL
);
1039 save_suppress
= info
->suppress_expansion
;
1040 if (convert_nonlocal_omp_clauses (&OMP_PARALLEL_CLAUSES (t
), wi
))
1043 decl
= get_chain_decl (info
);
1044 c
= build_omp_clause (OMP_CLAUSE_FIRSTPRIVATE
);
1045 OMP_CLAUSE_DECL (c
) = decl
;
1046 OMP_CLAUSE_CHAIN (c
) = OMP_PARALLEL_CLAUSES (t
);
1047 OMP_PARALLEL_CLAUSES (t
) = c
;
1050 save_local_var_chain
= info
->new_local_var_chain
;
1051 info
->new_local_var_chain
= NULL
;
1053 walk_body (convert_nonlocal_reference
, info
, &OMP_PARALLEL_BODY (t
));
1055 if (info
->new_local_var_chain
)
1056 declare_vars (info
->new_local_var_chain
, OMP_PARALLEL_BODY (t
), false);
1057 info
->new_local_var_chain
= save_local_var_chain
;
1058 info
->suppress_expansion
= save_suppress
;
1064 save_suppress
= info
->suppress_expansion
;
1065 convert_nonlocal_omp_clauses (&OMP_CLAUSES (t
), wi
);
1066 walk_body (convert_nonlocal_reference
, info
, &OMP_BODY (t
));
1067 info
->suppress_expansion
= save_suppress
;
1073 walk_body (convert_nonlocal_reference
, info
, &OMP_BODY (t
));
1077 if (!IS_TYPE_OR_DECL_P (t
))
1080 wi
->val_only
= true;
1090 convert_nonlocal_omp_clauses (tree
*pclauses
, struct walk_stmt_info
*wi
)
1092 struct nesting_info
*info
= wi
->info
;
1093 bool need_chain
= false;
1096 bitmap new_suppress
;
1098 new_suppress
= BITMAP_GGC_ALLOC ();
1099 bitmap_copy (new_suppress
, info
->suppress_expansion
);
1101 for (clause
= *pclauses
; clause
; clause
= OMP_CLAUSE_CHAIN (clause
))
1103 switch (OMP_CLAUSE_CODE (clause
))
1105 case OMP_CLAUSE_PRIVATE
:
1106 case OMP_CLAUSE_FIRSTPRIVATE
:
1107 case OMP_CLAUSE_LASTPRIVATE
:
1108 case OMP_CLAUSE_REDUCTION
:
1109 case OMP_CLAUSE_COPYPRIVATE
:
1110 case OMP_CLAUSE_SHARED
:
1111 decl
= OMP_CLAUSE_DECL (clause
);
1112 if (decl_function_context (decl
) != info
->context
)
1114 bitmap_set_bit (new_suppress
, DECL_UID (decl
));
1115 OMP_CLAUSE_DECL (clause
) = get_nonlocal_debug_decl (info
, decl
);
1120 case OMP_CLAUSE_SCHEDULE
:
1121 if (OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (clause
) == NULL
)
1125 case OMP_CLAUSE_NUM_THREADS
:
1126 wi
->val_only
= true;
1128 convert_nonlocal_reference (&OMP_CLAUSE_OPERAND (clause
, 0), &dummy
,
1132 case OMP_CLAUSE_NOWAIT
:
1133 case OMP_CLAUSE_ORDERED
:
1134 case OMP_CLAUSE_DEFAULT
:
1135 case OMP_CLAUSE_COPYIN
:
1143 info
->suppress_expansion
= new_suppress
;
1148 /* A subroutine of convert_local_reference. Create a local variable
1149 in the parent function with DECL_VALUE_EXPR set to reference the
1150 field in FRAME. This is used both for debug info and in OpenMP
1154 get_local_debug_decl (struct nesting_info
*info
, tree decl
, tree field
)
1159 slot
= pointer_map_insert (info
->var_map
, decl
);
1163 /* Make sure frame_decl gets created. */
1164 (void) get_frame_type (info
);
1165 x
= info
->frame_decl
;
1166 x
= build3 (COMPONENT_REF
, TREE_TYPE (field
), x
, field
, NULL_TREE
);
1168 new_decl
= build_decl (VAR_DECL
, DECL_NAME (decl
), TREE_TYPE (decl
));
1169 DECL_CONTEXT (new_decl
) = info
->context
;
1170 DECL_SOURCE_LOCATION (new_decl
) = DECL_SOURCE_LOCATION (decl
);
1171 DECL_ARTIFICIAL (new_decl
) = DECL_ARTIFICIAL (decl
);
1172 DECL_IGNORED_P (new_decl
) = DECL_IGNORED_P (decl
);
1173 TREE_THIS_VOLATILE (new_decl
) = TREE_THIS_VOLATILE (decl
);
1174 TREE_SIDE_EFFECTS (new_decl
) = TREE_SIDE_EFFECTS (decl
);
1175 TREE_READONLY (new_decl
) = TREE_READONLY (decl
);
1176 TREE_ADDRESSABLE (new_decl
) = TREE_ADDRESSABLE (decl
);
1177 DECL_SEEN_IN_BIND_EXPR_P (new_decl
) = 1;
1179 SET_DECL_VALUE_EXPR (new_decl
, x
);
1180 DECL_HAS_VALUE_EXPR_P (new_decl
) = 1;
1183 TREE_CHAIN (new_decl
) = info
->debug_var_chain
;
1184 info
->debug_var_chain
= new_decl
;
1186 /* Do not emit debug info twice. */
1187 DECL_IGNORED_P (decl
) = 1;
1192 /* Called via walk_function+walk_tree, rewrite all references to VAR
1193 and PARM_DECLs that were referenced by inner nested functions.
1194 The rewrite will be a structure reference to the local frame variable. */
1196 static bool convert_local_omp_clauses (tree
*, struct walk_stmt_info
*);
1199 convert_local_reference (tree
*tp
, int *walk_subtrees
, void *data
)
1201 struct walk_stmt_info
*wi
= (struct walk_stmt_info
*) data
;
1202 struct nesting_info
*info
= wi
->info
;
1203 tree t
= *tp
, field
, x
;
1205 tree save_local_var_chain
;
1206 bitmap save_suppress
;
1209 switch (TREE_CODE (t
))
1212 /* Non-automatic variables are never processed. */
1213 if (TREE_STATIC (t
) || DECL_EXTERNAL (t
))
1218 if (decl_function_context (t
) == info
->context
)
1220 /* If we copied a pointer to the frame, then the original decl
1221 is used unchanged in the parent function. */
1222 if (use_pointer_in_frame (t
))
1225 /* No need to transform anything if no child references the
1227 field
= lookup_field_for_decl (info
, t
, NO_INSERT
);
1232 x
= get_local_debug_decl (info
, t
, field
);
1233 if (!bitmap_bit_p (info
->suppress_expansion
, DECL_UID (t
)))
1234 x
= get_frame_field (info
, info
->context
, field
, &wi
->tsi
);
1239 x
= save_tmp_var (info
, x
, &wi
->tsi
);
1241 x
= init_tmp_var (info
, x
, &wi
->tsi
);
1249 save_val_only
= wi
->val_only
;
1250 wi
->val_only
= false;
1252 wi
->changed
= false;
1253 walk_tree (&TREE_OPERAND (t
, 0), convert_local_reference
, wi
, NULL
);
1254 wi
->val_only
= save_val_only
;
1256 /* If we converted anything ... */
1261 /* Then the frame decl is now addressable. */
1262 TREE_ADDRESSABLE (info
->frame_decl
) = 1;
1264 save_context
= current_function_decl
;
1265 current_function_decl
= info
->context
;
1266 recompute_tree_invariant_for_addr_expr (t
);
1267 current_function_decl
= save_context
;
1269 /* If we are in a context where we only accept values, then
1270 compute the address into a temporary. */
1272 *tp
= tsi_gimplify_val (wi
->info
, t
, &wi
->tsi
);
1280 case ARRAY_RANGE_REF
:
1282 /* Go down this entire nest and just look at the final prefix and
1283 anything that describes the references. Otherwise, we lose track
1284 of whether a NOP_EXPR or VIEW_CONVERT_EXPR needs a simple value. */
1285 save_val_only
= wi
->val_only
;
1286 wi
->val_only
= true;
1288 for (; handled_component_p (t
); tp
= &TREE_OPERAND (t
, 0), t
= *tp
)
1290 if (TREE_CODE (t
) == COMPONENT_REF
)
1291 walk_tree (&TREE_OPERAND (t
, 2), convert_local_reference
, wi
,
1293 else if (TREE_CODE (t
) == ARRAY_REF
1294 || TREE_CODE (t
) == ARRAY_RANGE_REF
)
1296 walk_tree (&TREE_OPERAND (t
, 1), convert_local_reference
, wi
,
1298 walk_tree (&TREE_OPERAND (t
, 2), convert_local_reference
, wi
,
1300 walk_tree (&TREE_OPERAND (t
, 3), convert_local_reference
, wi
,
1303 else if (TREE_CODE (t
) == BIT_FIELD_REF
)
1305 walk_tree (&TREE_OPERAND (t
, 1), convert_local_reference
, wi
,
1307 walk_tree (&TREE_OPERAND (t
, 2), convert_local_reference
, wi
,
1311 wi
->val_only
= false;
1312 walk_tree (tp
, convert_local_reference
, wi
, NULL
);
1313 wi
->val_only
= save_val_only
;
1317 save_suppress
= info
->suppress_expansion
;
1318 if (convert_local_omp_clauses (&OMP_PARALLEL_CLAUSES (t
), wi
))
1321 (void) get_frame_type (info
);
1322 c
= build_omp_clause (OMP_CLAUSE_SHARED
);
1323 OMP_CLAUSE_DECL (c
) = info
->frame_decl
;
1324 OMP_CLAUSE_CHAIN (c
) = OMP_PARALLEL_CLAUSES (t
);
1325 OMP_PARALLEL_CLAUSES (t
) = c
;
1328 save_local_var_chain
= info
->new_local_var_chain
;
1329 info
->new_local_var_chain
= NULL
;
1331 walk_body (convert_local_reference
, info
, &OMP_PARALLEL_BODY (t
));
1333 if (info
->new_local_var_chain
)
1334 declare_vars (info
->new_local_var_chain
, OMP_PARALLEL_BODY (t
), false);
1335 info
->new_local_var_chain
= save_local_var_chain
;
1336 info
->suppress_expansion
= save_suppress
;
1342 save_suppress
= info
->suppress_expansion
;
1343 convert_local_omp_clauses (&OMP_CLAUSES (t
), wi
);
1344 walk_body (convert_local_reference
, info
, &OMP_BODY (t
));
1345 info
->suppress_expansion
= save_suppress
;
1351 walk_body (convert_local_reference
, info
, &OMP_BODY (t
));
1355 if (!IS_TYPE_OR_DECL_P (t
))
1358 wi
->val_only
= true;
1368 convert_local_omp_clauses (tree
*pclauses
, struct walk_stmt_info
*wi
)
1370 struct nesting_info
*info
= wi
->info
;
1371 bool need_frame
= false;
1374 bitmap new_suppress
;
1376 new_suppress
= BITMAP_GGC_ALLOC ();
1377 bitmap_copy (new_suppress
, info
->suppress_expansion
);
1379 for (clause
= *pclauses
; clause
; clause
= OMP_CLAUSE_CHAIN (clause
))
1381 switch (OMP_CLAUSE_CODE (clause
))
1383 case OMP_CLAUSE_PRIVATE
:
1384 case OMP_CLAUSE_FIRSTPRIVATE
:
1385 case OMP_CLAUSE_LASTPRIVATE
:
1386 case OMP_CLAUSE_REDUCTION
:
1387 case OMP_CLAUSE_COPYPRIVATE
:
1388 case OMP_CLAUSE_SHARED
:
1389 decl
= OMP_CLAUSE_DECL (clause
);
1390 if (decl_function_context (decl
) == info
->context
1391 && !use_pointer_in_frame (decl
))
1393 tree field
= lookup_field_for_decl (info
, decl
, NO_INSERT
);
1396 bitmap_set_bit (new_suppress
, DECL_UID (decl
));
1397 OMP_CLAUSE_DECL (clause
)
1398 = get_local_debug_decl (info
, decl
, field
);
1404 case OMP_CLAUSE_SCHEDULE
:
1405 if (OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (clause
) == NULL
)
1409 case OMP_CLAUSE_NUM_THREADS
:
1410 wi
->val_only
= true;
1412 convert_local_reference (&OMP_CLAUSE_OPERAND (clause
, 0), &dummy
, wi
);
1415 case OMP_CLAUSE_NOWAIT
:
1416 case OMP_CLAUSE_ORDERED
:
1417 case OMP_CLAUSE_DEFAULT
:
1418 case OMP_CLAUSE_COPYIN
:
1426 info
->suppress_expansion
= new_suppress
;
1431 /* Called via walk_function+walk_tree, rewrite all GOTO_EXPRs that
1432 reference labels from outer functions. The rewrite will be a
1433 call to __builtin_nonlocal_goto. */
1436 convert_nl_goto_reference (tree
*tp
, int *walk_subtrees
, void *data
)
1438 struct walk_stmt_info
*wi
= (struct walk_stmt_info
*) data
;
1439 struct nesting_info
*info
= wi
->info
, *i
;
1440 tree t
= *tp
, label
, new_label
, target_context
, x
, field
;
1444 if (TREE_CODE (t
) != GOTO_EXPR
)
1446 label
= GOTO_DESTINATION (t
);
1447 if (TREE_CODE (label
) != LABEL_DECL
)
1449 target_context
= decl_function_context (label
);
1450 if (target_context
== info
->context
)
1453 for (i
= info
->outer
; target_context
!= i
->context
; i
= i
->outer
)
1456 /* The original user label may also be use for a normal goto, therefore
1457 we must create a new label that will actually receive the abnormal
1458 control transfer. This new label will be marked LABEL_NONLOCAL; this
1459 mark will trigger proper behavior in the cfg, as well as cause the
1460 (hairy target-specific) non-local goto receiver code to be generated
1461 when we expand rtl. Enter this association into var_map so that we
1462 can insert the new label into the IL during a second pass. */
1463 slot
= pointer_map_insert (i
->var_map
, label
);
1466 new_label
= create_artificial_label ();
1467 DECL_NONLOCAL (new_label
) = 1;
1473 /* Build: __builtin_nl_goto(new_label, &chain->nl_goto_field). */
1474 field
= get_nl_goto_field (i
);
1475 x
= get_frame_field (info
, target_context
, field
, &wi
->tsi
);
1476 x
= build_addr (x
, target_context
);
1477 x
= tsi_gimplify_val (info
, x
, &wi
->tsi
);
1478 x
= build_call_expr (implicit_built_in_decls
[BUILT_IN_NONLOCAL_GOTO
], 2,
1479 build_addr (new_label
, target_context
), x
);
1481 SET_EXPR_LOCUS (x
, EXPR_LOCUS (tsi_stmt (wi
->tsi
)));
1482 *tsi_stmt_ptr (wi
->tsi
) = x
;
1487 /* Called via walk_function+walk_tree, rewrite all LABEL_EXPRs that
1488 are referenced via nonlocal goto from a nested function. The rewrite
1489 will involve installing a newly generated DECL_NONLOCAL label, and
1490 (potentially) a branch around the rtl gunk that is assumed to be
1491 attached to such a label. */
1494 convert_nl_goto_receiver (tree
*tp
, int *walk_subtrees
, void *data
)
1496 struct walk_stmt_info
*wi
= (struct walk_stmt_info
*) data
;
1497 struct nesting_info
*info
= wi
->info
;
1498 tree t
= *tp
, label
, new_label
, x
;
1499 tree_stmt_iterator tmp_tsi
;
1503 if (TREE_CODE (t
) != LABEL_EXPR
)
1505 label
= LABEL_EXPR_LABEL (t
);
1507 slot
= pointer_map_contains (info
->var_map
, label
);
1511 /* If there's any possibility that the previous statement falls through,
1512 then we must branch around the new non-local label. */
1514 tsi_prev (&tmp_tsi
);
1515 if (tsi_end_p (tmp_tsi
) || block_may_fallthru (tsi_stmt (tmp_tsi
)))
1517 x
= build1 (GOTO_EXPR
, void_type_node
, label
);
1518 tsi_link_before (&wi
->tsi
, x
, TSI_SAME_STMT
);
1521 new_label
= (tree
) *slot
;
1522 x
= build1 (LABEL_EXPR
, void_type_node
, new_label
);
1523 tsi_link_before (&wi
->tsi
, x
, TSI_SAME_STMT
);
1528 /* Called via walk_function+walk_tree, rewrite all references to addresses
1529 of nested functions that require the use of trampolines. The rewrite
1530 will involve a reference a trampoline generated for the occasion. */
1533 convert_tramp_reference (tree
*tp
, int *walk_subtrees
, void *data
)
1535 struct walk_stmt_info
*wi
= (struct walk_stmt_info
*) data
;
1536 struct nesting_info
*info
= wi
->info
, *i
;
1537 tree t
= *tp
, decl
, target_context
, x
;
1540 switch (TREE_CODE (t
))
1544 T.1 = &CHAIN->tramp;
1545 T.2 = __builtin_adjust_trampoline (T.1);
1546 T.3 = (func_type)T.2;
1549 decl
= TREE_OPERAND (t
, 0);
1550 if (TREE_CODE (decl
) != FUNCTION_DECL
)
1553 /* Only need to process nested functions. */
1554 target_context
= decl_function_context (decl
);
1555 if (!target_context
)
1558 /* If the nested function doesn't use a static chain, then
1559 it doesn't need a trampoline. */
1560 if (DECL_NO_STATIC_CHAIN (decl
))
1563 /* Lookup the immediate parent of the callee, as that's where
1564 we need to insert the trampoline. */
1565 for (i
= info
; i
->context
!= target_context
; i
= i
->outer
)
1567 x
= lookup_tramp_for_decl (i
, decl
, INSERT
);
1569 /* Compute the address of the field holding the trampoline. */
1570 x
= get_frame_field (info
, target_context
, x
, &wi
->tsi
);
1571 x
= build_addr (x
, target_context
);
1572 x
= tsi_gimplify_val (info
, x
, &wi
->tsi
);
1574 /* Do machine-specific ugliness. Normally this will involve
1575 computing extra alignment, but it can really be anything. */
1576 x
= build_call_expr (implicit_built_in_decls
[BUILT_IN_ADJUST_TRAMPOLINE
],
1578 x
= init_tmp_var (info
, x
, &wi
->tsi
);
1580 /* Cast back to the proper function type. */
1581 x
= build1 (NOP_EXPR
, TREE_TYPE (t
), x
);
1582 x
= init_tmp_var (info
, x
, &wi
->tsi
);
1588 /* Only walk call arguments, lest we generate trampolines for
1591 int nargs
= call_expr_nargs (t
);
1593 for (i
= 0; i
< nargs
; i
++)
1594 walk_tree (&CALL_EXPR_ARG (t
, i
), convert_tramp_reference
, wi
, NULL
);
1599 if (!IS_TYPE_OR_DECL_P (t
))
1607 /* Called via walk_function+walk_tree, rewrite all CALL_EXPRs that
1608 reference nested functions to make sure that the static chain is
1609 set up properly for the call. */
1612 convert_call_expr (tree
*tp
, int *walk_subtrees
, void *data
)
1614 struct walk_stmt_info
*wi
= (struct walk_stmt_info
*) data
;
1615 struct nesting_info
*info
= wi
->info
;
1616 tree t
= *tp
, decl
, target_context
;
1617 char save_static_chain_added
;
1621 switch (TREE_CODE (t
))
1624 decl
= get_callee_fndecl (t
);
1627 target_context
= decl_function_context (decl
);
1628 if (target_context
&& !DECL_NO_STATIC_CHAIN (decl
))
1630 CALL_EXPR_STATIC_CHAIN (t
)
1631 = get_static_chain (info
, target_context
, &wi
->tsi
);
1632 info
->static_chain_added
1633 |= (1 << (info
->context
!= target_context
));
1638 case GIMPLE_MODIFY_STMT
:
1639 case WITH_SIZE_EXPR
:
1640 /* Only return modify and with_size_expr may contain calls. */
1645 save_static_chain_added
= info
->static_chain_added
;
1646 info
->static_chain_added
= 0;
1647 walk_body (convert_call_expr
, info
, &OMP_PARALLEL_BODY (t
));
1648 for (i
= 0; i
< 2; i
++)
1651 if ((info
->static_chain_added
& (1 << i
)) == 0)
1653 decl
= i
? get_chain_decl (info
) : info
->frame_decl
;
1654 /* Don't add CHAIN.* or FRAME.* twice. */
1655 for (c
= OMP_PARALLEL_CLAUSES (t
); c
; c
= OMP_CLAUSE_CHAIN (c
))
1656 if ((OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_FIRSTPRIVATE
1657 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_SHARED
)
1658 && OMP_CLAUSE_DECL (c
) == decl
)
1662 c
= build_omp_clause (OMP_CLAUSE_FIRSTPRIVATE
);
1663 OMP_CLAUSE_DECL (c
) = decl
;
1664 OMP_CLAUSE_CHAIN (c
) = OMP_PARALLEL_CLAUSES (t
);
1665 OMP_PARALLEL_CLAUSES (t
) = c
;
1668 info
->static_chain_added
|= save_static_chain_added
;
1678 walk_body (convert_call_expr
, info
, &OMP_BODY (t
));
1688 /* Walk the nesting tree starting with ROOT, depth first. Convert all
1689 trampolines and call expressions. On the way back up, determine if
1690 a nested function actually uses its static chain; if not, remember that. */
1693 convert_all_function_calls (struct nesting_info
*root
)
1698 convert_all_function_calls (root
->inner
);
1700 walk_function (convert_tramp_reference
, root
);
1701 walk_function (convert_call_expr
, root
);
1703 /* If the function does not use a static chain, then remember that. */
1704 if (root
->outer
&& !root
->chain_decl
&& !root
->chain_field
)
1705 DECL_NO_STATIC_CHAIN (root
->context
) = 1;
1707 gcc_assert (!DECL_NO_STATIC_CHAIN (root
->context
));
1714 /* Do "everything else" to clean up or complete state collected by the
1715 various walking passes -- lay out the types and decls, generate code
1716 to initialize the frame decl, store critical expressions in the
1717 struct function for rtl to find. */
1720 finalize_nesting_tree_1 (struct nesting_info
*root
)
1722 tree stmt_list
= NULL
;
1723 tree context
= root
->context
;
1724 struct function
*sf
;
1726 /* If we created a non-local frame type or decl, we need to lay them
1727 out at this time. */
1728 if (root
->frame_type
)
1730 /* In some cases the frame type will trigger the -Wpadded warning.
1731 This is not helpful; suppress it. */
1732 int save_warn_padded
= warn_padded
;
1734 layout_type (root
->frame_type
);
1735 warn_padded
= save_warn_padded
;
1736 layout_decl (root
->frame_decl
, 0);
1739 /* If any parameters were referenced non-locally, then we need to
1740 insert a copy. Likewise, if any variables were referenced by
1741 pointer, we need to initialize the address. */
1742 if (root
->any_parm_remapped
)
1745 for (p
= DECL_ARGUMENTS (context
); p
; p
= TREE_CHAIN (p
))
1749 field
= lookup_field_for_decl (root
, p
, NO_INSERT
);
1753 if (use_pointer_in_frame (p
))
1754 x
= build_addr (p
, context
);
1758 y
= build3 (COMPONENT_REF
, TREE_TYPE (field
),
1759 root
->frame_decl
, field
, NULL_TREE
);
1760 x
= build2 (GIMPLE_MODIFY_STMT
, TREE_TYPE (field
), y
, x
);
1761 append_to_statement_list (x
, &stmt_list
);
1765 /* If a chain_field was created, then it needs to be initialized
1767 if (root
->chain_field
)
1769 tree x
= build3 (COMPONENT_REF
, TREE_TYPE (root
->chain_field
),
1770 root
->frame_decl
, root
->chain_field
, NULL_TREE
);
1771 x
= build2 (GIMPLE_MODIFY_STMT
, TREE_TYPE (x
), x
, get_chain_decl (root
));
1772 append_to_statement_list (x
, &stmt_list
);
1775 /* If trampolines were created, then we need to initialize them. */
1776 if (root
->any_tramp_created
)
1778 struct nesting_info
*i
;
1779 for (i
= root
->inner
; i
; i
= i
->next
)
1781 tree arg1
, arg2
, arg3
, x
, field
;
1783 field
= lookup_tramp_for_decl (root
, i
->context
, NO_INSERT
);
1787 if (DECL_NO_STATIC_CHAIN (i
->context
))
1788 arg3
= null_pointer_node
;
1790 arg3
= build_addr (root
->frame_decl
, context
);
1792 arg2
= build_addr (i
->context
, context
);
1794 x
= build3 (COMPONENT_REF
, TREE_TYPE (field
),
1795 root
->frame_decl
, field
, NULL_TREE
);
1796 arg1
= build_addr (x
, context
);
1798 x
= implicit_built_in_decls
[BUILT_IN_INIT_TRAMPOLINE
];
1799 x
= build_call_expr (x
, 3, arg1
, arg2
, arg3
);
1800 append_to_statement_list (x
, &stmt_list
);
1804 /* If we created initialization statements, insert them. */
1807 annotate_all_with_locus (&stmt_list
,
1808 DECL_SOURCE_LOCATION (context
));
1809 append_to_statement_list (BIND_EXPR_BODY (DECL_SAVED_TREE (context
)),
1811 BIND_EXPR_BODY (DECL_SAVED_TREE (context
)) = stmt_list
;
1814 /* If a chain_decl was created, then it needs to be registered with
1815 struct function so that it gets initialized from the static chain
1816 register at the beginning of the function. */
1817 sf
= DECL_STRUCT_FUNCTION (root
->context
);
1818 sf
->static_chain_decl
= root
->chain_decl
;
1820 /* Similarly for the non-local goto save area. */
1821 if (root
->nl_goto_field
)
1823 sf
->nonlocal_goto_save_area
1824 = get_frame_field (root
, context
, root
->nl_goto_field
, NULL
);
1825 sf
->has_nonlocal_label
= 1;
1828 /* Make sure all new local variables get inserted into the
1829 proper BIND_EXPR. */
1830 if (root
->new_local_var_chain
)
1831 declare_vars (root
->new_local_var_chain
, DECL_SAVED_TREE (root
->context
),
1833 if (root
->debug_var_chain
)
1834 declare_vars (root
->debug_var_chain
, DECL_SAVED_TREE (root
->context
),
1837 /* Dump the translated tree function. */
1838 dump_function (TDI_nested
, root
->context
);
1842 finalize_nesting_tree (struct nesting_info
*root
)
1847 finalize_nesting_tree (root
->inner
);
1848 finalize_nesting_tree_1 (root
);
1854 /* Unnest the nodes and pass them to cgraph. */
1857 unnest_nesting_tree_1 (struct nesting_info
*root
)
1859 struct cgraph_node
*node
= cgraph_node (root
->context
);
1861 /* For nested functions update the cgraph to reflect unnesting.
1862 We also delay finalizing of these functions up to this point. */
1865 cgraph_unnest_node (cgraph_node (root
->context
));
1866 cgraph_finalize_function (root
->context
, true);
1871 unnest_nesting_tree (struct nesting_info
*root
)
1876 unnest_nesting_tree (root
->inner
);
1877 unnest_nesting_tree_1 (root
);
1883 /* Free the data structures allocated during this pass. */
1886 free_nesting_tree (struct nesting_info
*root
)
1888 struct nesting_info
*next
;
1892 free_nesting_tree (root
->inner
);
1893 pointer_map_destroy (root
->var_map
);
1894 pointer_map_destroy (root
->field_map
);
1902 /* Main entry point for this pass. Process FNDECL and all of its nested
1903 subroutines and turn them into something less tightly bound. */
1906 lower_nested_functions (tree fndecl
)
1908 struct cgraph_node
*cgn
;
1909 struct nesting_info
*root
;
1911 /* If there are no nested functions, there's nothing to do. */
1912 cgn
= cgraph_node (fndecl
);
1916 bitmap_obstack_initialize (&nesting_info_bitmap_obstack
);
1917 root
= create_nesting_tree (cgn
);
1918 walk_all_functions (convert_nonlocal_reference
, root
);
1919 walk_all_functions (convert_local_reference
, root
);
1920 walk_all_functions (convert_nl_goto_reference
, root
);
1921 walk_all_functions (convert_nl_goto_receiver
, root
);
1922 convert_all_function_calls (root
);
1923 finalize_nesting_tree (root
);
1924 unnest_nesting_tree (root
);
1925 free_nesting_tree (root
);
1926 bitmap_obstack_release (&nesting_info_bitmap_obstack
);
1929 #include "gt-tree-nested.h"