00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "config.h"
00022 #include "system.h"
00023 #include "coretypes.h"
00024 #include "tm.h"
00025 #include "tree.h"
00026 #include "rtl.h"
00027 #include "tm_p.h"
00028 #include "function.h"
00029 #include "tree-dump.h"
00030 #include "tree-inline.h"
00031 #include "tree-gimple.h"
00032 #include "tree-iterator.h"
00033 #include "tree-flow.h"
00034 #include "cgraph.h"
00035 #include "expr.h"
00036 #include "langhooks.h"
00037 #include "ggc.h"
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 struct var_map_elt GTY(())
00081 {
00082 tree old;
00083 tree new;
00084 };
00085
00086 struct nesting_info GTY ((chain_next ("%h.next")))
00087 {
00088 struct nesting_info *outer;
00089 struct nesting_info *inner;
00090 struct nesting_info *next;
00091
00092 htab_t GTY ((param_is (struct var_map_elt))) field_map;
00093 htab_t GTY ((param_is (struct var_map_elt))) var_map;
00094 bitmap suppress_expansion;
00095
00096 tree context;
00097 tree new_local_var_chain;
00098 tree debug_var_chain;
00099 tree frame_type;
00100 tree frame_decl;
00101 tree chain_field;
00102 tree chain_decl;
00103 tree nl_goto_field;
00104
00105 bool any_parm_remapped;
00106 bool any_tramp_created;
00107 };
00108
00109
00110
00111
00112 static hashval_t
00113 var_map_hash (const void *x)
00114 {
00115 const struct var_map_elt *a = (const struct var_map_elt *) x;
00116 return htab_hash_pointer (a->old);
00117 }
00118
00119 static int
00120 var_map_eq (const void *x, const void *y)
00121 {
00122 const struct var_map_elt *a = (const struct var_map_elt *) x;
00123 const struct var_map_elt *b = (const struct var_map_elt *) y;
00124 return a->old == b->old;
00125 }
00126
00127
00128
00129 #define create_tmp_var cant_use_create_tmp_var_here_dummy
00130
00131
00132
00133
00134 static tree
00135 create_tmp_var_for (struct nesting_info *info, tree type, const char *prefix)
00136 {
00137 tree tmp_var;
00138
00139
00140
00141
00142 gcc_assert (!TREE_ADDRESSABLE (type));
00143 gcc_assert (!TYPE_SIZE_UNIT (type)
00144 || TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST);
00145
00146 tmp_var = create_tmp_var_raw (type, prefix);
00147 DECL_CONTEXT (tmp_var) = info->context;
00148 TREE_CHAIN (tmp_var) = info->new_local_var_chain;
00149 DECL_SEEN_IN_BIND_EXPR_P (tmp_var) = 1;
00150 if (TREE_CODE (type) == COMPLEX_TYPE)
00151 DECL_COMPLEX_GIMPLE_REG_P (tmp_var) = 1;
00152
00153 info->new_local_var_chain = tmp_var;
00154
00155 return tmp_var;
00156 }
00157
00158
00159
00160
00161 tree
00162 build_addr (tree exp, tree context)
00163 {
00164 tree base = exp;
00165 tree save_context;
00166 tree retval;
00167
00168 while (handled_component_p (base))
00169 base = TREE_OPERAND (base, 0);
00170
00171 if (DECL_P (base))
00172 TREE_ADDRESSABLE (base) = 1;
00173
00174
00175
00176
00177
00178
00179
00180
00181 save_context = current_function_decl;
00182 current_function_decl = context;
00183 retval = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (exp)), exp);
00184 current_function_decl = save_context;;
00185 return retval;
00186 }
00187
00188
00189
00190 void
00191 insert_field_into_struct (tree type, tree field)
00192 {
00193 tree *p;
00194
00195 DECL_CONTEXT (field) = type;
00196
00197 for (p = &TYPE_FIELDS (type); *p ; p = &TREE_CHAIN (*p))
00198 if (DECL_ALIGN (field) >= DECL_ALIGN (*p))
00199 break;
00200
00201 TREE_CHAIN (field) = *p;
00202 *p = field;
00203 }
00204
00205
00206
00207
00208
00209
00210
00211
00212 static tree
00213 get_frame_type (struct nesting_info *info)
00214 {
00215 tree type = info->frame_type;
00216 if (!type)
00217 {
00218 char *name;
00219
00220 type = make_node (RECORD_TYPE);
00221
00222 name = concat ("FRAME.",
00223 IDENTIFIER_POINTER (DECL_NAME (info->context)),
00224 NULL);
00225 TYPE_NAME (type) = get_identifier (name);
00226 free (name);
00227
00228 info->frame_type = type;
00229 info->frame_decl = create_tmp_var_for (info, type, "FRAME");
00230
00231
00232
00233
00234
00235
00236
00237 TREE_ADDRESSABLE (info->frame_decl) = 1;
00238 }
00239 return type;
00240 }
00241
00242
00243
00244
00245 static bool
00246 use_pointer_in_frame (tree decl)
00247 {
00248 if (TREE_CODE (decl) == PARM_DECL)
00249 {
00250
00251
00252
00253 return AGGREGATE_TYPE_P (TREE_TYPE (decl));
00254 }
00255 else
00256 {
00257
00258 return DECL_SIZE (decl) == NULL || !TREE_CONSTANT (DECL_SIZE (decl));
00259 }
00260 }
00261
00262
00263
00264
00265 static tree
00266 lookup_field_for_decl (struct nesting_info *info, tree decl,
00267 enum insert_option insert)
00268 {
00269 struct var_map_elt *elt, dummy;
00270 void **slot;
00271 tree field;
00272
00273 dummy.old = decl;
00274 slot = htab_find_slot (info->field_map, &dummy, insert);
00275 if (!slot)
00276 {
00277 gcc_assert (insert != INSERT);
00278 return NULL;
00279 }
00280 elt = (struct var_map_elt *) *slot;
00281
00282 if (!elt && insert == INSERT)
00283 {
00284 field = make_node (FIELD_DECL);
00285 DECL_NAME (field) = DECL_NAME (decl);
00286
00287 if (use_pointer_in_frame (decl))
00288 {
00289 TREE_TYPE (field) = build_pointer_type (TREE_TYPE (decl));
00290 DECL_ALIGN (field) = TYPE_ALIGN (TREE_TYPE (field));
00291 DECL_NONADDRESSABLE_P (field) = 1;
00292 }
00293 else
00294 {
00295 TREE_TYPE (field) = TREE_TYPE (decl);
00296 DECL_SOURCE_LOCATION (field) = DECL_SOURCE_LOCATION (decl);
00297 DECL_ALIGN (field) = DECL_ALIGN (decl);
00298 DECL_USER_ALIGN (field) = DECL_USER_ALIGN (decl);
00299 TREE_ADDRESSABLE (field) = TREE_ADDRESSABLE (decl);
00300 DECL_NONADDRESSABLE_P (field) = !TREE_ADDRESSABLE (decl);
00301 TREE_THIS_VOLATILE (field) = TREE_THIS_VOLATILE (decl);
00302 }
00303
00304 insert_field_into_struct (get_frame_type (info), field);
00305
00306 elt = GGC_NEW (struct var_map_elt);
00307 elt->old = decl;
00308 elt->new = field;
00309 *slot = elt;
00310
00311 if (TREE_CODE (decl) == PARM_DECL)
00312 info->any_parm_remapped = true;
00313 }
00314 else
00315 field = elt ? elt->new : NULL;
00316
00317 return field;
00318 }
00319
00320
00321
00322
00323 static tree
00324 get_chain_decl (struct nesting_info *info)
00325 {
00326 tree decl = info->chain_decl;
00327 if (!decl)
00328 {
00329 tree type;
00330
00331 type = get_frame_type (info->outer);
00332 type = build_pointer_type (type);
00333
00334
00335
00336
00337
00338
00339
00340 decl = build_decl (PARM_DECL, create_tmp_var_name ("CHAIN"), type);
00341 DECL_ARTIFICIAL (decl) = 1;
00342 DECL_IGNORED_P (decl) = 1;
00343 TREE_USED (decl) = 1;
00344 DECL_CONTEXT (decl) = info->context;
00345 DECL_ARG_TYPE (decl) = type;
00346
00347
00348
00349 TREE_READONLY (decl) = 1;
00350
00351 info->chain_decl = decl;
00352 }
00353 return decl;
00354 }
00355
00356
00357
00358
00359
00360 static tree
00361 get_chain_field (struct nesting_info *info)
00362 {
00363 tree field = info->chain_field;
00364 if (!field)
00365 {
00366 tree type = build_pointer_type (get_frame_type (info->outer));
00367
00368 field = make_node (FIELD_DECL);
00369 DECL_NAME (field) = get_identifier ("__chain");
00370 TREE_TYPE (field) = type;
00371 DECL_ALIGN (field) = TYPE_ALIGN (type);
00372 DECL_NONADDRESSABLE_P (field) = 1;
00373
00374 insert_field_into_struct (get_frame_type (info), field);
00375
00376 info->chain_field = field;
00377 }
00378 return field;
00379 }
00380
00381
00382
00383
00384 static tree
00385 init_tmp_var (struct nesting_info *info, tree exp, tree_stmt_iterator *tsi)
00386 {
00387 tree t, stmt;
00388
00389 t = create_tmp_var_for (info, TREE_TYPE (exp), NULL);
00390 stmt = build2 (MODIFY_EXPR, TREE_TYPE (t), t, exp);
00391 SET_EXPR_LOCUS (stmt, EXPR_LOCUS (tsi_stmt (*tsi)));
00392 tsi_link_before (tsi, stmt, TSI_SAME_STMT);
00393
00394 return t;
00395 }
00396
00397
00398
00399 static tree
00400 tsi_gimplify_val (struct nesting_info *info, tree exp, tree_stmt_iterator *tsi)
00401 {
00402 if (is_gimple_val (exp))
00403 return exp;
00404 else
00405 return init_tmp_var (info, exp, tsi);
00406 }
00407
00408
00409
00410
00411 static tree
00412 save_tmp_var (struct nesting_info *info, tree exp,
00413 tree_stmt_iterator *tsi)
00414 {
00415 tree t, stmt;
00416
00417 t = create_tmp_var_for (info, TREE_TYPE (exp), NULL);
00418 stmt = build2 (MODIFY_EXPR, TREE_TYPE (t), exp, t);
00419 SET_EXPR_LOCUS (stmt, EXPR_LOCUS (tsi_stmt (*tsi)));
00420 tsi_link_after (tsi, stmt, TSI_SAME_STMT);
00421
00422 return t;
00423 }
00424
00425
00426
00427 static GTY(()) tree trampoline_type;
00428
00429 static tree
00430 get_trampoline_type (void)
00431 {
00432 tree record, t;
00433 unsigned align, size;
00434
00435 if (trampoline_type)
00436 return trampoline_type;
00437
00438 align = TRAMPOLINE_ALIGNMENT;
00439 size = TRAMPOLINE_SIZE;
00440
00441
00442
00443 if (align > STACK_BOUNDARY)
00444 {
00445 size += ((align/BITS_PER_UNIT) - 1) & -(STACK_BOUNDARY/BITS_PER_UNIT);
00446 align = STACK_BOUNDARY;
00447 }
00448
00449 t = build_index_type (build_int_cst (NULL_TREE, size - 1));
00450 t = build_array_type (char_type_node, t);
00451 t = build_decl (FIELD_DECL, get_identifier ("__data"), t);
00452 DECL_ALIGN (t) = align;
00453 DECL_USER_ALIGN (t) = 1;
00454
00455 record = make_node (RECORD_TYPE);
00456 TYPE_NAME (record) = get_identifier ("__builtin_trampoline");
00457 TYPE_FIELDS (record) = t;
00458 layout_type (record);
00459
00460 return record;
00461 }
00462
00463
00464
00465
00466 static tree
00467 lookup_tramp_for_decl (struct nesting_info *info, tree decl,
00468 enum insert_option insert)
00469 {
00470 struct var_map_elt *elt, dummy;
00471 void **slot;
00472 tree field;
00473
00474 dummy.old = decl;
00475 slot = htab_find_slot (info->var_map, &dummy, insert);
00476 if (!slot)
00477 {
00478 gcc_assert (insert != INSERT);
00479 return NULL;
00480 }
00481 elt = (struct var_map_elt *) *slot;
00482
00483 if (!elt && insert == INSERT)
00484 {
00485 field = make_node (FIELD_DECL);
00486 DECL_NAME (field) = DECL_NAME (decl);
00487 TREE_TYPE (field) = get_trampoline_type ();
00488 TREE_ADDRESSABLE (field) = 1;
00489
00490 insert_field_into_struct (get_frame_type (info), field);
00491
00492 elt = GGC_NEW (struct var_map_elt);
00493 elt->old = decl;
00494 elt->new = field;
00495 *slot = elt;
00496
00497 info->any_tramp_created = true;
00498 }
00499 else
00500 field = elt ? elt->new : NULL;
00501
00502 return field;
00503 }
00504
00505
00506
00507
00508
00509 static tree
00510 get_nl_goto_field (struct nesting_info *info)
00511 {
00512 tree field = info->nl_goto_field;
00513 if (!field)
00514 {
00515 unsigned size;
00516 tree type;
00517
00518
00519
00520
00521
00522 if (Pmode == ptr_mode)
00523 type = ptr_type_node;
00524 else
00525 type = lang_hooks.types.type_for_mode (Pmode, 1);
00526
00527 size = GET_MODE_SIZE (STACK_SAVEAREA_MODE (SAVE_NONLOCAL));
00528 size = size / GET_MODE_SIZE (Pmode);
00529 size = size + 1;
00530
00531 type = build_array_type
00532 (type, build_index_type (build_int_cst (NULL_TREE, size)));
00533
00534 field = make_node (FIELD_DECL);
00535 DECL_NAME (field) = get_identifier ("__nl_goto_buf");
00536 TREE_TYPE (field) = type;
00537 DECL_ALIGN (field) = TYPE_ALIGN (type);
00538 TREE_ADDRESSABLE (field) = 1;
00539
00540 insert_field_into_struct (get_frame_type (info), field);
00541
00542 info->nl_goto_field = field;
00543 }
00544
00545 return field;
00546 }
00547
00548
00549
00550
00551 void
00552 walk_stmts (struct walk_stmt_info *wi, tree *tp)
00553 {
00554 tree t = *tp;
00555 int walk_subtrees;
00556
00557 if (!t)
00558 return;
00559
00560 if (wi->want_locations && EXPR_HAS_LOCATION (t))
00561 input_location = EXPR_LOCATION (t);
00562
00563 switch (TREE_CODE (t))
00564 {
00565 case STATEMENT_LIST:
00566 {
00567 tree_stmt_iterator i;
00568 for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
00569 {
00570 wi->tsi = i;
00571 walk_stmts (wi, tsi_stmt_ptr (i));
00572 }
00573 }
00574 break;
00575
00576 case COND_EXPR:
00577 walk_tree (&COND_EXPR_COND (t), wi->callback, wi, NULL);
00578 walk_stmts (wi, &COND_EXPR_THEN (t));
00579 walk_stmts (wi, &COND_EXPR_ELSE (t));
00580 break;
00581 case CATCH_EXPR:
00582 walk_stmts (wi, &CATCH_BODY (t));
00583 break;
00584 case EH_FILTER_EXPR:
00585 walk_stmts (wi, &EH_FILTER_FAILURE (t));
00586 break;
00587 case TRY_CATCH_EXPR:
00588 case TRY_FINALLY_EXPR:
00589 walk_stmts (wi, &TREE_OPERAND (t, 0));
00590 walk_stmts (wi, &TREE_OPERAND (t, 1));
00591 break;
00592
00593 case BIND_EXPR:
00594 if (wi->want_bind_expr)
00595 {
00596 walk_subtrees = 1;
00597 wi->callback (tp, &walk_subtrees, wi);
00598 if (!walk_subtrees)
00599 break;
00600 }
00601 walk_stmts (wi, &BIND_EXPR_BODY (t));
00602 break;
00603
00604 case RETURN_EXPR:
00605 if (wi->want_return_expr)
00606 {
00607 walk_subtrees = 1;
00608 wi->callback (tp, &walk_subtrees, wi);
00609 if (!walk_subtrees)
00610 break;
00611 }
00612 walk_stmts (wi, &TREE_OPERAND (t, 0));
00613 break;
00614
00615 case MODIFY_EXPR:
00616
00617 wi->val_only = !is_gimple_formal_tmp_var (TREE_OPERAND (t, 0));
00618 walk_tree (&TREE_OPERAND (t, 1), wi->callback, wi, NULL);
00619
00620
00621
00622 wi->val_only = !is_gimple_mem_rhs (TREE_OPERAND (t, 1));
00623 wi->is_lhs = true;
00624 walk_tree (&TREE_OPERAND (t, 0), wi->callback, wi, NULL);
00625
00626 wi->val_only = true;
00627 wi->is_lhs = false;
00628 break;
00629
00630 default:
00631 wi->val_only = true;
00632 walk_tree (tp, wi->callback, wi, NULL);
00633 break;
00634 }
00635 }
00636
00637
00638
00639 static void
00640 walk_body (walk_tree_fn callback, struct nesting_info *info, tree *stmt_p)
00641 {
00642 struct walk_stmt_info wi;
00643
00644 memset (&wi, 0, sizeof (wi));
00645 wi.callback = callback;
00646 wi.info = info;
00647 wi.val_only = true;
00648
00649 walk_stmts (&wi, stmt_p);
00650 }
00651
00652
00653
00654 static inline void
00655 walk_function (walk_tree_fn callback, struct nesting_info *info)
00656 {
00657 walk_body (callback, info, &DECL_SAVED_TREE (info->context));
00658 }
00659
00660
00661
00662 static void
00663 walk_all_functions (walk_tree_fn callback, struct nesting_info *root)
00664 {
00665 do
00666 {
00667 if (root->inner)
00668 walk_all_functions (callback, root->inner);
00669 walk_function (callback, root);
00670 root = root->next;
00671 }
00672 while (root);
00673 }
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698 static bool
00699 check_for_nested_with_variably_modified (tree fndecl, tree orig_fndecl)
00700 {
00701 struct cgraph_node *cgn = cgraph_node (fndecl);
00702 tree arg;
00703
00704 for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested)
00705 {
00706 for (arg = DECL_ARGUMENTS (cgn->decl); arg; arg = TREE_CHAIN (arg))
00707 if (variably_modified_type_p (TREE_TYPE (arg), 0), orig_fndecl)
00708 return true;
00709
00710 if (check_for_nested_with_variably_modified (cgn->decl, orig_fndecl))
00711 return true;
00712 }
00713
00714 return false;
00715 }
00716
00717
00718
00719
00720 static struct nesting_info *
00721 create_nesting_tree (struct cgraph_node *cgn)
00722 {
00723 struct nesting_info *info = GGC_CNEW (struct nesting_info);
00724 info->field_map = htab_create_ggc (7, var_map_hash, var_map_eq, ggc_free);
00725 info->var_map = htab_create_ggc (7, var_map_hash, var_map_eq, ggc_free);
00726 info->suppress_expansion = BITMAP_GGC_ALLOC ();
00727 info->context = cgn->decl;
00728
00729 for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested)
00730 {
00731 struct nesting_info *sub = create_nesting_tree (cgn);
00732 sub->outer = info;
00733 sub->next = info->inner;
00734 info->inner = sub;
00735 }
00736
00737
00738
00739 if (check_for_nested_with_variably_modified (info->context, info->context))
00740 DECL_UNINLINABLE (info->context) = true;
00741
00742 return info;
00743 }
00744
00745
00746
00747
00748 static tree
00749 get_static_chain (struct nesting_info *info, tree target_context,
00750 tree_stmt_iterator *tsi)
00751 {
00752 struct nesting_info *i;
00753 tree x;
00754
00755 if (info->context == target_context)
00756 {
00757 x = build_addr (info->frame_decl, target_context);
00758 }
00759 else
00760 {
00761 x = get_chain_decl (info);
00762
00763 for (i = info->outer; i->context != target_context; i = i->outer)
00764 {
00765 tree field = get_chain_field (i);
00766
00767 x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
00768 x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
00769 x = init_tmp_var (info, x, tsi);
00770 }
00771 }
00772
00773 return x;
00774 }
00775
00776
00777
00778
00779
00780 static tree
00781 get_frame_field (struct nesting_info *info, tree target_context,
00782 tree field, tree_stmt_iterator *tsi)
00783 {
00784 struct nesting_info *i;
00785 tree x;
00786
00787 if (info->context == target_context)
00788 {
00789
00790 (void) get_frame_type (info);
00791 x = info->frame_decl;
00792 }
00793 else
00794 {
00795 x = get_chain_decl (info);
00796
00797 for (i = info->outer; i->context != target_context; i = i->outer)
00798 {
00799 tree field = get_chain_field (i);
00800
00801 x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
00802 x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
00803 x = init_tmp_var (info, x, tsi);
00804 }
00805
00806 x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
00807 }
00808
00809 x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
00810 return x;
00811 }
00812
00813
00814
00815
00816
00817
00818 static tree
00819 get_nonlocal_debug_decl (struct nesting_info *info, tree decl)
00820 {
00821 struct var_map_elt *elt, dummy;
00822 tree target_context;
00823 struct nesting_info *i;
00824 tree x, field, new_decl;
00825 void **slot;
00826
00827 dummy.old = decl;
00828 slot = htab_find_slot (info->var_map, &dummy, INSERT);
00829 elt = *slot;
00830
00831 if (elt)
00832 return elt->new;
00833
00834 target_context = decl_function_context (decl);
00835
00836
00837 if (info->context == target_context)
00838 {
00839
00840 (void) get_frame_type (info);
00841 x = info->frame_decl;
00842 i = info;
00843 }
00844 else
00845 {
00846 x = get_chain_decl (info);
00847 for (i = info->outer; i->context != target_context; i = i->outer)
00848 {
00849 field = get_chain_field (i);
00850 x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
00851 x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
00852 }
00853 x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
00854 }
00855
00856 field = lookup_field_for_decl (i, decl, INSERT);
00857 x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
00858 if (use_pointer_in_frame (decl))
00859 x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
00860
00861
00862 new_decl = build_decl (VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
00863 DECL_CONTEXT (new_decl) = info->context;
00864 DECL_SOURCE_LOCATION (new_decl) = DECL_SOURCE_LOCATION (decl);
00865 DECL_ARTIFICIAL (new_decl) = DECL_ARTIFICIAL (decl);
00866 DECL_IGNORED_P (new_decl) = DECL_IGNORED_P (decl);
00867 TREE_THIS_VOLATILE (new_decl) = TREE_THIS_VOLATILE (decl);
00868 TREE_SIDE_EFFECTS (new_decl) = TREE_SIDE_EFFECTS (decl);
00869 TREE_READONLY (new_decl) = TREE_READONLY (decl);
00870 TREE_ADDRESSABLE (new_decl) = TREE_ADDRESSABLE (decl);
00871 DECL_SEEN_IN_BIND_EXPR_P (new_decl) = 1;
00872
00873 SET_DECL_VALUE_EXPR (new_decl, x);
00874 DECL_HAS_VALUE_EXPR_P (new_decl) = 1;
00875
00876 elt = ggc_alloc (sizeof (*elt));
00877 elt->old = decl;
00878 elt->new = new_decl;
00879 *slot = elt;
00880
00881 TREE_CHAIN (new_decl) = info->debug_var_chain;
00882 info->debug_var_chain = new_decl;
00883
00884 return new_decl;
00885 }
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895 static bool convert_nonlocal_omp_clauses (tree *, struct walk_stmt_info *);
00896
00897 static tree
00898 convert_nonlocal_reference (tree *tp, int *walk_subtrees, void *data)
00899 {
00900 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
00901 struct nesting_info *info = wi->info;
00902 tree t = *tp;
00903 tree save_local_var_chain;
00904 bitmap save_suppress;
00905
00906 *walk_subtrees = 0;
00907 switch (TREE_CODE (t))
00908 {
00909 case VAR_DECL:
00910
00911 if (TREE_STATIC (t) || DECL_EXTERNAL (t))
00912 break;
00913
00914
00915 case PARM_DECL:
00916 if (decl_function_context (t) != info->context)
00917 {
00918 tree x;
00919 wi->changed = true;
00920
00921 x = get_nonlocal_debug_decl (info, t);
00922 if (!bitmap_bit_p (info->suppress_expansion, DECL_UID (t)))
00923 {
00924 tree target_context = decl_function_context (t);
00925 struct nesting_info *i;
00926 for (i = info->outer; i->context != target_context; i = i->outer)
00927 continue;
00928 x = lookup_field_for_decl (i, t, INSERT);
00929 x = get_frame_field (info, target_context, x, &wi->tsi);
00930 if (use_pointer_in_frame (t))
00931 {
00932 x = init_tmp_var (info, x, &wi->tsi);
00933 x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
00934 }
00935 }
00936
00937 if (wi->val_only)
00938 {
00939 if (wi->is_lhs)
00940 x = save_tmp_var (info, x, &wi->tsi);
00941 else
00942 x = init_tmp_var (info, x, &wi->tsi);
00943 }
00944
00945 *tp = x;
00946 }
00947 break;
00948
00949 case GOTO_EXPR:
00950
00951 if (TREE_CODE (GOTO_DESTINATION (t)) != LABEL_DECL)
00952 {
00953 *walk_subtrees = 1;
00954 wi->val_only = true;
00955 wi->is_lhs = false;
00956 }
00957 break;
00958
00959 case LABEL_DECL:
00960
00961
00962
00963
00964 if (decl_function_context (t) != info->context)
00965 FORCED_LABEL (t) = 1;
00966 break;
00967
00968 case ADDR_EXPR:
00969 {
00970 bool save_val_only = wi->val_only;
00971
00972 wi->val_only = false;
00973 wi->is_lhs = false;
00974 wi->changed = false;
00975 walk_tree (&TREE_OPERAND (t, 0), convert_nonlocal_reference, wi, NULL);
00976 wi->val_only = true;
00977
00978 if (wi->changed)
00979 {
00980 tree save_context;
00981
00982
00983
00984 save_context = current_function_decl;
00985 current_function_decl = info->context;
00986 recompute_tree_invariant_for_addr_expr (t);
00987 current_function_decl = save_context;
00988
00989
00990
00991
00992 if (save_val_only)
00993 *tp = tsi_gimplify_val (wi->info, t, &wi->tsi);
00994 }
00995 }
00996 break;
00997
00998 case REALPART_EXPR:
00999 case IMAGPART_EXPR:
01000 case COMPONENT_REF:
01001 case ARRAY_REF:
01002 case ARRAY_RANGE_REF:
01003 case BIT_FIELD_REF:
01004
01005
01006
01007 wi->val_only = true;
01008 wi->is_lhs = false;
01009 for (; handled_component_p (t); tp = &TREE_OPERAND (t, 0), t = *tp)
01010 {
01011 if (TREE_CODE (t) == COMPONENT_REF)
01012 walk_tree (&TREE_OPERAND (t, 2), convert_nonlocal_reference, wi,
01013 NULL);
01014 else if (TREE_CODE (t) == ARRAY_REF
01015 || TREE_CODE (t) == ARRAY_RANGE_REF)
01016 {
01017 walk_tree (&TREE_OPERAND (t, 1), convert_nonlocal_reference, wi,
01018 NULL);
01019 walk_tree (&TREE_OPERAND (t, 2), convert_nonlocal_reference, wi,
01020 NULL);
01021 walk_tree (&TREE_OPERAND (t, 3), convert_nonlocal_reference, wi,
01022 NULL);
01023 }
01024 else if (TREE_CODE (t) == BIT_FIELD_REF)
01025 {
01026 walk_tree (&TREE_OPERAND (t, 1), convert_nonlocal_reference, wi,
01027 NULL);
01028 walk_tree (&TREE_OPERAND (t, 2), convert_nonlocal_reference, wi,
01029 NULL);
01030 }
01031 }
01032 wi->val_only = false;
01033 walk_tree (tp, convert_nonlocal_reference, wi, NULL);
01034 break;
01035
01036 case OMP_PARALLEL:
01037 save_suppress = info->suppress_expansion;
01038 if (convert_nonlocal_omp_clauses (&OMP_PARALLEL_CLAUSES (t), wi))
01039 {
01040 tree c, decl;
01041 decl = get_chain_decl (info);
01042 c = build_omp_clause (OMP_CLAUSE_FIRSTPRIVATE);
01043 OMP_CLAUSE_DECL (c) = decl;
01044 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (t);
01045 OMP_PARALLEL_CLAUSES (t) = c;
01046 }
01047
01048 save_local_var_chain = info->new_local_var_chain;
01049 info->new_local_var_chain = NULL;
01050
01051 walk_body (convert_nonlocal_reference, info, &OMP_PARALLEL_BODY (t));
01052
01053 if (info->new_local_var_chain)
01054 declare_vars (info->new_local_var_chain, OMP_PARALLEL_BODY (t), false);
01055 info->new_local_var_chain = save_local_var_chain;
01056 info->suppress_expansion = save_suppress;
01057 break;
01058
01059 case OMP_FOR:
01060 case OMP_SECTIONS:
01061 case OMP_SINGLE:
01062 save_suppress = info->suppress_expansion;
01063 convert_nonlocal_omp_clauses (&OMP_CLAUSES (t), wi);
01064 walk_body (convert_nonlocal_reference, info, &OMP_BODY (t));
01065 info->suppress_expansion = save_suppress;
01066 break;
01067
01068 case OMP_SECTION:
01069 case OMP_MASTER:
01070 case OMP_ORDERED:
01071 walk_body (convert_nonlocal_reference, info, &OMP_BODY (t));
01072 break;
01073
01074 default:
01075 if (!IS_TYPE_OR_DECL_P (t))
01076 {
01077 *walk_subtrees = 1;
01078 wi->val_only = true;
01079 wi->is_lhs = false;
01080 }
01081 break;
01082 }
01083
01084 return NULL_TREE;
01085 }
01086
01087 static bool
01088 convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
01089 {
01090 struct nesting_info *info = wi->info;
01091 bool need_chain = false;
01092 tree clause, decl;
01093 int dummy;
01094 bitmap new_suppress;
01095
01096 new_suppress = BITMAP_GGC_ALLOC ();
01097 bitmap_copy (new_suppress, info->suppress_expansion);
01098
01099 for (clause = *pclauses; clause ; clause = OMP_CLAUSE_CHAIN (clause))
01100 {
01101 switch (OMP_CLAUSE_CODE (clause))
01102 {
01103