Mercurial > hg > CbC > CbC_gcc
comparison gcc/tree-nested.c @ 55:77e2b8dfacca gcc-4.4.5
update it from 4.4.3 to 4.5.0
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 12 Feb 2010 23:39:51 +0900 |
parents | a06113de4d67 |
children | b7f97abdc517 |
comparison
equal
deleted
inserted
replaced
52:c156f1bd5cd9 | 55:77e2b8dfacca |
---|---|
1 /* Nested function decomposition for GIMPLE. | 1 /* Nested function decomposition for GIMPLE. |
2 Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. | 2 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 |
3 Free Software Foundation, Inc. | |
3 | 4 |
4 This file is part of GCC. | 5 This file is part of GCC. |
5 | 6 |
6 GCC is free software; you can redistribute it and/or modify | 7 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 it under the terms of the GNU General Public License as published by |
40 /* The object of this pass is to lower the representation of a set of nested | 41 /* The object of this pass is to lower the representation of a set of nested |
41 functions in order to expose all of the gory details of the various | 42 functions in order to expose all of the gory details of the various |
42 nonlocal references. We want to do this sooner rather than later, in | 43 nonlocal references. We want to do this sooner rather than later, in |
43 order to give us more freedom in emitting all of the functions in question. | 44 order to give us more freedom in emitting all of the functions in question. |
44 | 45 |
45 Back in olden times, when gcc was young, we developed an insanely | 46 Back in olden times, when gcc was young, we developed an insanely |
46 complicated scheme whereby variables which were referenced nonlocally | 47 complicated scheme whereby variables which were referenced nonlocally |
47 were forced to live in the stack of the declaring function, and then | 48 were forced to live in the stack of the declaring function, and then |
48 the nested functions magically discovered where these variables were | 49 the nested functions magically discovered where these variables were |
49 placed. In order for this scheme to function properly, it required | 50 placed. In order for this scheme to function properly, it required |
50 that the outer function be partially expanded, then we switch to | 51 that the outer function be partially expanded, then we switch to |
51 compiling the inner function, and once done with those we switch back | 52 compiling the inner function, and once done with those we switch back |
52 to compiling the outer function. Such delicate ordering requirements | 53 to compiling the outer function. Such delicate ordering requirements |
53 makes it difficult to do whole translation unit optimizations | 54 makes it difficult to do whole translation unit optimizations |
54 involving such functions. | 55 involving such functions. |
55 | 56 |
56 The implementation here is much more direct. Everything that can be | 57 The implementation here is much more direct. Everything that can be |
57 referenced by an inner function is a member of an explicitly created | 58 referenced by an inner function is a member of an explicitly created |
58 structure herein called the "nonlocal frame struct". The incoming | 59 structure herein called the "nonlocal frame struct". The incoming |
59 static chain for a nested function is a pointer to this struct in | 60 static chain for a nested function is a pointer to this struct in |
60 the parent. In this way, we settle on known offsets from a known | 61 the parent. In this way, we settle on known offsets from a known |
61 base, and so are decoupled from the logic that places objects in the | 62 base, and so are decoupled from the logic that places objects in the |
62 function's stack frame. More importantly, we don't have to wait for | 63 function's stack frame. More importantly, we don't have to wait for |
63 that to happen -- since the compilation of the inner function is no | 64 that to happen -- since the compilation of the inner function is no |
64 longer tied to a real stack frame, the nonlocal frame struct can be | 65 longer tied to a real stack frame, the nonlocal frame struct can be |
65 allocated anywhere. Which means that the outer function is now | 66 allocated anywhere. Which means that the outer function is now |
66 inlinable. | 67 inlinable. |
67 | 68 |
68 Theory of operation here is very simple. Iterate over all the | 69 Theory of operation here is very simple. Iterate over all the |
69 statements in all the functions (depth first) several times, | 70 statements in all the functions (depth first) several times, |
70 allocating structures and fields on demand. In general we want to | 71 allocating structures and fields on demand. In general we want to |
71 examine inner functions first, so that we can avoid making changes | 72 examine inner functions first, so that we can avoid making changes |
72 to outer functions which are unnecessary. | 73 to outer functions which are unnecessary. |
73 | 74 |
74 The order of the passes matters a bit, in that later passes will be | 75 The order of the passes matters a bit, in that later passes will be |
80 struct nesting_info | 81 struct nesting_info |
81 { | 82 { |
82 struct nesting_info *outer; | 83 struct nesting_info *outer; |
83 struct nesting_info *inner; | 84 struct nesting_info *inner; |
84 struct nesting_info *next; | 85 struct nesting_info *next; |
85 | 86 |
86 struct pointer_map_t *field_map; | 87 struct pointer_map_t *field_map; |
87 struct pointer_map_t *var_map; | 88 struct pointer_map_t *var_map; |
88 bitmap suppress_expansion; | 89 bitmap suppress_expansion; |
89 | 90 |
90 tree context; | 91 tree context; |
100 bool any_tramp_created; | 101 bool any_tramp_created; |
101 char static_chain_added; | 102 char static_chain_added; |
102 }; | 103 }; |
103 | 104 |
104 | 105 |
106 /* Iterate over the nesting tree, starting with ROOT, depth first. */ | |
107 | |
108 static inline struct nesting_info * | |
109 iter_nestinfo_start (struct nesting_info *root) | |
110 { | |
111 while (root->inner) | |
112 root = root->inner; | |
113 return root; | |
114 } | |
115 | |
116 static inline struct nesting_info * | |
117 iter_nestinfo_next (struct nesting_info *node) | |
118 { | |
119 if (node->next) | |
120 return iter_nestinfo_start (node->next); | |
121 return node->outer; | |
122 } | |
123 | |
124 #define FOR_EACH_NEST_INFO(I, ROOT) \ | |
125 for ((I) = iter_nestinfo_start (ROOT); (I); (I) = iter_nestinfo_next (I)) | |
126 | |
105 /* Obstack used for the bitmaps in the struct above. */ | 127 /* Obstack used for the bitmaps in the struct above. */ |
106 static struct bitmap_obstack nesting_info_bitmap_obstack; | 128 static struct bitmap_obstack nesting_info_bitmap_obstack; |
107 | 129 |
108 | 130 |
109 /* We're working in so many different function contexts simultaneously, | 131 /* We're working in so many different function contexts simultaneously, |
299 | 321 |
300 static tree | 322 static tree |
301 get_chain_decl (struct nesting_info *info) | 323 get_chain_decl (struct nesting_info *info) |
302 { | 324 { |
303 tree decl = info->chain_decl; | 325 tree decl = info->chain_decl; |
326 | |
304 if (!decl) | 327 if (!decl) |
305 { | 328 { |
306 tree type; | 329 tree type; |
307 | 330 |
308 type = get_frame_type (info->outer); | 331 type = get_frame_type (info->outer); |
310 | 333 |
311 /* Note that this variable is *not* entered into any BIND_EXPR; | 334 /* Note that this variable is *not* entered into any BIND_EXPR; |
312 the construction of this variable is handled specially in | 335 the construction of this variable is handled specially in |
313 expand_function_start and initialize_inlined_parameters. | 336 expand_function_start and initialize_inlined_parameters. |
314 Note also that it's represented as a parameter. This is more | 337 Note also that it's represented as a parameter. This is more |
315 close to the truth, since the initial value does come from | 338 close to the truth, since the initial value does come from |
316 the caller. */ | 339 the caller. */ |
317 decl = build_decl (PARM_DECL, create_tmp_var_name ("CHAIN"), type); | 340 decl = build_decl (DECL_SOURCE_LOCATION (info->context), |
341 PARM_DECL, create_tmp_var_name ("CHAIN"), type); | |
318 DECL_ARTIFICIAL (decl) = 1; | 342 DECL_ARTIFICIAL (decl) = 1; |
319 DECL_IGNORED_P (decl) = 1; | 343 DECL_IGNORED_P (decl) = 1; |
320 TREE_USED (decl) = 1; | 344 TREE_USED (decl) = 1; |
321 DECL_CONTEXT (decl) = info->context; | 345 DECL_CONTEXT (decl) = info->context; |
322 DECL_ARG_TYPE (decl) = type; | 346 DECL_ARG_TYPE (decl) = type; |
324 /* Tell tree-inline.c that we never write to this variable, so | 348 /* Tell tree-inline.c that we never write to this variable, so |
325 it can copy-prop the replacement value immediately. */ | 349 it can copy-prop the replacement value immediately. */ |
326 TREE_READONLY (decl) = 1; | 350 TREE_READONLY (decl) = 1; |
327 | 351 |
328 info->chain_decl = decl; | 352 info->chain_decl = decl; |
353 | |
354 if (dump_file | |
355 && (dump_flags & TDF_DETAILS) | |
356 && !DECL_STATIC_CHAIN (info->context)) | |
357 fprintf (dump_file, "Setting static-chain for %s\n", | |
358 lang_hooks.decl_printable_name (info->context, 2)); | |
359 | |
360 DECL_STATIC_CHAIN (info->context) = 1; | |
329 } | 361 } |
330 return decl; | 362 return decl; |
331 } | 363 } |
332 | 364 |
333 /* Build or return the field within the non-local frame state that holds | 365 /* Build or return the field within the non-local frame state that holds |
336 | 368 |
337 static tree | 369 static tree |
338 get_chain_field (struct nesting_info *info) | 370 get_chain_field (struct nesting_info *info) |
339 { | 371 { |
340 tree field = info->chain_field; | 372 tree field = info->chain_field; |
373 | |
341 if (!field) | 374 if (!field) |
342 { | 375 { |
343 tree type = build_pointer_type (get_frame_type (info->outer)); | 376 tree type = build_pointer_type (get_frame_type (info->outer)); |
344 | 377 |
345 field = make_node (FIELD_DECL); | 378 field = make_node (FIELD_DECL); |
349 DECL_NONADDRESSABLE_P (field) = 1; | 382 DECL_NONADDRESSABLE_P (field) = 1; |
350 | 383 |
351 insert_field_into_struct (get_frame_type (info), field); | 384 insert_field_into_struct (get_frame_type (info), field); |
352 | 385 |
353 info->chain_field = field; | 386 info->chain_field = field; |
387 | |
388 if (dump_file | |
389 && (dump_flags & TDF_DETAILS) | |
390 && !DECL_STATIC_CHAIN (info->context)) | |
391 fprintf (dump_file, "Setting static-chain for %s\n", | |
392 lang_hooks.decl_printable_name (info->context, 2)); | |
393 | |
394 DECL_STATIC_CHAIN (info->context) = 1; | |
354 } | 395 } |
355 return field; | 396 return field; |
356 } | 397 } |
357 | 398 |
358 /* Initialize a new temporary with the GIMPLE_CALL STMT. */ | 399 /* Initialize a new temporary with the GIMPLE_CALL STMT. */ |
370 gsi_insert_before (gsi, call, GSI_SAME_STMT); | 411 gsi_insert_before (gsi, call, GSI_SAME_STMT); |
371 | 412 |
372 return t; | 413 return t; |
373 } | 414 } |
374 | 415 |
375 | 416 |
376 /* Copy EXP into a temporary. Allocate the temporary in the context of | 417 /* Copy EXP into a temporary. Allocate the temporary in the context of |
377 INFO and insert the initialization statement before GSI. */ | 418 INFO and insert the initialization statement before GSI. */ |
378 | 419 |
379 static tree | 420 static tree |
380 init_tmp_var (struct nesting_info *info, tree exp, gimple_stmt_iterator *gsi) | 421 init_tmp_var (struct nesting_info *info, tree exp, gimple_stmt_iterator *gsi) |
425 /* Build or return the type used to represent a nested function trampoline. */ | 466 /* Build or return the type used to represent a nested function trampoline. */ |
426 | 467 |
427 static GTY(()) tree trampoline_type; | 468 static GTY(()) tree trampoline_type; |
428 | 469 |
429 static tree | 470 static tree |
430 get_trampoline_type (void) | 471 get_trampoline_type (struct nesting_info *info) |
431 { | 472 { |
432 unsigned align, size; | 473 unsigned align, size; |
433 tree t; | 474 tree t; |
434 | 475 |
435 if (trampoline_type) | 476 if (trampoline_type) |
446 align = STACK_BOUNDARY; | 487 align = STACK_BOUNDARY; |
447 } | 488 } |
448 | 489 |
449 t = build_index_type (build_int_cst (NULL_TREE, size - 1)); | 490 t = build_index_type (build_int_cst (NULL_TREE, size - 1)); |
450 t = build_array_type (char_type_node, t); | 491 t = build_array_type (char_type_node, t); |
451 t = build_decl (FIELD_DECL, get_identifier ("__data"), t); | 492 t = build_decl (DECL_SOURCE_LOCATION (info->context), |
493 FIELD_DECL, get_identifier ("__data"), t); | |
452 DECL_ALIGN (t) = align; | 494 DECL_ALIGN (t) = align; |
453 DECL_USER_ALIGN (t) = 1; | 495 DECL_USER_ALIGN (t) = 1; |
454 | 496 |
455 trampoline_type = make_node (RECORD_TYPE); | 497 trampoline_type = make_node (RECORD_TYPE); |
456 TYPE_NAME (trampoline_type) = get_identifier ("__builtin_trampoline"); | 498 TYPE_NAME (trampoline_type) = get_identifier ("__builtin_trampoline"); |
479 slot = pointer_map_insert (info->var_map, decl); | 521 slot = pointer_map_insert (info->var_map, decl); |
480 if (!*slot) | 522 if (!*slot) |
481 { | 523 { |
482 tree field = make_node (FIELD_DECL); | 524 tree field = make_node (FIELD_DECL); |
483 DECL_NAME (field) = DECL_NAME (decl); | 525 DECL_NAME (field) = DECL_NAME (decl); |
484 TREE_TYPE (field) = get_trampoline_type (); | 526 TREE_TYPE (field) = get_trampoline_type (info); |
485 TREE_ADDRESSABLE (field) = 1; | 527 TREE_ADDRESSABLE (field) = 1; |
486 | 528 |
487 insert_field_into_struct (get_frame_type (info), field); | 529 insert_field_into_struct (get_frame_type (info), field); |
488 *slot = field; | 530 *slot = field; |
489 | 531 |
490 info->any_tramp_created = true; | 532 info->any_tramp_created = true; |
491 } | 533 } |
492 | 534 |
493 return (tree) *slot; | 535 return (tree) *slot; |
494 } | 536 } |
495 | 537 |
496 /* Build or return the field within the non-local frame state that holds | 538 /* Build or return the field within the non-local frame state that holds |
497 the non-local goto "jmp_buf". The buffer itself is maintained by the | 539 the non-local goto "jmp_buf". The buffer itself is maintained by the |
498 rtl middle-end as dynamic stack space is allocated. */ | 540 rtl middle-end as dynamic stack space is allocated. */ |
499 | 541 |
613 gimple_omp_for_set_pre_body (for_stmt, pre_body); | 655 gimple_omp_for_set_pre_body (for_stmt, pre_body); |
614 } | 656 } |
615 } | 657 } |
616 | 658 |
617 /* Similarly for ROOT and all functions nested underneath, depth first. */ | 659 /* Similarly for ROOT and all functions nested underneath, depth first. */ |
618 | 660 |
619 static void | 661 static void |
620 walk_all_functions (walk_stmt_fn callback_stmt, walk_tree_fn callback_op, | 662 walk_all_functions (walk_stmt_fn callback_stmt, walk_tree_fn callback_op, |
621 struct nesting_info *root) | 663 struct nesting_info *root) |
622 { | 664 { |
623 do | 665 struct nesting_info *n; |
624 { | 666 FOR_EACH_NEST_INFO (n, root) |
625 if (root->inner) | 667 walk_function (callback_stmt, callback_op, n); |
626 walk_all_functions (callback_stmt, callback_op, root->inner); | |
627 walk_function (callback_stmt, callback_op, root); | |
628 root = root->next; | |
629 } | |
630 while (root); | |
631 } | 668 } |
632 | 669 |
633 | 670 |
634 /* We have to check for a fairly pathological case. The operands of function | 671 /* We have to check for a fairly pathological case. The operands of function |
635 nested function are to be interpreted in the context of the enclosing | 672 nested function are to be interpreted in the context of the enclosing |
768 | 805 |
769 x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE); | 806 x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE); |
770 return x; | 807 return x; |
771 } | 808 } |
772 | 809 |
810 static void note_nonlocal_vla_type (struct nesting_info *info, tree type); | |
773 | 811 |
774 /* A subroutine of convert_nonlocal_reference_op. Create a local variable | 812 /* A subroutine of convert_nonlocal_reference_op. Create a local variable |
775 in the nested function with DECL_VALUE_EXPR set to reference the true | 813 in the nested function with DECL_VALUE_EXPR set to reference the true |
776 variable in the parent function. This is used both for debug info | 814 variable in the parent function. This is used both for debug info |
777 and in OpenMP lowering. */ | 815 and in OpenMP lowering. */ |
778 | 816 |
779 static tree | 817 static tree |
780 get_nonlocal_debug_decl (struct nesting_info *info, tree decl) | 818 get_nonlocal_debug_decl (struct nesting_info *info, tree decl) |
781 { | 819 { |
815 x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE); | 853 x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE); |
816 if (use_pointer_in_frame (decl)) | 854 if (use_pointer_in_frame (decl)) |
817 x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x); | 855 x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x); |
818 | 856 |
819 /* ??? We should be remapping types as well, surely. */ | 857 /* ??? We should be remapping types as well, surely. */ |
820 new_decl = build_decl (VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl)); | 858 new_decl = build_decl (DECL_SOURCE_LOCATION (decl), |
859 VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl)); | |
821 DECL_CONTEXT (new_decl) = info->context; | 860 DECL_CONTEXT (new_decl) = info->context; |
822 DECL_SOURCE_LOCATION (new_decl) = DECL_SOURCE_LOCATION (decl); | |
823 DECL_ARTIFICIAL (new_decl) = DECL_ARTIFICIAL (decl); | 861 DECL_ARTIFICIAL (new_decl) = DECL_ARTIFICIAL (decl); |
824 DECL_IGNORED_P (new_decl) = DECL_IGNORED_P (decl); | 862 DECL_IGNORED_P (new_decl) = DECL_IGNORED_P (decl); |
825 TREE_THIS_VOLATILE (new_decl) = TREE_THIS_VOLATILE (decl); | 863 TREE_THIS_VOLATILE (new_decl) = TREE_THIS_VOLATILE (decl); |
826 TREE_SIDE_EFFECTS (new_decl) = TREE_SIDE_EFFECTS (decl); | 864 TREE_SIDE_EFFECTS (new_decl) = TREE_SIDE_EFFECTS (decl); |
827 TREE_READONLY (new_decl) = TREE_READONLY (decl); | 865 TREE_READONLY (new_decl) = TREE_READONLY (decl); |
828 TREE_ADDRESSABLE (new_decl) = TREE_ADDRESSABLE (decl); | 866 TREE_ADDRESSABLE (new_decl) = TREE_ADDRESSABLE (decl); |
829 DECL_SEEN_IN_BIND_EXPR_P (new_decl) = 1; | 867 DECL_SEEN_IN_BIND_EXPR_P (new_decl) = 1; |
868 if ((TREE_CODE (decl) == PARM_DECL | |
869 || TREE_CODE (decl) == RESULT_DECL | |
870 || TREE_CODE (decl) == VAR_DECL) | |
871 && DECL_BY_REFERENCE (decl)) | |
872 DECL_BY_REFERENCE (new_decl) = 1; | |
830 | 873 |
831 SET_DECL_VALUE_EXPR (new_decl, x); | 874 SET_DECL_VALUE_EXPR (new_decl, x); |
832 DECL_HAS_VALUE_EXPR_P (new_decl) = 1; | 875 DECL_HAS_VALUE_EXPR_P (new_decl) = 1; |
833 | 876 |
834 *slot = new_decl; | 877 *slot = new_decl; |
835 TREE_CHAIN (new_decl) = info->debug_var_chain; | 878 TREE_CHAIN (new_decl) = info->debug_var_chain; |
836 info->debug_var_chain = new_decl; | 879 info->debug_var_chain = new_decl; |
880 | |
881 if (!optimize | |
882 && info->context != target_context | |
883 && variably_modified_type_p (TREE_TYPE (decl), NULL)) | |
884 note_nonlocal_vla_type (info, TREE_TYPE (decl)); | |
837 | 885 |
838 return new_decl; | 886 return new_decl; |
839 } | 887 } |
840 | 888 |
841 | 889 |
1104 } | 1152 } |
1105 | 1153 |
1106 return need_chain; | 1154 return need_chain; |
1107 } | 1155 } |
1108 | 1156 |
1157 /* Create nonlocal debug decls for nonlocal VLA array bounds. */ | |
1158 | |
1159 static void | |
1160 note_nonlocal_vla_type (struct nesting_info *info, tree type) | |
1161 { | |
1162 while (POINTER_TYPE_P (type) && !TYPE_NAME (type)) | |
1163 type = TREE_TYPE (type); | |
1164 | |
1165 if (TYPE_NAME (type) | |
1166 && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL | |
1167 && DECL_ORIGINAL_TYPE (TYPE_NAME (type))) | |
1168 type = DECL_ORIGINAL_TYPE (TYPE_NAME (type)); | |
1169 | |
1170 while (POINTER_TYPE_P (type) | |
1171 || TREE_CODE (type) == VECTOR_TYPE | |
1172 || TREE_CODE (type) == FUNCTION_TYPE | |
1173 || TREE_CODE (type) == METHOD_TYPE) | |
1174 type = TREE_TYPE (type); | |
1175 | |
1176 if (TREE_CODE (type) == ARRAY_TYPE) | |
1177 { | |
1178 tree domain, t; | |
1179 | |
1180 note_nonlocal_vla_type (info, TREE_TYPE (type)); | |
1181 domain = TYPE_DOMAIN (type); | |
1182 if (domain) | |
1183 { | |
1184 t = TYPE_MIN_VALUE (domain); | |
1185 if (t && (TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == PARM_DECL) | |
1186 && decl_function_context (t) != info->context) | |
1187 get_nonlocal_debug_decl (info, t); | |
1188 t = TYPE_MAX_VALUE (domain); | |
1189 if (t && (TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == PARM_DECL) | |
1190 && decl_function_context (t) != info->context) | |
1191 get_nonlocal_debug_decl (info, t); | |
1192 } | |
1193 } | |
1194 } | |
1195 | |
1196 /* Create nonlocal debug decls for nonlocal VLA array bounds for VLAs | |
1197 in BLOCK. */ | |
1198 | |
1199 static void | |
1200 note_nonlocal_block_vlas (struct nesting_info *info, tree block) | |
1201 { | |
1202 tree var; | |
1203 | |
1204 for (var = BLOCK_VARS (block); var; var = TREE_CHAIN (var)) | |
1205 if (TREE_CODE (var) == VAR_DECL | |
1206 && variably_modified_type_p (TREE_TYPE (var), NULL) | |
1207 && DECL_HAS_VALUE_EXPR_P (var) | |
1208 && decl_function_context (var) != info->context) | |
1209 note_nonlocal_vla_type (info, TREE_TYPE (var)); | |
1210 } | |
1109 | 1211 |
1110 /* Callback for walk_gimple_stmt. Rewrite all references to VAR and | 1212 /* Callback for walk_gimple_stmt. Rewrite all references to VAR and |
1111 PARM_DECLs that belong to outer functions. This handles statements | 1213 PARM_DECLs that belong to outer functions. This handles statements |
1112 that are not handled via the standard recursion done in | 1214 that are not handled via the standard recursion done in |
1113 walk_gimple_stmt. STMT is the statement to examine, DATA is as in | 1215 walk_gimple_stmt. STMT is the statement to examine, DATA is as in |
1142 if (convert_nonlocal_omp_clauses (gimple_omp_taskreg_clauses_ptr (stmt), | 1244 if (convert_nonlocal_omp_clauses (gimple_omp_taskreg_clauses_ptr (stmt), |
1143 wi)) | 1245 wi)) |
1144 { | 1246 { |
1145 tree c, decl; | 1247 tree c, decl; |
1146 decl = get_chain_decl (info); | 1248 decl = get_chain_decl (info); |
1147 c = build_omp_clause (OMP_CLAUSE_FIRSTPRIVATE); | 1249 c = build_omp_clause (gimple_location (stmt), |
1250 OMP_CLAUSE_FIRSTPRIVATE); | |
1148 OMP_CLAUSE_DECL (c) = decl; | 1251 OMP_CLAUSE_DECL (c) = decl; |
1149 OMP_CLAUSE_CHAIN (c) = gimple_omp_taskreg_clauses (stmt); | 1252 OMP_CLAUSE_CHAIN (c) = gimple_omp_taskreg_clauses (stmt); |
1150 gimple_omp_taskreg_set_clauses (stmt, c); | 1253 gimple_omp_taskreg_set_clauses (stmt, c); |
1151 } | 1254 } |
1152 | 1255 |
1195 case GIMPLE_OMP_ORDERED: | 1298 case GIMPLE_OMP_ORDERED: |
1196 walk_body (convert_nonlocal_reference_stmt, convert_nonlocal_reference_op, | 1299 walk_body (convert_nonlocal_reference_stmt, convert_nonlocal_reference_op, |
1197 info, gimple_omp_body (stmt)); | 1300 info, gimple_omp_body (stmt)); |
1198 break; | 1301 break; |
1199 | 1302 |
1303 case GIMPLE_BIND: | |
1304 if (!optimize && gimple_bind_block (stmt)) | |
1305 note_nonlocal_block_vlas (info, gimple_bind_block (stmt)); | |
1306 | |
1307 *handled_ops_p = false; | |
1308 return NULL_TREE; | |
1309 | |
1310 case GIMPLE_COND: | |
1311 wi->val_only = true; | |
1312 wi->is_lhs = false; | |
1313 *handled_ops_p = false; | |
1314 return NULL_TREE; | |
1315 | |
1200 default: | 1316 default: |
1201 /* For every other statement that we are not interested in | 1317 /* For every other statement that we are not interested in |
1202 handling here, let the walker traverse the operands. */ | 1318 handling here, let the walker traverse the operands. */ |
1203 *handled_ops_p = false; | 1319 *handled_ops_p = false; |
1204 return NULL_TREE; | 1320 return NULL_TREE; |
1228 /* Make sure frame_decl gets created. */ | 1344 /* Make sure frame_decl gets created. */ |
1229 (void) get_frame_type (info); | 1345 (void) get_frame_type (info); |
1230 x = info->frame_decl; | 1346 x = info->frame_decl; |
1231 x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE); | 1347 x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE); |
1232 | 1348 |
1233 new_decl = build_decl (VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl)); | 1349 new_decl = build_decl (DECL_SOURCE_LOCATION (decl), |
1350 VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl)); | |
1234 DECL_CONTEXT (new_decl) = info->context; | 1351 DECL_CONTEXT (new_decl) = info->context; |
1235 DECL_SOURCE_LOCATION (new_decl) = DECL_SOURCE_LOCATION (decl); | |
1236 DECL_ARTIFICIAL (new_decl) = DECL_ARTIFICIAL (decl); | 1352 DECL_ARTIFICIAL (new_decl) = DECL_ARTIFICIAL (decl); |
1237 DECL_IGNORED_P (new_decl) = DECL_IGNORED_P (decl); | 1353 DECL_IGNORED_P (new_decl) = DECL_IGNORED_P (decl); |
1238 TREE_THIS_VOLATILE (new_decl) = TREE_THIS_VOLATILE (decl); | 1354 TREE_THIS_VOLATILE (new_decl) = TREE_THIS_VOLATILE (decl); |
1239 TREE_SIDE_EFFECTS (new_decl) = TREE_SIDE_EFFECTS (decl); | 1355 TREE_SIDE_EFFECTS (new_decl) = TREE_SIDE_EFFECTS (decl); |
1240 TREE_READONLY (new_decl) = TREE_READONLY (decl); | 1356 TREE_READONLY (new_decl) = TREE_READONLY (decl); |
1241 TREE_ADDRESSABLE (new_decl) = TREE_ADDRESSABLE (decl); | 1357 TREE_ADDRESSABLE (new_decl) = TREE_ADDRESSABLE (decl); |
1242 DECL_SEEN_IN_BIND_EXPR_P (new_decl) = 1; | 1358 DECL_SEEN_IN_BIND_EXPR_P (new_decl) = 1; |
1359 if ((TREE_CODE (decl) == PARM_DECL | |
1360 || TREE_CODE (decl) == RESULT_DECL | |
1361 || TREE_CODE (decl) == VAR_DECL) | |
1362 && DECL_BY_REFERENCE (decl)) | |
1363 DECL_BY_REFERENCE (new_decl) = 1; | |
1243 | 1364 |
1244 SET_DECL_VALUE_EXPR (new_decl, x); | 1365 SET_DECL_VALUE_EXPR (new_decl, x); |
1245 DECL_HAS_VALUE_EXPR_P (new_decl) = 1; | 1366 DECL_HAS_VALUE_EXPR_P (new_decl) = 1; |
1246 *slot = new_decl; | 1367 *slot = new_decl; |
1247 | 1368 |
1322 { | 1443 { |
1323 tree save_context; | 1444 tree save_context; |
1324 | 1445 |
1325 /* Then the frame decl is now addressable. */ | 1446 /* Then the frame decl is now addressable. */ |
1326 TREE_ADDRESSABLE (info->frame_decl) = 1; | 1447 TREE_ADDRESSABLE (info->frame_decl) = 1; |
1327 | 1448 |
1328 save_context = current_function_decl; | 1449 save_context = current_function_decl; |
1329 current_function_decl = info->context; | 1450 current_function_decl = info->context; |
1330 recompute_tree_invariant_for_addr_expr (t); | 1451 recompute_tree_invariant_for_addr_expr (t); |
1331 current_function_decl = save_context; | 1452 current_function_decl = save_context; |
1332 | 1453 |
1537 if (convert_local_omp_clauses (gimple_omp_taskreg_clauses_ptr (stmt), | 1658 if (convert_local_omp_clauses (gimple_omp_taskreg_clauses_ptr (stmt), |
1538 wi)) | 1659 wi)) |
1539 { | 1660 { |
1540 tree c; | 1661 tree c; |
1541 (void) get_frame_type (info); | 1662 (void) get_frame_type (info); |
1542 c = build_omp_clause (OMP_CLAUSE_SHARED); | 1663 c = build_omp_clause (gimple_location (stmt), |
1664 OMP_CLAUSE_SHARED); | |
1543 OMP_CLAUSE_DECL (c) = info->frame_decl; | 1665 OMP_CLAUSE_DECL (c) = info->frame_decl; |
1544 OMP_CLAUSE_CHAIN (c) = gimple_omp_taskreg_clauses (stmt); | 1666 OMP_CLAUSE_CHAIN (c) = gimple_omp_taskreg_clauses (stmt); |
1545 gimple_omp_taskreg_set_clauses (stmt, c); | 1667 gimple_omp_taskreg_set_clauses (stmt, c); |
1546 } | 1668 } |
1547 | 1669 |
1588 case GIMPLE_OMP_MASTER: | 1710 case GIMPLE_OMP_MASTER: |
1589 case GIMPLE_OMP_ORDERED: | 1711 case GIMPLE_OMP_ORDERED: |
1590 walk_body (convert_local_reference_stmt, convert_local_reference_op, | 1712 walk_body (convert_local_reference_stmt, convert_local_reference_op, |
1591 info, gimple_omp_body (stmt)); | 1713 info, gimple_omp_body (stmt)); |
1592 break; | 1714 break; |
1715 | |
1716 case GIMPLE_COND: | |
1717 wi->val_only = true; | |
1718 wi->is_lhs = false; | |
1719 *handled_ops_p = false; | |
1720 return NULL_TREE; | |
1593 | 1721 |
1594 default: | 1722 default: |
1595 /* For every other statement that we are not interested in | 1723 /* For every other statement that we are not interested in |
1596 handling here, let the walker traverse the operands. */ | 1724 handling here, let the walker traverse the operands. */ |
1597 *handled_ops_p = false; | 1725 *handled_ops_p = false; |
1649 when we expand rtl. Enter this association into var_map so that we | 1777 when we expand rtl. Enter this association into var_map so that we |
1650 can insert the new label into the IL during a second pass. */ | 1778 can insert the new label into the IL during a second pass. */ |
1651 slot = pointer_map_insert (i->var_map, label); | 1779 slot = pointer_map_insert (i->var_map, label); |
1652 if (*slot == NULL) | 1780 if (*slot == NULL) |
1653 { | 1781 { |
1654 new_label = create_artificial_label (); | 1782 new_label = create_artificial_label (UNKNOWN_LOCATION); |
1655 DECL_NONLOCAL (new_label) = 1; | 1783 DECL_NONLOCAL (new_label) = 1; |
1656 *slot = new_label; | 1784 *slot = new_label; |
1657 } | 1785 } |
1658 else | 1786 else |
1659 new_label = (tree) *slot; | 1787 new_label = (tree) *slot; |
1660 | 1788 |
1661 /* Build: __builtin_nl_goto(new_label, &chain->nl_goto_field). */ | 1789 /* Build: __builtin_nl_goto(new_label, &chain->nl_goto_field). */ |
1662 field = get_nl_goto_field (i); | 1790 field = get_nl_goto_field (i); |
1663 x = get_frame_field (info, target_context, field, &wi->gsi); | 1791 x = get_frame_field (info, target_context, field, &wi->gsi); |
1664 x = build_addr (x, target_context); | 1792 x = build_addr (x, target_context); |
1665 x = gsi_gimplify_val (info, x, &wi->gsi); | 1793 x = gsi_gimplify_val (info, x, &wi->gsi); |
1754 if (!target_context) | 1882 if (!target_context) |
1755 break; | 1883 break; |
1756 | 1884 |
1757 /* If the nested function doesn't use a static chain, then | 1885 /* If the nested function doesn't use a static chain, then |
1758 it doesn't need a trampoline. */ | 1886 it doesn't need a trampoline. */ |
1759 if (DECL_NO_STATIC_CHAIN (decl)) | 1887 if (!DECL_STATIC_CHAIN (decl)) |
1760 break; | 1888 break; |
1761 | 1889 |
1762 /* If we don't want a trampoline, then don't build one. */ | 1890 /* If we don't want a trampoline, then don't build one. */ |
1763 if (TREE_NO_TRAMPOLINE (t)) | 1891 if (TREE_NO_TRAMPOLINE (t)) |
1764 break; | 1892 break; |
1848 gimple stmt = gsi_stmt (*gsi); | 1976 gimple stmt = gsi_stmt (*gsi); |
1849 | 1977 |
1850 switch (gimple_code (stmt)) | 1978 switch (gimple_code (stmt)) |
1851 { | 1979 { |
1852 case GIMPLE_CALL: | 1980 case GIMPLE_CALL: |
1981 if (gimple_call_chain (stmt)) | |
1982 break; | |
1853 decl = gimple_call_fndecl (stmt); | 1983 decl = gimple_call_fndecl (stmt); |
1854 if (!decl) | 1984 if (!decl) |
1855 break; | 1985 break; |
1856 target_context = decl_function_context (decl); | 1986 target_context = decl_function_context (decl); |
1857 if (target_context && !DECL_NO_STATIC_CHAIN (decl)) | 1987 if (target_context && DECL_STATIC_CHAIN (decl)) |
1858 { | 1988 { |
1859 gimple_call_set_chain (stmt, get_static_chain (info, target_context, | 1989 gimple_call_set_chain (stmt, get_static_chain (info, target_context, |
1860 &wi->gsi)); | 1990 &wi->gsi)); |
1861 info->static_chain_added |= (1 << (info->context != target_context)); | 1991 info->static_chain_added |= (1 << (info->context != target_context)); |
1862 } | 1992 } |
1881 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED) | 2011 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED) |
1882 && OMP_CLAUSE_DECL (c) == decl) | 2012 && OMP_CLAUSE_DECL (c) == decl) |
1883 break; | 2013 break; |
1884 if (c == NULL) | 2014 if (c == NULL) |
1885 { | 2015 { |
1886 c = build_omp_clause (i ? OMP_CLAUSE_FIRSTPRIVATE | 2016 c = build_omp_clause (gimple_location (stmt), |
1887 : OMP_CLAUSE_SHARED); | 2017 i ? OMP_CLAUSE_FIRSTPRIVATE |
2018 : OMP_CLAUSE_SHARED); | |
1888 OMP_CLAUSE_DECL (c) = decl; | 2019 OMP_CLAUSE_DECL (c) = decl; |
1889 OMP_CLAUSE_CHAIN (c) = gimple_omp_taskreg_clauses (stmt); | 2020 OMP_CLAUSE_CHAIN (c) = gimple_omp_taskreg_clauses (stmt); |
1890 gimple_omp_taskreg_set_clauses (stmt, c); | 2021 gimple_omp_taskreg_set_clauses (stmt, c); |
1891 } | 2022 } |
1892 } | 2023 } |
1914 | 2045 |
1915 *handled_ops_p = true; | 2046 *handled_ops_p = true; |
1916 return NULL_TREE; | 2047 return NULL_TREE; |
1917 } | 2048 } |
1918 | 2049 |
1919 | 2050 /* Walk the nesting tree starting with ROOT. Convert all trampolines and |
1920 /* Walk the nesting tree starting with ROOT, depth first. Convert all | 2051 call expressions. At the same time, determine if a nested function |
1921 trampolines and call expressions. On the way back up, determine if | 2052 actually uses its static chain; if not, remember that. */ |
1922 a nested function actually uses its static chain; if not, remember that. */ | |
1923 | 2053 |
1924 static void | 2054 static void |
1925 convert_all_function_calls (struct nesting_info *root) | 2055 convert_all_function_calls (struct nesting_info *root) |
1926 { | 2056 { |
2057 struct nesting_info *n; | |
2058 int iter_count; | |
2059 bool any_changed; | |
2060 | |
2061 /* First, optimistically clear static_chain for all decls that haven't | |
2062 used the static chain already for variable access. */ | |
2063 FOR_EACH_NEST_INFO (n, root) | |
2064 { | |
2065 tree decl = n->context; | |
2066 if (!n->outer || (!n->chain_decl && !n->chain_field)) | |
2067 { | |
2068 DECL_STATIC_CHAIN (decl) = 0; | |
2069 if (dump_file && (dump_flags & TDF_DETAILS)) | |
2070 fprintf (dump_file, "Guessing no static-chain for %s\n", | |
2071 lang_hooks.decl_printable_name (decl, 2)); | |
2072 } | |
2073 else | |
2074 DECL_STATIC_CHAIN (decl) = 1; | |
2075 } | |
2076 | |
2077 /* Walk the functions and perform transformations. Note that these | |
2078 transformations can induce new uses of the static chain, which in turn | |
2079 require re-examining all users of the decl. */ | |
2080 /* ??? It would make sense to try to use the call graph to speed this up, | |
2081 but the call graph hasn't really been built yet. Even if it did, we | |
2082 would still need to iterate in this loop since address-of references | |
2083 wouldn't show up in the callgraph anyway. */ | |
2084 iter_count = 0; | |
1927 do | 2085 do |
1928 { | 2086 { |
1929 if (root->inner) | 2087 any_changed = false; |
1930 convert_all_function_calls (root->inner); | 2088 iter_count++; |
1931 | 2089 |
1932 walk_function (convert_tramp_reference_stmt, convert_tramp_reference_op, | 2090 if (dump_file && (dump_flags & TDF_DETAILS)) |
1933 root); | 2091 fputc ('\n', dump_file); |
1934 walk_function (convert_gimple_call, NULL, root); | 2092 |
1935 | 2093 FOR_EACH_NEST_INFO (n, root) |
1936 /* If the function does not use a static chain, then remember that. */ | 2094 { |
1937 if (root->outer && !root->chain_decl && !root->chain_field) | 2095 tree decl = n->context; |
1938 DECL_NO_STATIC_CHAIN (root->context) = 1; | 2096 bool old_static_chain = DECL_STATIC_CHAIN (decl); |
1939 else | 2097 |
1940 gcc_assert (!DECL_NO_STATIC_CHAIN (root->context)); | 2098 walk_function (convert_tramp_reference_stmt, |
1941 | 2099 convert_tramp_reference_op, n); |
1942 root = root->next; | 2100 walk_function (convert_gimple_call, NULL, n); |
1943 } | 2101 |
1944 while (root); | 2102 /* If a call to another function created the use of a chain |
2103 within this function, we'll have to continue iteration. */ | |
2104 if (!old_static_chain && DECL_STATIC_CHAIN (decl)) | |
2105 any_changed = true; | |
2106 } | |
2107 } | |
2108 while (any_changed); | |
2109 | |
2110 if (dump_file && (dump_flags & TDF_DETAILS)) | |
2111 fprintf (dump_file, "convert_all_function_calls iterations: %d\n\n", | |
2112 iter_count); | |
2113 } | |
2114 | |
2115 struct nesting_copy_body_data | |
2116 { | |
2117 copy_body_data cb; | |
2118 struct nesting_info *root; | |
2119 }; | |
2120 | |
2121 /* A helper subroutine for debug_var_chain type remapping. */ | |
2122 | |
2123 static tree | |
2124 nesting_copy_decl (tree decl, copy_body_data *id) | |
2125 { | |
2126 struct nesting_copy_body_data *nid = (struct nesting_copy_body_data *) id; | |
2127 void **slot = pointer_map_contains (nid->root->var_map, decl); | |
2128 | |
2129 if (slot) | |
2130 return (tree) *slot; | |
2131 | |
2132 if (TREE_CODE (decl) == TYPE_DECL && DECL_ORIGINAL_TYPE (decl)) | |
2133 { | |
2134 tree new_decl = copy_decl_no_change (decl, id); | |
2135 DECL_ORIGINAL_TYPE (new_decl) | |
2136 = remap_type (DECL_ORIGINAL_TYPE (decl), id); | |
2137 return new_decl; | |
2138 } | |
2139 | |
2140 if (TREE_CODE (decl) == VAR_DECL | |
2141 || TREE_CODE (decl) == PARM_DECL | |
2142 || TREE_CODE (decl) == RESULT_DECL) | |
2143 return decl; | |
2144 | |
2145 return copy_decl_no_change (decl, id); | |
2146 } | |
2147 | |
2148 /* A helper function for remap_vla_decls. See if *TP contains | |
2149 some remapped variables. */ | |
2150 | |
2151 static tree | |
2152 contains_remapped_vars (tree *tp, int *walk_subtrees, void *data) | |
2153 { | |
2154 struct nesting_info *root = (struct nesting_info *) data; | |
2155 tree t = *tp; | |
2156 void **slot; | |
2157 | |
2158 if (DECL_P (t)) | |
2159 { | |
2160 *walk_subtrees = 0; | |
2161 slot = pointer_map_contains (root->var_map, t); | |
2162 | |
2163 if (slot) | |
2164 return (tree) *slot; | |
2165 } | |
2166 return NULL; | |
2167 } | |
2168 | |
2169 /* Remap VLA decls in BLOCK and subblocks if remapped variables are | |
2170 involved. */ | |
2171 | |
2172 static void | |
2173 remap_vla_decls (tree block, struct nesting_info *root) | |
2174 { | |
2175 tree var, subblock, val, type; | |
2176 struct nesting_copy_body_data id; | |
2177 | |
2178 for (subblock = BLOCK_SUBBLOCKS (block); | |
2179 subblock; | |
2180 subblock = BLOCK_CHAIN (subblock)) | |
2181 remap_vla_decls (subblock, root); | |
2182 | |
2183 for (var = BLOCK_VARS (block); var; var = TREE_CHAIN (var)) | |
2184 { | |
2185 if (TREE_CODE (var) == VAR_DECL | |
2186 && variably_modified_type_p (TREE_TYPE (var), NULL) | |
2187 && DECL_HAS_VALUE_EXPR_P (var)) | |
2188 { | |
2189 type = TREE_TYPE (var); | |
2190 val = DECL_VALUE_EXPR (var); | |
2191 if (walk_tree (&type, contains_remapped_vars, root, NULL) != NULL | |
2192 || walk_tree (&val, contains_remapped_vars, root, NULL) != NULL) | |
2193 break; | |
2194 } | |
2195 } | |
2196 if (var == NULL_TREE) | |
2197 return; | |
2198 | |
2199 memset (&id, 0, sizeof (id)); | |
2200 id.cb.copy_decl = nesting_copy_decl; | |
2201 id.cb.decl_map = pointer_map_create (); | |
2202 id.root = root; | |
2203 | |
2204 for (; var; var = TREE_CHAIN (var)) | |
2205 if (TREE_CODE (var) == VAR_DECL | |
2206 && variably_modified_type_p (TREE_TYPE (var), NULL) | |
2207 && DECL_HAS_VALUE_EXPR_P (var)) | |
2208 { | |
2209 struct nesting_info *i; | |
2210 tree newt, t, context; | |
2211 | |
2212 t = type = TREE_TYPE (var); | |
2213 val = DECL_VALUE_EXPR (var); | |
2214 if (walk_tree (&type, contains_remapped_vars, root, NULL) == NULL | |
2215 && walk_tree (&val, contains_remapped_vars, root, NULL) == NULL) | |
2216 continue; | |
2217 | |
2218 context = decl_function_context (var); | |
2219 for (i = root; i; i = i->outer) | |
2220 if (i->context == context) | |
2221 break; | |
2222 | |
2223 if (i == NULL) | |
2224 continue; | |
2225 | |
2226 id.cb.src_fn = i->context; | |
2227 id.cb.dst_fn = i->context; | |
2228 id.cb.src_cfun = DECL_STRUCT_FUNCTION (root->context); | |
2229 | |
2230 TREE_TYPE (var) = newt = remap_type (type, &id.cb); | |
2231 while (POINTER_TYPE_P (newt) && !TYPE_NAME (newt)) | |
2232 { | |
2233 newt = TREE_TYPE (newt); | |
2234 t = TREE_TYPE (t); | |
2235 } | |
2236 if (TYPE_NAME (newt) | |
2237 && TREE_CODE (TYPE_NAME (newt)) == TYPE_DECL | |
2238 && DECL_ORIGINAL_TYPE (TYPE_NAME (newt)) | |
2239 && newt != t | |
2240 && TYPE_NAME (newt) == TYPE_NAME (t)) | |
2241 TYPE_NAME (newt) = remap_decl (TYPE_NAME (newt), &id.cb); | |
2242 | |
2243 walk_tree (&val, copy_tree_body_r, &id.cb, NULL); | |
2244 if (val != DECL_VALUE_EXPR (var)) | |
2245 SET_DECL_VALUE_EXPR (var, val); | |
2246 } | |
2247 | |
2248 pointer_map_destroy (id.cb.decl_map); | |
1945 } | 2249 } |
1946 | 2250 |
1947 /* Do "everything else" to clean up or complete state collected by the | 2251 /* Do "everything else" to clean up or complete state collected by the |
1948 various walking passes -- lay out the types and decls, generate code | 2252 various walking passes -- lay out the types and decls, generate code |
1949 to initialize the frame decl, store critical expressions in the | 2253 to initialize the frame decl, store critical expressions in the |
1964 if (root->frame_type) | 2268 if (root->frame_type) |
1965 { | 2269 { |
1966 /* In some cases the frame type will trigger the -Wpadded warning. | 2270 /* In some cases the frame type will trigger the -Wpadded warning. |
1967 This is not helpful; suppress it. */ | 2271 This is not helpful; suppress it. */ |
1968 int save_warn_padded = warn_padded; | 2272 int save_warn_padded = warn_padded; |
2273 tree *adjust; | |
2274 | |
1969 warn_padded = 0; | 2275 warn_padded = 0; |
1970 layout_type (root->frame_type); | 2276 layout_type (root->frame_type); |
1971 warn_padded = save_warn_padded; | 2277 warn_padded = save_warn_padded; |
1972 layout_decl (root->frame_decl, 0); | 2278 layout_decl (root->frame_decl, 0); |
1973 } | 2279 |
1974 | 2280 /* Remove root->frame_decl from root->new_local_var_chain, so |
1975 /* If any parameters were referenced non-locally, then we need to | 2281 that we can declare it also in the lexical blocks, which |
2282 helps ensure virtual regs that end up appearing in its RTL | |
2283 expression get substituted in instantiate_virtual_regs(). */ | |
2284 for (adjust = &root->new_local_var_chain; | |
2285 *adjust != root->frame_decl; | |
2286 adjust = &TREE_CHAIN (*adjust)) | |
2287 gcc_assert (TREE_CHAIN (*adjust)); | |
2288 *adjust = TREE_CHAIN (*adjust); | |
2289 | |
2290 TREE_CHAIN (root->frame_decl) = NULL_TREE; | |
2291 declare_vars (root->frame_decl, | |
2292 gimple_seq_first_stmt (gimple_body (context)), true); | |
2293 } | |
2294 | |
2295 /* If any parameters were referenced non-locally, then we need to | |
1976 insert a copy. Likewise, if any variables were referenced by | 2296 insert a copy. Likewise, if any variables were referenced by |
1977 pointer, we need to initialize the address. */ | 2297 pointer, we need to initialize the address. */ |
1978 if (root->any_parm_remapped) | 2298 if (root->any_parm_remapped) |
1979 { | 2299 { |
1980 tree p; | 2300 tree p; |
2027 | 2347 |
2028 field = lookup_tramp_for_decl (root, i->context, NO_INSERT); | 2348 field = lookup_tramp_for_decl (root, i->context, NO_INSERT); |
2029 if (!field) | 2349 if (!field) |
2030 continue; | 2350 continue; |
2031 | 2351 |
2032 if (DECL_NO_STATIC_CHAIN (i->context)) | 2352 gcc_assert (DECL_STATIC_CHAIN (i->context)); |
2033 arg3 = null_pointer_node; | 2353 arg3 = build_addr (root->frame_decl, context); |
2034 else | |
2035 arg3 = build_addr (root->frame_decl, context); | |
2036 | 2354 |
2037 arg2 = build_addr (i->context, context); | 2355 arg2 = build_addr (i->context, context); |
2038 | 2356 |
2039 x = build3 (COMPONENT_REF, TREE_TYPE (field), | 2357 x = build3 (COMPONENT_REF, TREE_TYPE (field), |
2040 root->frame_decl, field, NULL_TREE); | 2358 root->frame_decl, field, NULL_TREE); |
2074 proper BIND_EXPR. */ | 2392 proper BIND_EXPR. */ |
2075 if (root->new_local_var_chain) | 2393 if (root->new_local_var_chain) |
2076 declare_vars (root->new_local_var_chain, | 2394 declare_vars (root->new_local_var_chain, |
2077 gimple_seq_first_stmt (gimple_body (root->context)), | 2395 gimple_seq_first_stmt (gimple_body (root->context)), |
2078 false); | 2396 false); |
2397 | |
2079 if (root->debug_var_chain) | 2398 if (root->debug_var_chain) |
2080 declare_vars (root->debug_var_chain, | 2399 { |
2081 gimple_seq_first_stmt (gimple_body (root->context)), | 2400 tree debug_var; |
2082 true); | 2401 gimple scope; |
2402 | |
2403 remap_vla_decls (DECL_INITIAL (root->context), root); | |
2404 | |
2405 for (debug_var = root->debug_var_chain; debug_var; | |
2406 debug_var = TREE_CHAIN (debug_var)) | |
2407 if (variably_modified_type_p (TREE_TYPE (debug_var), NULL)) | |
2408 break; | |
2409 | |
2410 /* If there are any debug decls with variable length types, | |
2411 remap those types using other debug_var_chain variables. */ | |
2412 if (debug_var) | |
2413 { | |
2414 struct nesting_copy_body_data id; | |
2415 | |
2416 memset (&id, 0, sizeof (id)); | |
2417 id.cb.copy_decl = nesting_copy_decl; | |
2418 id.cb.decl_map = pointer_map_create (); | |
2419 id.root = root; | |
2420 | |
2421 for (; debug_var; debug_var = TREE_CHAIN (debug_var)) | |
2422 if (variably_modified_type_p (TREE_TYPE (debug_var), NULL)) | |
2423 { | |
2424 tree type = TREE_TYPE (debug_var); | |
2425 tree newt, t = type; | |
2426 struct nesting_info *i; | |
2427 | |
2428 for (i = root; i; i = i->outer) | |
2429 if (variably_modified_type_p (type, i->context)) | |
2430 break; | |
2431 | |
2432 if (i == NULL) | |
2433 continue; | |
2434 | |
2435 id.cb.src_fn = i->context; | |
2436 id.cb.dst_fn = i->context; | |
2437 id.cb.src_cfun = DECL_STRUCT_FUNCTION (root->context); | |
2438 | |
2439 TREE_TYPE (debug_var) = newt = remap_type (type, &id.cb); | |
2440 while (POINTER_TYPE_P (newt) && !TYPE_NAME (newt)) | |
2441 { | |
2442 newt = TREE_TYPE (newt); | |
2443 t = TREE_TYPE (t); | |
2444 } | |
2445 if (TYPE_NAME (newt) | |
2446 && TREE_CODE (TYPE_NAME (newt)) == TYPE_DECL | |
2447 && DECL_ORIGINAL_TYPE (TYPE_NAME (newt)) | |
2448 && newt != t | |
2449 && TYPE_NAME (newt) == TYPE_NAME (t)) | |
2450 TYPE_NAME (newt) = remap_decl (TYPE_NAME (newt), &id.cb); | |
2451 } | |
2452 | |
2453 pointer_map_destroy (id.cb.decl_map); | |
2454 } | |
2455 | |
2456 scope = gimple_seq_first_stmt (gimple_body (root->context)); | |
2457 if (gimple_bind_block (scope)) | |
2458 declare_vars (root->debug_var_chain, scope, true); | |
2459 else | |
2460 BLOCK_VARS (DECL_INITIAL (root->context)) | |
2461 = chainon (BLOCK_VARS (DECL_INITIAL (root->context)), | |
2462 root->debug_var_chain); | |
2463 } | |
2083 | 2464 |
2084 /* Dump the translated tree function. */ | 2465 /* Dump the translated tree function. */ |
2085 dump_function (TDI_nested, root->context); | 2466 if (dump_file) |
2467 { | |
2468 fputs ("\n\n", dump_file); | |
2469 dump_function_to_file (root->context, dump_file, dump_flags); | |
2470 } | |
2086 } | 2471 } |
2087 | 2472 |
2088 static void | 2473 static void |
2089 finalize_nesting_tree (struct nesting_info *root) | 2474 finalize_nesting_tree (struct nesting_info *root) |
2090 { | 2475 { |
2091 do | 2476 struct nesting_info *n; |
2092 { | 2477 FOR_EACH_NEST_INFO (n, root) |
2093 if (root->inner) | 2478 finalize_nesting_tree_1 (n); |
2094 finalize_nesting_tree (root->inner); | |
2095 finalize_nesting_tree_1 (root); | |
2096 root = root->next; | |
2097 } | |
2098 while (root); | |
2099 } | 2479 } |
2100 | 2480 |
2101 /* Unnest the nodes and pass them to cgraph. */ | 2481 /* Unnest the nodes and pass them to cgraph. */ |
2102 | 2482 |
2103 static void | 2483 static void |
2115 } | 2495 } |
2116 | 2496 |
2117 static void | 2497 static void |
2118 unnest_nesting_tree (struct nesting_info *root) | 2498 unnest_nesting_tree (struct nesting_info *root) |
2119 { | 2499 { |
2120 do | 2500 struct nesting_info *n; |
2121 { | 2501 FOR_EACH_NEST_INFO (n, root) |
2122 if (root->inner) | 2502 unnest_nesting_tree_1 (n); |
2123 unnest_nesting_tree (root->inner); | |
2124 unnest_nesting_tree_1 (root); | |
2125 root = root->next; | |
2126 } | |
2127 while (root); | |
2128 } | 2503 } |
2129 | 2504 |
2130 /* Free the data structures allocated during this pass. */ | 2505 /* Free the data structures allocated during this pass. */ |
2131 | 2506 |
2132 static void | 2507 static void |
2133 free_nesting_tree (struct nesting_info *root) | 2508 free_nesting_tree (struct nesting_info *root) |
2134 { | 2509 { |
2135 struct nesting_info *next; | 2510 struct nesting_info *node, *next; |
2511 | |
2512 node = iter_nestinfo_start (root); | |
2136 do | 2513 do |
2137 { | 2514 { |
2138 if (root->inner) | 2515 next = iter_nestinfo_next (node); |
2139 free_nesting_tree (root->inner); | 2516 pointer_map_destroy (node->var_map); |
2140 pointer_map_destroy (root->var_map); | 2517 pointer_map_destroy (node->field_map); |
2141 pointer_map_destroy (root->field_map); | 2518 free (node); |
2142 next = root->next; | 2519 node = next; |
2143 free (root); | 2520 } |
2144 root = next; | 2521 while (node); |
2145 } | 2522 } |
2146 while (root); | 2523 |
2524 /* Gimplify a function and all its nested functions. */ | |
2525 static void | |
2526 gimplify_all_functions (struct cgraph_node *root) | |
2527 { | |
2528 struct cgraph_node *iter; | |
2529 if (!gimple_body (root->decl)) | |
2530 gimplify_function_tree (root->decl); | |
2531 for (iter = root->nested; iter; iter = iter->next_nested) | |
2532 gimplify_all_functions (iter); | |
2147 } | 2533 } |
2148 | 2534 |
2149 /* Main entry point for this pass. Process FNDECL and all of its nested | 2535 /* Main entry point for this pass. Process FNDECL and all of its nested |
2150 subroutines and turn them into something less tightly bound. */ | 2536 subroutines and turn them into something less tightly bound. */ |
2151 | 2537 |
2158 /* If there are no nested functions, there's nothing to do. */ | 2544 /* If there are no nested functions, there's nothing to do. */ |
2159 cgn = cgraph_node (fndecl); | 2545 cgn = cgraph_node (fndecl); |
2160 if (!cgn->nested) | 2546 if (!cgn->nested) |
2161 return; | 2547 return; |
2162 | 2548 |
2549 gimplify_all_functions (cgn); | |
2550 | |
2551 dump_file = dump_begin (TDI_nested, &dump_flags); | |
2552 if (dump_file) | |
2553 fprintf (dump_file, "\n;; Function %s\n\n", | |
2554 lang_hooks.decl_printable_name (fndecl, 2)); | |
2555 | |
2163 bitmap_obstack_initialize (&nesting_info_bitmap_obstack); | 2556 bitmap_obstack_initialize (&nesting_info_bitmap_obstack); |
2164 root = create_nesting_tree (cgn); | 2557 root = create_nesting_tree (cgn); |
2558 | |
2165 walk_all_functions (convert_nonlocal_reference_stmt, | 2559 walk_all_functions (convert_nonlocal_reference_stmt, |
2166 convert_nonlocal_reference_op, | 2560 convert_nonlocal_reference_op, |
2167 root); | 2561 root); |
2168 walk_all_functions (convert_local_reference_stmt, | 2562 walk_all_functions (convert_local_reference_stmt, |
2169 convert_local_reference_op, | 2563 convert_local_reference_op, |
2170 root); | 2564 root); |
2171 walk_all_functions (convert_nl_goto_reference, NULL, root); | 2565 walk_all_functions (convert_nl_goto_reference, NULL, root); |
2172 walk_all_functions (convert_nl_goto_receiver, NULL, root); | 2566 walk_all_functions (convert_nl_goto_receiver, NULL, root); |
2567 | |
2173 convert_all_function_calls (root); | 2568 convert_all_function_calls (root); |
2174 finalize_nesting_tree (root); | 2569 finalize_nesting_tree (root); |
2175 unnest_nesting_tree (root); | 2570 unnest_nesting_tree (root); |
2571 | |
2176 free_nesting_tree (root); | 2572 free_nesting_tree (root); |
2177 bitmap_obstack_release (&nesting_info_bitmap_obstack); | 2573 bitmap_obstack_release (&nesting_info_bitmap_obstack); |
2574 | |
2575 if (dump_file) | |
2576 { | |
2577 dump_end (TDI_nested, dump_file); | |
2578 dump_file = NULL; | |
2579 } | |
2178 } | 2580 } |
2179 | 2581 |
2180 #include "gt-tree-nested.h" | 2582 #include "gt-tree-nested.h" |