tree-nested.c

Go to the documentation of this file.
00001 /* Nested function decomposition for trees.
00002    Copyright (C) 2004, 2005 Free Software Foundation, Inc.
00003 
00004    This file is part of GCC.
00005 
00006    GCC is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2, or (at your option)
00009    any later version.
00010 
00011    GCC is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014    GNU General Public License for more details.
00015 
00016    You should have received a copy of the GNU General Public License
00017    along with GCC; see the file COPYING.  If not, write to
00018    the Free Software Foundation, 51 Franklin Street, Fifth Floor,
00019    Boston, MA 02110-1301, USA.  */
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 /* The object of this pass is to lower the representation of a set of nested
00041    functions in order to expose all of the gory details of the various
00042    nonlocal references.  We want to do this sooner rather than later, in
00043    order to give us more freedom in emitting all of the functions in question.
00044 
00045    Back in olden times, when gcc was young, we developed an insanely 
00046    complicated scheme whereby variables which were referenced nonlocally
00047    were forced to live in the stack of the declaring function, and then
00048    the nested functions magically discovered where these variables were
00049    placed.  In order for this scheme to function properly, it required
00050    that the outer function be partially expanded, then we switch to 
00051    compiling the inner function, and once done with those we switch back
00052    to compiling the outer function.  Such delicate ordering requirements
00053    makes it difficult to do whole translation unit optimizations 
00054    involving such functions.
00055 
00056    The implementation here is much more direct.  Everything that can be
00057    referenced by an inner function is a member of an explicitly created
00058    structure herein called the "nonlocal frame struct".  The incoming
00059    static chain for a nested function is a pointer to this struct in 
00060    the parent.  In this way, we settle on known offsets from a known
00061    base, and so are decoupled from the logic that places objects in the
00062    function's stack frame.  More importantly, we don't have to wait for
00063    that to happen -- since the compilation of the inner function is no
00064    longer tied to a real stack frame, the nonlocal frame struct can be
00065    allocated anywhere.  Which means that the outer function is now
00066    inlinable.
00067 
00068    Theory of operation here is very simple.  Iterate over all the 
00069    statements in all the functions (depth first) several times, 
00070    allocating structures and fields on demand.  In general we want to
00071    examine inner functions first, so that we can avoid making changes
00072    to outer functions which are unnecessary.
00073 
00074    The order of the passes matters a bit, in that later passes will be
00075    skipped if it is discovered that the functions don't actually interact
00076    at all.  That is, they're nested in the lexical sense but could have
00077    been written as independent functions without change.  */
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 /* Hashing and equality functions for nesting_info->var_map.  */
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 /* We're working in so many different function contexts simultaneously,
00128    that create_tmp_var is dangerous.  Prevent mishap.  */
00129 #define create_tmp_var cant_use_create_tmp_var_here_dummy
00130 
00131 /* Like create_tmp_var, except record the variable for registration at
00132    the given nesting level.  */
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   /* If the type is of variable size or a type which must be created by the
00140      frontend, something is wrong.  Note that we explicitly allow
00141      incomplete types here, since we create them ourselves here.  */
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 /* Take the address of EXP to be used within function CONTEXT.
00159    Mark it for addressability as necessary.  */
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   /* Building the ADDR_EXPR will compute a set of properties for
00175      that ADDR_EXPR.  Those properties are unfortunately context
00176      specific.  ie, they are dependent on CURRENT_FUNCTION_DECL.
00177 
00178      Temporarily set CURRENT_FUNCTION_DECL to the desired context,
00179      build the ADDR_EXPR, then restore CURRENT_FUNCTION_DECL.  That
00180      way the properties are for the ADDR_EXPR are computed properly.  */
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 /* Insert FIELD into TYPE, sorted by alignment requirements.  */
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 /* Build or return the RECORD_TYPE that describes the frame state that is
00206    shared between INFO->CONTEXT and its nested functions.  This record will
00207    not be complete until finalize_nesting_tree; up until that point we'll
00208    be adding fields as necessary.
00209 
00210    We also build the DECL that represents this frame in the function.  */
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       /* ??? Always make it addressable for now, since it is meant to
00232          be pointed to by the static chain pointer.  This pessimizes
00233          when it turns out that no static chains are needed because
00234          the nested functions referencing non-local variables are not
00235          reachable, but the true pessimization is to create the non-
00236          local frame structure in the first place.  */
00237       TREE_ADDRESSABLE (info->frame_decl) = 1;
00238     }
00239   return type;
00240 }
00241 
00242 /* Return true if DECL should be referenced by pointer in the non-local
00243    frame structure.  */
00244 
00245 static bool
00246 use_pointer_in_frame (tree decl)
00247 {
00248   if (TREE_CODE (decl) == PARM_DECL)
00249     {
00250       /* It's illegal to copy TREE_ADDRESSABLE, impossible to copy variable
00251          sized decls, and inefficient to copy large aggregates.  Don't bother
00252          moving anything but scalar variables.  */
00253       return AGGREGATE_TYPE_P (TREE_TYPE (decl));
00254     }
00255   else
00256     {
00257       /* Variable sized types make things "interesting" in the frame.  */
00258       return DECL_SIZE (decl) == NULL || !TREE_CONSTANT (DECL_SIZE (decl));
00259     }
00260 }
00261 
00262 /* Given DECL, a non-locally accessed variable, find or create a field
00263    in the non-local frame structure for the given nesting context.  */
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 /* Build or return the variable that holds the static chain within
00321    INFO->CONTEXT.  This variable may only be used within INFO->CONTEXT.  */
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       /* Note that this variable is *not* entered into any BIND_EXPR;
00335          the construction of this variable is handled specially in
00336          expand_function_start and initialize_inlined_parameters.
00337          Note also that it's represented as a parameter.  This is more
00338          close to the truth, since the initial value does come from 
00339          the caller.  */
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       /* Tell tree-inline.c that we never write to this variable, so
00348          it can copy-prop the replacement value immediately.  */
00349       TREE_READONLY (decl) = 1;
00350 
00351       info->chain_decl = decl;
00352     }
00353   return decl;
00354 }
00355 
00356 /* Build or return the field within the non-local frame state that holds
00357    the static chain for INFO->CONTEXT.  This is the way to walk back up
00358    multiple nesting levels.  */
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 /* Copy EXP into a temporary.  Allocate the temporary in the context of
00382    INFO and insert the initialization statement before TSI.  */
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 /* Similarly, but only do so to force EXP to satisfy is_gimple_val.  */
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 /* Similarly, but copy from the temporary and insert the statement
00409    after the iterator.  */
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 /* Build or return the type used to represent a nested function trampoline.  */
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   /* If we won't be able to guarantee alignment simply via TYPE_ALIGN,
00442      then allocate extra space so that we can do dynamic alignment.  */
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 /* Given DECL, a nested function, find or create a field in the non-local
00464    frame structure for a trampoline for this function.  */
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 /* Build or return the field within the non-local frame state that holds
00506    the non-local goto "jmp_buf".  The buffer itself is maintained by the
00507    rtl middle-end as dynamic stack space is allocated.  */
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       /* For __builtin_nonlocal_goto, we need N words.  The first is the
00519          frame pointer, the rest is for the target's stack pointer save
00520          area.  The number of words is controlled by STACK_SAVEAREA_MODE;
00521          not the best interface, but it'll do for now.  */
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 /* Iterate over all sub-statements of *TP calling walk_tree with
00549    WI->CALLBACK for every sub-expression in each statement found.  */
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       /* A formal temporary lhs may use a COMPONENT_REF rhs.  */
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       /* If the rhs is appropriate for a memory, we may use a
00621          COMPONENT_REF on the lhs.  */
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 /* Invoke CALLBACK on all statements of *STMT_P.  */
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 /* Invoke CALLBACK on all statements of INFO->CONTEXT.  */
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 /* Similarly for ROOT and all functions nested underneath, depth first.  */
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 /* We have to check for a fairly pathological case.  The operands of function
00676    nested function are to be interpreted in the context of the enclosing
00677    function.  So if any are variably-sized, they will get remapped when the
00678    enclosing function is inlined.  But that remapping would also have to be
00679    done in the types of the PARM_DECLs of the nested function, meaning the
00680    argument types of that function will disagree with the arguments in the
00681    calls to that function.  So we'd either have to make a copy of the nested
00682    function corresponding to each time the enclosing function was inlined or
00683    add a VIEW_CONVERT_EXPR to each such operand for each call to the nested
00684    function.  The former is not practical.  The latter would still require
00685    detecting this case to know when to add the conversions.  So, for now at
00686    least, we don't inline such an enclosing function.
00687 
00688    We have to do that check recursively, so here return indicating whether
00689    FNDECL has such a nested function.  ORIG_FN is the function we were
00690    trying to inline to use for checking whether any argument is variably
00691    modified by anything in it.
00692 
00693    It would be better to do this in tree-inline.c so that we could give
00694    the appropriate warning for why a function can't be inlined, but that's
00695    too late since the nesting structure has already been flattened and
00696    adding a flag just to record this fact seems a waste of a flag.  */
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 /* Construct our local datastructure describing the function nesting
00718    tree rooted by CGN.  */
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   /* See discussion at check_for_nested_with_variably_modified for a
00738      discussion of why this has to be here.  */
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 /* Return an expression computing the static chain for TARGET_CONTEXT
00746    from INFO->CONTEXT.  Insert any necessary computations before TSI.  */
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 /* Return an expression referencing FIELD from TARGET_CONTEXT's non-local
00777    frame as seen from INFO->CONTEXT.  Insert any necessary computations
00778    before TSI.  */
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       /* Make sure frame_decl gets created.  */
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 /* A subroutine of convert_nonlocal_reference.  Create a local variable
00814    in the nested function with DECL_VALUE_EXPR set to reference the true
00815    variable in the parent function.  This is used both for debug info 
00816    and in OpenMP lowering.  */
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   /* A copy of the code in get_frame_field, but without the temporaries.  */
00837   if (info->context == target_context)
00838     {
00839       /* Make sure frame_decl gets created.  */
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   /* ??? We should be remapping types as well, surely.  */
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 /* Called via walk_function+walk_tree, rewrite all references to VAR
00888    and PARM_DECLs that belong to outer functions.
00889 
00890    The rewrite will involve some number of structure accesses back up
00891    the static chain.  E.g. for a variable FOO up one nesting level it'll
00892    be CHAIN->FOO.  For two levels it'll be CHAIN->__chain->FOO.  Further
00893    indirections apply to decls for which use_pointer_in_frame is true.  */
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       /* Non-automatic variables are never processed.  */
00911       if (TREE_STATIC (t) || DECL_EXTERNAL (t))
00912         break;
00913       /* FALLTHRU */
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       /* Don't walk non-local gotos for now.  */
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       /* We're taking the address of a label from a parent function, but
00961          this is not itself a non-local goto.  Mark the label such that it
00962          will not be deleted, much as we would with a label address in
00963          static storage.  */
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             /* If we changed anything, then TREE_INVARIANT is be wrong,
00983                since we're no longer directly referencing a decl.  */
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             /* If the callback converted the address argument in a context
00990                where we only accept variables (and min_invariant, presumably),
00991                then compute the address into a temporary.  */
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       /* Go down this entire nest and just look at the final prefix and
01005          anything that describes the references.  Otherwise, we lose track
01006          of whether a NOP_EXPR or VIEW_CONVERT_EXPR needs a simple value.  */
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