GCC Middle and Back End API Reference
tree-nested.c File Reference
#include "langhooks.h"
#include "pointer-set.h"
Include dependency graph for tree-nested.c:

Data Structures

struct  nesting_info
struct  nesting_copy_body_data

Functions

static struct nesting_infoiter_nestinfo_start ()
static struct nesting_infoiter_nestinfo_next ()
static tree create_tmp_var_for ()
tree build_addr ()
void insert_field_into_struct ()
static tree get_frame_type ()
static bool use_pointer_in_frame ()
static tree lookup_field_for_decl (struct nesting_info *info, tree decl, enum insert_option insert)
static tree get_chain_decl ()
static tree get_chain_field ()
static tree init_tmp_var_with_call (struct nesting_info *info, gimple_stmt_iterator *gsi, gimple call)
static tree init_tmp_var ()
static tree gsi_gimplify_val (struct nesting_info *info, tree exp, gimple_stmt_iterator *gsi)
static tree save_tmp_var ()
static tree get_trampoline_type ()
static tree lookup_tramp_for_decl (struct nesting_info *info, tree decl, enum insert_option insert)
static tree get_nl_goto_field ()
static void walk_body (walk_stmt_fn callback_stmt, walk_tree_fn callback_op, struct nesting_info *info, gimple_seq *pseq)
static void walk_function (walk_stmt_fn callback_stmt, walk_tree_fn callback_op, struct nesting_info *info)
static void walk_gimple_omp_for (gimple for_stmt, walk_stmt_fn callback_stmt, walk_tree_fn callback_op, struct nesting_info *info)
static void walk_all_functions (walk_stmt_fn callback_stmt, walk_tree_fn callback_op, struct nesting_info *root)
static bool check_for_nested_with_variably_modified ()
static struct nesting_infocreate_nesting_tree ()
static tree get_static_chain (struct nesting_info *info, tree target_context, gimple_stmt_iterator *gsi)
static tree get_frame_field (struct nesting_info *info, tree target_context, tree field, gimple_stmt_iterator *gsi)
static void note_nonlocal_vla_type (struct nesting_info *info, tree type)
static tree get_nonlocal_debug_decl ()
static tree convert_nonlocal_reference_op ()
static tree convert_nonlocal_reference_stmt (gimple_stmt_iterator *, bool *, struct walk_stmt_info *)
static bool convert_nonlocal_omp_clauses ()
static void note_nonlocal_vla_type ()
static void note_nonlocal_block_vlas ()
static tree get_local_debug_decl ()
static bool convert_local_omp_clauses (tree *, struct walk_stmt_info *)
static tree convert_local_reference_op ()
static tree convert_local_reference_stmt (gimple_stmt_iterator *, bool *, struct walk_stmt_info *)
static bool convert_local_omp_clauses ()
static tree convert_nl_goto_reference (gimple_stmt_iterator *gsi, bool *handled_ops_p, struct walk_stmt_info *wi)
static tree convert_nl_goto_receiver (gimple_stmt_iterator *gsi, bool *handled_ops_p, struct walk_stmt_info *wi)
static tree convert_tramp_reference_op ()
static tree convert_tramp_reference_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p, struct walk_stmt_info *wi)
static tree convert_gimple_call (gimple_stmt_iterator *gsi, bool *handled_ops_p, struct walk_stmt_info *wi)
static void convert_all_function_calls ()
static tree nesting_copy_decl ()
static tree contains_remapped_vars ()
static void remap_vla_decls ()
static bool fold_mem_refs ()
static void finalize_nesting_tree_1 ()
static void finalize_nesting_tree ()
static void unnest_nesting_tree_1 ()
static void unnest_nesting_tree ()
static void free_nesting_tree ()
static void gimplify_all_functions ()
void lower_nested_functions ()

Variables

static struct bitmap_obstack nesting_info_bitmap_obstack
static tree trampoline_type

Function Documentation

static bool check_for_nested_with_variably_modified ( )
static
We have to check for a fairly pathological case.  The operands of function
   nested function are to be interpreted in the context of the enclosing
   function.  So if any are variably-sized, they will get remapped when the
   enclosing function is inlined.  But that remapping would also have to be
   done in the types of the PARM_DECLs of the nested function, meaning the
   argument types of that function will disagree with the arguments in the
   calls to that function.  So we'd either have to make a copy of the nested
   function corresponding to each time the enclosing function was inlined or
   add a VIEW_CONVERT_EXPR to each such operand for each call to the nested
   function.  The former is not practical.  The latter would still require
   detecting this case to know when to add the conversions.  So, for now at
   least, we don't inline such an enclosing function.

   We have to do that check recursively, so here return indicating whether
   FNDECL has such a nested function.  ORIG_FN is the function we were
   trying to inline to use for checking whether any argument is variably
   modified by anything in it.

   It would be better to do this in tree-inline.c so that we could give
   the appropriate warning for why a function can't be inlined, but that's
   too late since the nesting structure has already been flattened and
   adding a flag just to record this fact seems a waste of a flag.   

References cgraph_get_node(), symtab_node_base::decl, cgraph_node::nested, cgraph_node::next_nested, cgraph_node::symbol, and variably_modified_type_p().

Referenced by create_nesting_tree().

static tree contains_remapped_vars ( )
static
A helper function for remap_vla_decls.  See if *TP contains
   some remapped variables.   

References pointer_map_contains(), and nesting_info::var_map.

Referenced by remap_vla_decls().

static void convert_all_function_calls ( )
static
Walk the nesting tree starting with ROOT.  Convert all trampolines and
   call expressions.  At the same time, determine if a nested function
   actually uses its static chain; if not, remember that.   

References nesting_info::chain_decl, nesting_info::chain_field, nesting_info::context, convert_gimple_call(), convert_tramp_reference_op(), convert_tramp_reference_stmt(), lang_hooks::decl_printable_name, dump_file, dump_flags, nesting_info::outer, and walk_function().

Referenced by lower_nested_functions().

static bool convert_local_omp_clauses ( tree ,
struct walk_stmt_info  
)
static
Called via walk_function+walk_gimple_stmt, rewrite all references to VAR
   and PARM_DECLs that were referenced by inner nested functions.
   The rewrite will be a structure reference to the local frame variable.   

Referenced by convert_local_reference_stmt().

static tree convert_nl_goto_receiver ( gimple_stmt_iterator gsi,
bool *  handled_ops_p,
struct walk_stmt_info wi 
)
static
Called via walk_function+walk_tree, rewrite all GIMPLE_LABELs whose labels
   are referenced via nonlocal goto from a nested function.  The rewrite
   will involve installing a newly generated DECL_NONLOCAL label, and
   (potentially) a branch around the rtl gunk that is assumed to be
   attached to such a label.   

References gimple_build_goto(), gimple_build_label(), gimple_label_label(), gimple_stmt_may_fallthru(), walk_stmt_info::gsi, gsi_end_p(), gsi_insert_before(), gsi_prev(), GSI_SAME_STMT, gsi_stmt(), walk_stmt_info::info, pointer_map_contains(), and nesting_info::var_map.

Referenced by lower_nested_functions().

static tree convert_nl_goto_reference ( gimple_stmt_iterator gsi,
bool *  handled_ops_p,
struct walk_stmt_info wi 
)
static
Called via walk_function+walk_gimple_stmt, rewrite all GIMPLE_GOTOs
   that reference labels from outer functions.  The rewrite will be a
   call to __builtin_nonlocal_goto.   

References build_addr(), builtin_decl_implicit(), nesting_info::context, create_artificial_label(), decl_function_context(), get_frame_field(), get_nl_goto_field(), gimple_build_call(), gimple_goto_dest(), gsi_gimplify_val(), gsi_replace(), gsi_stmt(), walk_stmt_info::info, nesting_info::outer, and pointer_map_insert().

Referenced by lower_nested_functions().

static tree convert_nonlocal_reference_op ( )
static
Callback for walk_gimple_stmt, rewrite all references to VAR
   and PARM_DECLs that belong to outer functions.

   The rewrite will involve some number of structure accesses back up
   the static chain.  E.g. for a variable FOO up one nesting level it'll
   be CHAIN->FOO.  For two levels it'll be CHAIN->__chain->FOO.  Further
   indirections apply to decls for which use_pointer_in_frame is true.   

References bitmap_bit_p(), walk_stmt_info::changed, nesting_info::context, current_function_decl, decl_function_context(), get_frame_field(), get_nonlocal_debug_decl(), walk_stmt_info::gsi, gsi_gimplify_val(), handled_component_p(), walk_stmt_info::info, init_tmp_var(), walk_stmt_info::is_lhs, lookup_field_for_decl(), nesting_info::outer, recompute_tree_invariant_for_addr_expr(), save_tmp_var(), nesting_info::suppress_expansion, use_pointer_in_frame(), and walk_stmt_info::val_only.

Referenced by convert_nonlocal_omp_clauses(), convert_nonlocal_reference_stmt(), and lower_nested_functions().

static tree convert_nonlocal_reference_stmt ( gimple_stmt_iterator gsi,
bool *  handled_ops_p,
struct walk_stmt_info wi 
)
static
Callback for walk_gimple_stmt.  Rewrite all references to VAR and
   PARM_DECLs that belong to outer functions.  This handles statements
   that are not handled via the standard recursion done in
   walk_gimple_stmt.  STMT is the statement to examine, DATA is as in
   convert_nonlocal_reference_op.  Set *HANDLED_OPS_P to true if all the
   operands of STMT have been handled by this function.   

References build_omp_clause(), convert_nonlocal_omp_clauses(), convert_nonlocal_reference_op(), declare_vars(), get_chain_decl(), gimple_bind_block(), gimple_goto_dest(), gimple_location(), gimple_omp_body(), gimple_omp_body_ptr(), gimple_omp_for_clauses_ptr(), gimple_omp_sections_clauses_ptr(), gimple_omp_single_clauses_ptr(), gimple_omp_taskreg_clauses(), gimple_omp_taskreg_clauses_ptr(), gimple_omp_taskreg_set_clauses(), gimple_seq_first_stmt(), gsi_stmt(), walk_stmt_info::info, walk_stmt_info::is_lhs, nesting_info::new_local_var_chain, note_nonlocal_block_vlas(), OMP_CLAUSE_FIRSTPRIVATE, nesting_info::suppress_expansion, walk_stmt_info::val_only, walk_body(), and walk_gimple_omp_for().

Referenced by convert_nonlocal_omp_clauses(), and lower_nested_functions().

static tree convert_tramp_reference_op ( )
static
Called via walk_function+walk_stmt, rewrite all references to addresses
   of nested functions that require the use of trampolines.  The rewrite
   will involve a reference a trampoline generated for the occasion.   

References build_addr(), builtin_decl_implicit(), nesting_info::context, decl_function_context(), get_frame_field(), gimple_build_call(), walk_stmt_info::gsi, gsi_gimplify_val(), walk_stmt_info::info, init_tmp_var(), init_tmp_var_with_call(), and lookup_tramp_for_decl().

Referenced by convert_all_function_calls(), and convert_tramp_reference_stmt().

static tree convert_tramp_reference_stmt ( gimple_stmt_iterator gsi,
bool *  handled_ops_p,
struct walk_stmt_info wi 
)
static
Called via walk_function+walk_gimple_stmt, rewrite all references
   to addresses of nested functions that require the use of
   trampolines.  The rewrite will involve a reference a trampoline
   generated for the occasion.   

References convert_tramp_reference_op(), declare_vars(), gimple_call_arg_ptr(), gimple_call_num_args(), gimple_omp_body(), gimple_omp_body_ptr(), gimple_seq_first_stmt(), gsi_stmt(), walk_stmt_info::info, nesting_info::new_local_var_chain, walk_body(), and walk_gimple_op().

Referenced by convert_all_function_calls().

static tree create_tmp_var_for ( )
static
Like create_tmp_var, except record the variable for registration at
   the given nesting level.   

References nesting_info::context, create_tmp_var_raw(), and nesting_info::new_local_var_chain.

Referenced by get_frame_type(), init_tmp_var(), init_tmp_var_with_call(), and save_tmp_var().

static void finalize_nesting_tree ( )
static
static void finalize_nesting_tree_1 ( )
static
Do "everything else" to clean up or complete state collected by the
   various walking passes -- lay out the types and decls, generate code
   to initialize the frame decl, store critical expressions in the
   struct function for rtl to find.   

References annotate_all_with_location(), nesting_info::any_parm_remapped, nesting_info::any_tramp_created, build_addr(), builtin_decl_implicit(), nesting_info::chain_decl, nesting_info::chain_field, chainon(), nesting_info::context, nesting_info::debug_var_chain, declare_vars(), dump_file, dump_flags, dump_function_to_file(), fold_mem_refs(), nesting_info::frame_decl, nesting_info::frame_type, get_chain_decl(), get_frame_field(), gimple_assign_set_rhs1(), gimple_bind_block(), gimple_bind_body(), gimple_bind_set_body(), gimple_body(), gimple_build_call(), gimple_seq_add_seq(), gimple_seq_add_stmt(), gimple_seq_first_stmt(), function::has_nonlocal_label, init_tmp_var(), nesting_info::inner, is_gimple_reg(), is_gimple_reg_type(), layout_decl(), layout_type(), lookup_field_for_decl(), lookup_tramp_for_decl(), nesting_info::mem_refs, memset(), nesting_copy_decl(), nesting_info::new_local_var_chain, nesting_info::next, nesting_info::nl_goto_field, function::nonlocal_goto_save_area, nesting_info::outer, pointer_map_create(), pointer_map_destroy(), pointer_set_traverse(), remap_decl(), remap_type(), remap_vla_decls(), nesting_copy_body_data::root, function::static_chain_decl, type(), use_pointer_in_frame(), and variably_modified_type_p().

Referenced by finalize_nesting_tree().

static bool fold_mem_refs ( )
static
Fold the MEM_REF *E.   

References fold().

Referenced by finalize_nesting_tree_1().

static void free_nesting_tree ( )
static
static tree get_chain_decl ( )
static
static tree get_chain_field ( )
static
Build or return the field within the non-local frame state that holds
   the static chain for INFO->CONTEXT.  This is the way to walk back up
   multiple nesting levels.   

References build_pointer_type(), nesting_info::chain_field, nesting_info::context, lang_hooks::decl_printable_name, dump_file, dump_flags, get_frame_type(), get_identifier(), insert_field_into_struct(), nesting_info::outer, and type().

Referenced by get_frame_field(), get_nonlocal_debug_decl(), and get_static_chain().

static tree get_frame_field ( struct nesting_info info,
tree  target_context,
tree  field,
gimple_stmt_iterator gsi 
)
static
Return an expression referencing FIELD from TARGET_CONTEXT's non-local
   frame as seen from INFO->CONTEXT.  Insert any necessary computations
   before GSI.   

References nesting_info::context, nesting_info::frame_decl, get_chain_decl(), get_chain_field(), get_frame_type(), init_tmp_var(), and nesting_info::outer.

Referenced by convert_local_reference_op(), convert_nl_goto_reference(), convert_nonlocal_reference_op(), convert_tramp_reference_op(), and finalize_nesting_tree_1().

static tree get_frame_type ( )
static
Build or return the RECORD_TYPE that describes the frame state that is
   shared between INFO->CONTEXT and its nested functions.  This record will
   not be complete until finalize_nesting_tree; up until that point we'll
   be adding fields as necessary.

   We also build the DECL that represents this frame in the function.   

References nesting_info::context, create_tmp_var_for(), nesting_info::frame_decl, nesting_info::frame_type, free(), get_identifier(), and type().

Referenced by convert_local_reference_stmt(), get_chain_decl(), get_chain_field(), get_frame_field(), get_local_debug_decl(), get_nl_goto_field(), get_nonlocal_debug_decl(), lookup_field_for_decl(), and lookup_tramp_for_decl().

static tree get_local_debug_decl ( )
static
A subroutine of convert_local_reference.  Create a local variable
   in the parent function with DECL_VALUE_EXPR set to reference the
   field in FRAME.  This is used both for debug info and in OpenMP
   lowering.   

References nesting_info::context, nesting_info::debug_var_chain, nesting_info::frame_decl, get_frame_type(), pointer_map_insert(), and nesting_info::var_map.

Referenced by convert_local_omp_clauses(), and convert_local_reference_op().

static tree get_nl_goto_field ( )
static
Build or return the field within the non-local frame state that holds
   the non-local goto "jmp_buf".  The buffer itself is maintained by the
   rtl middle-end as dynamic stack space is allocated.   

References build_array_type(), build_index_type(), get_frame_type(), get_identifier(), insert_field_into_struct(), nesting_info::nl_goto_field, ptr_mode, SAVE_NONLOCAL, type(), lang_hooks_for_types::type_for_mode, and lang_hooks::types.

Referenced by convert_nl_goto_reference().

static tree get_nonlocal_debug_decl ( )
static
A subroutine of convert_nonlocal_reference_op.  Create a local variable
   in the nested function with DECL_VALUE_EXPR set to reference the true
   variable in the parent function.  This is used both for debug info
   and in OpenMP lowering.   

References nesting_info::context, nesting_info::debug_var_chain, decl_function_context(), nesting_info::frame_decl, get_chain_decl(), get_chain_field(), get_frame_type(), lookup_field_for_decl(), note_nonlocal_vla_type(), nesting_info::outer, pointer_map_insert(), use_pointer_in_frame(), nesting_info::var_map, and variably_modified_type_p().

Referenced by convert_nonlocal_omp_clauses(), convert_nonlocal_reference_op(), and note_nonlocal_vla_type().

static tree get_static_chain ( struct nesting_info info,
tree  target_context,
gimple_stmt_iterator gsi 
)
static
Return an expression computing the static chain for TARGET_CONTEXT
   from INFO->CONTEXT.  Insert any necessary computations before TSI.   

References build_addr(), nesting_info::context, nesting_info::frame_decl, get_chain_decl(), get_chain_field(), init_tmp_var(), and nesting_info::outer.

Referenced by convert_gimple_call().

static tree get_trampoline_type ( )
static
static void gimplify_all_functions ( )
static
static tree gsi_gimplify_val ( struct nesting_info info,
tree  exp,
gimple_stmt_iterator gsi 
)
static
Similarly, but only do so to force EXP to satisfy is_gimple_val.   

References exp(), init_tmp_var(), and is_gimple_val().

Referenced by convert_local_reference_op(), convert_nl_goto_reference(), convert_nonlocal_reference_op(), and convert_tramp_reference_op().

static tree init_tmp_var ( )
static
static tree init_tmp_var_with_call ( struct nesting_info info,
gimple_stmt_iterator gsi,
gimple  call 
)
static
void insert_field_into_struct ( )
Insert FIELD into TYPE, sorted by alignment requirements.   

References type().

static struct nesting_info* iter_nestinfo_next ( )
staticread
static struct nesting_info* iter_nestinfo_start ( )
staticread
Iterate over the nesting tree, starting with ROOT, depth first.   

References nesting_info::inner.

Referenced by free_nesting_tree(), and iter_nestinfo_next().

static tree lookup_field_for_decl ( struct nesting_info info,
tree  decl,
enum insert_option  insert 
)
static
static tree lookup_tramp_for_decl ( struct nesting_info info,
tree  decl,
enum insert_option  insert 
)
static
Given DECL, a nested function, find or create a field in the non-local
   frame structure for a trampoline for this function.   

References nesting_info::any_tramp_created, get_frame_type(), get_trampoline_type(), insert_field_into_struct(), pointer_map_contains(), pointer_map_insert(), and nesting_info::var_map.

Referenced by convert_tramp_reference_op(), and finalize_nesting_tree_1().

static tree nesting_copy_decl ( )
static
A helper subroutine for debug_var_chain type remapping.   

References copy_decl_no_change(), pointer_map_contains(), remap_type(), nesting_copy_body_data::root, and nesting_info::var_map.

Referenced by finalize_nesting_tree_1(), and remap_vla_decls().

static void note_nonlocal_block_vlas ( )
static
Create nonlocal debug decls for nonlocal VLA array bounds for VLAs
   in BLOCK.   

References nesting_info::context, decl_function_context(), note_nonlocal_vla_type(), and variably_modified_type_p().

Referenced by convert_nonlocal_reference_stmt().

static void note_nonlocal_vla_type ( struct nesting_info info,
tree  type 
)
static
static void note_nonlocal_vla_type ( )
static
Create nonlocal debug decls for nonlocal VLA array bounds.   

References nesting_info::context, decl_function_context(), get_nonlocal_debug_decl(), and note_nonlocal_vla_type().

static tree save_tmp_var ( )
static
Similarly, but copy from the temporary and insert the statement
   after the iterator.   

References create_tmp_var_for(), gimple_location(), gimple_set_location(), gsi_end_p(), gsi_insert_after_without_update(), GSI_SAME_STMT, and gsi_stmt().

Referenced by convert_local_reference_op(), and convert_nonlocal_reference_op().

static void unnest_nesting_tree ( )
static
static void unnest_nesting_tree_1 ( )
static
Unnest the nodes and pass them to cgraph.   

References cgraph_finalize_function(), cgraph_get_node(), cgraph_unnest_node(), nesting_info::context, and cgraph_node::origin.

Referenced by unnest_nesting_tree().

static bool use_pointer_in_frame ( )
static
static void walk_all_functions ( walk_stmt_fn  callback_stmt,
walk_tree_fn  callback_op,
struct nesting_info root 
)
static
Similarly for ROOT and all functions nested underneath, depth first.   

References walk_function().

Referenced by lower_nested_functions().

static void walk_function ( walk_stmt_fn  callback_stmt,
walk_tree_fn  callback_op,
struct nesting_info info 
)
inlinestatic
Invoke CALLBACK_STMT/CALLBACK_OP on all statements of INFO->CONTEXT.   

References nesting_info::context, gimple_body(), gimple_set_body(), and walk_body().

Referenced by convert_all_function_calls(), and walk_all_functions().


Variable Documentation

struct bitmap_obstack nesting_info_bitmap_obstack
static
Obstack used for the bitmaps in the struct above.   

Referenced by create_nesting_tree(), and lower_nested_functions().

tree trampoline_type
static
Build or return the type used to represent a nested function trampoline.   

Referenced by get_trampoline_type().