GCC Middle and Back End API Reference
tree-nested.cc File Reference
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "rtl.h"
#include "tree.h"
#include "gimple.h"
#include "memmodel.h"
#include "tm_p.h"
#include "stringpool.h"
#include "cgraph.h"
#include "fold-const.h"
#include "stor-layout.h"
#include "dumpfile.h"
#include "tree-inline.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "gimple-walk.h"
#include "tree-cfg.h"
#include "explow.h"
#include "langhooks.h"
#include "gimple-low.h"
#include "gomp-constants.h"
#include "diagnostic.h"
#include "alloc-pool.h"
#include "tree-nested.h"
#include "symbol-summary.h"
#include "symtab-thunks.h"
#include "gt-tree-nested.h"
Include dependency graph for tree-nested.cc:

Data Structures

struct  nesting_info
 
struct  nesting_copy_body_data
 

Macros

#define FOR_EACH_NEST_INFO(I, ROOT)    for ((I) = iter_nestinfo_start (ROOT); (I); (I) = iter_nestinfo_next (I))
 
#define create_tmp_var   cant_use_create_tmp_var_here_dummy
 

Functions

void unnest_function (cgraph_node *node)
 
void maybe_record_nested_function (cgraph_node *node)
 
static struct nesting_infoiter_nestinfo_start (struct nesting_info *root)
 
static struct nesting_infoiter_nestinfo_next (struct nesting_info *node)
 
static tree create_tmp_var_for (struct nesting_info *info, tree type, const char *prefix)
 
static tree build_simple_mem_ref_notrap (tree ptr)
 
tree build_addr (tree exp)
 
void insert_field_into_struct (tree type, tree field)
 
static tree get_frame_type (struct nesting_info *info)
 
static bool use_pointer_in_frame (tree decl)
 
static tree lookup_field_for_decl (struct nesting_info *info, tree decl, enum insert_option insert)
 
static tree get_chain_decl (struct nesting_info *info)
 
static tree get_chain_field (struct nesting_info *info)
 
static tree init_tmp_var_with_call (struct nesting_info *info, gimple_stmt_iterator *gsi, gcall *call)
 
static tree init_tmp_var (struct nesting_info *info, tree exp, gimple_stmt_iterator *gsi)
 
static tree gsi_gimplify_val (struct nesting_info *info, tree exp, gimple_stmt_iterator *gsi)
 
static tree save_tmp_var (struct nesting_info *info, tree exp, gimple_stmt_iterator *gsi)
 
static tree get_trampoline_type (struct nesting_info *info)
 
static tree get_descriptor_type (struct nesting_info *info)
 
static tree lookup_element_for_decl (struct nesting_info *info, tree decl, enum insert_option insert)
 
static tree create_field_for_decl (struct nesting_info *info, tree decl, tree type)
 
static tree lookup_tramp_for_decl (struct nesting_info *info, tree decl, enum insert_option insert)
 
static tree lookup_descr_for_decl (struct nesting_info *info, tree decl, enum insert_option insert)
 
static tree get_nl_goto_field (struct nesting_info *info)
 
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 (gomp_for *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 (tree fndecl, tree orig_fndecl)
 
static struct nesting_infocreate_nesting_tree (struct cgraph_node *cgn)
 
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 (struct nesting_info *info, tree decl)
 
static tree convert_nonlocal_reference_op (tree *tp, int *walk_subtrees, void *data)
 
static tree convert_nonlocal_reference_stmt (gimple_stmt_iterator *, bool *, struct walk_stmt_info *)
 
static bool convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
 
static tree get_local_debug_decl (struct nesting_info *info, tree decl, tree field)
 
static bool convert_local_omp_clauses (tree *, struct walk_stmt_info *)
 
static tree convert_local_reference_op (tree *tp, int *walk_subtrees, void *data)
 
static tree convert_local_reference_stmt (gimple_stmt_iterator *, bool *, struct walk_stmt_info *)
 
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 (tree *tp, int *walk_subtrees, void *data)
 
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 (struct nesting_info *root)
 
static tree nesting_copy_decl (tree decl, copy_body_data *id)
 
static tree contains_remapped_vars (tree *tp, int *walk_subtrees, void *data)
 
static void remap_vla_decls (tree block, struct nesting_info *root)
 
static void fixup_vla_decls (tree block)
 
bool fold_mem_refs (tree *const &e, void *data)
 
static gcallbuild_init_call_stmt (struct nesting_info *info, tree decl, tree field, tree func)
 
static void finalize_nesting_tree_1 (struct nesting_info *root)
 
static void finalize_nesting_tree (struct nesting_info *root)
 
static void unnest_nesting_tree_1 (struct nesting_info *root)
 
static void unnest_nesting_tree (struct nesting_info *root)
 
static void free_nesting_tree (struct nesting_info *root)
 
static void gimplify_all_functions (struct cgraph_node *root)
 
void lower_nested_functions (tree fndecl)
 

Variables

static function_summary< nested_function_info * > * nested_function_sum = NULL
 
static struct bitmap_obstack nesting_info_bitmap_obstack
 
static tree trampoline_type
 
static tree descriptor_type
 

Macro Definition Documentation

◆ create_tmp_var

#define create_tmp_var   cant_use_create_tmp_var_here_dummy
We're working in so many different function contexts simultaneously,
that create_tmp_var is dangerous.  Prevent mishap.   

Referenced by add_taskreg_looptemp_clauses(), asan_expand_poison_ifn(), build_instrumentation_call(), build_stack_save_restore(), clear_padding_type(), ipa_param_body_adjustments::common_initialization(), create_access_replacement(), create_call_for_reduction_1(), create_one_component_var(), create_tmp_from_val(), create_tmp_reg(), create_vector_array(), declare_return_variable(), detach_value(), expand_assign_tm(), expand_oacc_collapse_init(), expand_oacc_for(), expand_omp_atomic_pipeline(), expand_omp_for_generic(), expand_omp_for_init_vars(), expand_omp_for_static_chunk(), expand_omp_for_static_nochunk(), expand_omp_ordered_sink(), expand_omp_ordered_source_sink(), expand_omp_sections(), expand_omp_simd(), expand_omp_target(), expand_parallel_call(), fold_builtin_alloca_with_align(), gen_conditions_for_pow_int_base(), gen_emutls_addr(), gen_one_condition(), get_target_arguments(), gimple_fold_builtin_clear_padding(), gimple_fold_call(), gimple_lower_bitint(), gimple_push_cleanup(), gimplify_bind_expr(), gimplify_call_expr(), gimplify_cond_expr(), gimplify_expr(), gimplify_function_tree(), gimplify_init_constructor(), gimplify_init_ctor_eval_range(), gimplify_modify_expr_to_memcpy(), gimplify_modify_expr_to_memset(), gimplify_omp_depend(), gimplify_omp_for(), gimplify_omp_taskloop_expr(), gimplify_parameters(), gimplify_vla_decl(), handle_abnormal_edges(), instrument_builtin_call(), ipa_tm_insert_gettmclone_call(), lower_assumption(), lower_builtin_posix_memalign(), lower_depend_clauses(), lower_eh_constructs_2(), lower_eh_dispatch(), lower_emutls_1(), lower_lastprivate_clauses(), lower_oacc_head_tail(), lower_oacc_reductions(), lower_omp_1(), lower_omp_for(), lower_omp_for_scan(), lower_omp_ordered(), lower_omp_scan(), lower_omp_scope(), lower_omp_sections(), lower_omp_single_copy(), lower_omp_single_simple(), lower_omp_target(), lower_omp_task_reductions(), lower_omp_taskreg(), lower_omp_teams(), lower_private_allocate(), lower_rec_input_clauses(), lower_rec_simd_input_clauses(), lower_reduction_clauses(), lower_resx(), lower_transaction(), lower_try_finally_switch(), make_blocks_1(), maybe_add_implicit_barrier_cancel(), oacc_dim_call(), omp_extract_for_data(), remap_type_1(), rt_bb_visited::rt_bb_visited(), scan_omp_parallel(), separate_decls_in_region(), separate_decls_in_region_name(), simd_clone_adjust(), task_copyfn_copy_decl(), task_reduction_read(), ubsan_encode_value(), update_alias_info_with_stack_vars(), vect_build_loop_niters(), vect_gen_prolog_loop_niters(), vect_gen_vector_loop_niters(), vect_gen_vector_loop_niters_mult_vf(), vect_update_ivs_after_vectorizer(), vector_element(), vectorizable_simd_clone_call(), rt_bb_visited::vindex(), voidify_wrapper_expr(), rt_bb_visited::vset(), worker_single_copy(), and worker_single_simple().

◆ FOR_EACH_NEST_INFO

Function Documentation

◆ build_addr()

◆ build_init_call_stmt()

static gcall * build_init_call_stmt ( struct nesting_info * info,
tree decl,
tree field,
tree func )
static
Given DECL, a nested function, build an initialization call for FIELD,
the trampoline or descriptor for DECL, using FUNC as the function.   

References build3(), build_addr(), DECL_STATIC_CHAIN, nesting_info::frame_decl, gcc_assert, ggc_alloc(), gimple_build_call(), NULL_TREE, and TREE_TYPE.

Referenced by finalize_nesting_tree_1().

◆ build_simple_mem_ref_notrap()

static tree build_simple_mem_ref_notrap ( tree ptr)
static
Like build_simple_mem_ref, but set TREE_THIS_NOTRAP on the result.   

References build_simple_mem_ref, and TREE_THIS_NOTRAP.

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

◆ check_for_nested_with_variably_modified()

static bool check_for_nested_with_variably_modified ( tree fndecl,
tree orig_fndecl )
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.cc 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 check_for_nested_with_variably_modified(), DECL_ARGUMENTS, DECL_CHAIN, first_nested_function(), cgraph_node::get(), ggc_alloc(), next_nested_function(), TREE_TYPE, and variably_modified_type_p().

Referenced by check_for_nested_with_variably_modified(), and create_nesting_tree().

◆ contains_remapped_vars()

static tree contains_remapped_vars ( tree * tp,
int * walk_subtrees,
void * data )
static
A helper function for remap_vla_decls.  See if *TP contains
some remapped variables.   

References DECL_P, hash_map< KeyId, Value, Traits >::get(), ggc_alloc(), NULL, and nesting_info::var_map.

Referenced by remap_vla_decls().

◆ convert_all_function_calls()

static void convert_all_function_calls ( struct nesting_info * root)
static

◆ convert_gimple_call()

◆ convert_local_omp_clauses()

static bool convert_local_omp_clauses ( tree * pclauses,
struct walk_stmt_info * wi )
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.   
Helper for convert_local_reference.  Convert all the references in
the chain of clauses at *PCLAUSES.  WI is as in convert_local_reference.   

References bitmap_copy(), BITMAP_GGC_ALLOC, bitmap_set_bit, nesting_info::context, convert_local_reference_op(), convert_local_reference_stmt(), convert_nonlocal_reference_op(), DECL_CONTEXT, DECL_EXTERNAL, decl_function_context(), DECL_P, DECL_UID, gcc_unreachable, get_local_debug_decl(), ggc_alloc(), INDIRECT_REF_P, lookup_field_for_decl(), NULL, OMP_CLAUSE__CACHE_, OMP_CLAUSE__CONDTEMP_, OMP_CLAUSE__LOOPTEMP_, OMP_CLAUSE__REDUCTEMP_, OMP_CLAUSE__SCANTEMP_, OMP_CLAUSE__SIMDUID_, OMP_CLAUSE__SIMT_, OMP_CLAUSE_ALIGNED, OMP_CLAUSE_ALIGNED_ALIGNMENT, OMP_CLAUSE_ALLOCATE, OMP_CLAUSE_ALLOCATE_ALLOCATOR, OMP_CLAUSE_ASYNC, OMP_CLAUSE_AUTO, OMP_CLAUSE_BIND, OMP_CLAUSE_CHAIN, OMP_CLAUSE_CODE, OMP_CLAUSE_COLLAPSE, OMP_CLAUSE_COPYIN, OMP_CLAUSE_COPYPRIVATE, OMP_CLAUSE_DECL, OMP_CLAUSE_DEFAULT, OMP_CLAUSE_DEFAULTMAP, OMP_CLAUSE_DEPEND, OMP_CLAUSE_DETACH, OMP_CLAUSE_DEVICE, OMP_CLAUSE_DIST_SCHEDULE, OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR, OMP_CLAUSE_DOACROSS, OMP_CLAUSE_ENTER, OMP_CLAUSE_FILTER, OMP_CLAUSE_FINAL, OMP_CLAUSE_FINALIZE, OMP_CLAUSE_FIRSTPRIVATE, OMP_CLAUSE_FOR, OMP_CLAUSE_FROM, OMP_CLAUSE_GANG, OMP_CLAUSE_GANG_STATIC_EXPR, OMP_CLAUSE_GRAINSIZE, OMP_CLAUSE_HAS_DEVICE_ADDR, OMP_CLAUSE_HINT, OMP_CLAUSE_IF, OMP_CLAUSE_IF_PRESENT, OMP_CLAUSE_IN_REDUCTION, OMP_CLAUSE_INBRANCH, OMP_CLAUSE_INDEPENDENT, OMP_CLAUSE_IS_DEVICE_PTR, OMP_CLAUSE_LASTPRIVATE, OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ, OMP_CLAUSE_LINEAR, OMP_CLAUSE_LINEAR_GIMPLE_SEQ, OMP_CLAUSE_LINEAR_STEP, OMP_CLAUSE_LINK, OMP_CLAUSE_MAP, OMP_CLAUSE_MERGEABLE, OMP_CLAUSE_NOGROUP, OMP_CLAUSE_NOHOST, OMP_CLAUSE_NONTEMPORAL, OMP_CLAUSE_NOTINBRANCH, OMP_CLAUSE_NOWAIT, OMP_CLAUSE_NUM_GANGS, OMP_CLAUSE_NUM_TASKS, OMP_CLAUSE_NUM_TEAMS, OMP_CLAUSE_NUM_THREADS, OMP_CLAUSE_NUM_WORKERS, OMP_CLAUSE_OPERAND, OMP_CLAUSE_ORDER, OMP_CLAUSE_ORDERED, OMP_CLAUSE_PARALLEL, OMP_CLAUSE_PRIORITY, OMP_CLAUSE_PRIVATE, OMP_CLAUSE_PROC_BIND, OMP_CLAUSE_REDUCTION, OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER, OMP_CLAUSE_REDUCTION_GIMPLE_INIT, OMP_CLAUSE_REDUCTION_GIMPLE_MERGE, OMP_CLAUSE_REDUCTION_PLACEHOLDER, OMP_CLAUSE_SAFELEN, OMP_CLAUSE_SCHEDULE, OMP_CLAUSE_SCHEDULE_CHUNK_EXPR, OMP_CLAUSE_SECTIONS, OMP_CLAUSE_SELF, OMP_CLAUSE_SEQ, OMP_CLAUSE_SHARED, OMP_CLAUSE_SHARED_READONLY, OMP_CLAUSE_SIMD, OMP_CLAUSE_SIMDLEN, OMP_CLAUSE_SIZE, OMP_CLAUSE_TASK_REDUCTION, OMP_CLAUSE_TASKGROUP, OMP_CLAUSE_THREAD_LIMIT, OMP_CLAUSE_THREADS, OMP_CLAUSE_TILE, OMP_CLAUSE_TO, OMP_CLAUSE_UNIFORM, OMP_CLAUSE_UNTIED, OMP_CLAUSE_USE_DEVICE_ADDR, OMP_CLAUSE_USE_DEVICE_PTR, OMP_CLAUSE_VECTOR, OMP_CLAUSE_VECTOR_LENGTH, OMP_CLAUSE_WAIT, OMP_CLAUSE_WORKER, nesting_info::suppress_expansion, TREE_CODE, TREE_OPERAND, TREE_STATIC, use_pointer_in_frame(), VAR_P, walk_body(), and walk_tree.

Referenced by convert_local_reference_stmt().

◆ convert_local_reference_op()

◆ convert_local_reference_stmt()

static tree convert_local_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 VAR
and PARM_DECLs that were referenced by inner nested functions.
The rewrite will be a structure reference to the local frame variable.   

References build_omp_clause(), CONSTRUCTOR_ELT, CONSTRUCTOR_ELTS, nesting_info::context, convert_local_omp_clauses(), convert_local_reference_op(), convert_local_reference_stmt(), DECL_CHAIN, DECL_EXTERNAL, decl_function_context(), DECL_P, DECL_SIZE_UNIT, declare_vars(), decls, FOR_EACH_CONSTRUCTOR_VALUE, nesting_info::frame_decl, get_frame_type(), get_local_debug_decl(), ggc_alloc(), gimple_assign_lhs(), gimple_bind_vars(), gimple_build_nop(), gimple_clobber_p(), gimple_location(), gimple_omp_body(), gimple_omp_body_ptr(), gimple_omp_for_clauses_ptr(), gimple_omp_scope_clauses_ptr(), gimple_omp_sections_clauses_ptr(), gimple_omp_single_clauses_ptr(), gimple_omp_target_clauses(), gimple_omp_target_clauses_ptr(), gimple_omp_target_set_clauses(), gimple_omp_taskgroup_clauses_ptr(), gimple_omp_taskreg_clauses(), gimple_omp_taskreg_clauses_ptr(), gimple_omp_taskreg_set_clauses(), gimple_omp_teams_clauses_ptr(), gimple_omp_teams_host(), gimple_seq_first_stmt(), gsi_replace(), gsi_stmt(), i, is_gimple_omp_offloaded(), lookup_field_for_decl(), NAMELIST_DECL_ASSOCIATED_DECL, nesting_info::new_local_var_chain, NULL, NULL_TREE, OMP_CLAUSE_CHAIN, OMP_CLAUSE_DECL, OMP_CLAUSE_MAP, OMP_CLAUSE_SET_MAP_KIND, OMP_CLAUSE_SHARED, OMP_CLAUSE_SIZE, nesting_info::static_chain_added, nesting_info::suppress_expansion, TREE_CODE, TREE_STATIC, use_pointer_in_frame(), VAR_P, walk_body(), and walk_gimple_omp_for().

Referenced by convert_local_omp_clauses(), convert_local_reference_stmt(), and lower_nested_functions().

◆ convert_nl_goto_receiver()

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 hash_map< KeyId, Value, Traits >::get(), ggc_alloc(), gimple_build_goto(), gimple_build_label(), gimple_label_label(), gimple_stmt_may_fallthru(), gsi_end_p(), gsi_insert_before(), gsi_prev(), GSI_SAME_STMT, gsi_stmt(), NULL_TREE, and nesting_info::var_map.

Referenced by lower_nested_functions().

◆ convert_nl_goto_reference()

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(), DECL_NONLOCAL, get_frame_field(), get_nl_goto_field(), ggc_alloc(), gimple_build_call(), gimple_goto_dest(), gsi_gimplify_val(), gsi_replace(), gsi_stmt(), i, NULL, NULL_TREE, nesting_info::outer, TREE_CODE, and UNKNOWN_LOCATION.

Referenced by lower_nested_functions().

◆ convert_nonlocal_omp_clauses()

static bool convert_nonlocal_omp_clauses ( tree * pclauses,
struct walk_stmt_info * wi )
static
Helper for convert_nonlocal_references, rewrite all references to VAR
and PARM_DECLs that belong to outer functions.   

References bitmap_copy(), BITMAP_GGC_ALLOC, bitmap_set_bit, nesting_info::context, convert_nonlocal_reference_op(), convert_nonlocal_reference_stmt(), DECL_CONTEXT, DECL_EXTERNAL, decl_function_context(), DECL_P, DECL_UID, declare_vars(), g, gcc_unreachable, get_nonlocal_debug_decl(), ggc_alloc(), gimple_build_bind(), gimple_seq_add_stmt_without_update(), gimple_seq_first_stmt(), INDIRECT_REF_P, nesting_info::new_local_var_chain, NULL, NULL_TREE, OMP_CLAUSE__CACHE_, OMP_CLAUSE__CONDTEMP_, OMP_CLAUSE__LOOPTEMP_, OMP_CLAUSE__REDUCTEMP_, OMP_CLAUSE__SCANTEMP_, OMP_CLAUSE__SIMDUID_, OMP_CLAUSE__SIMT_, OMP_CLAUSE_ALIGNED, OMP_CLAUSE_ALIGNED_ALIGNMENT, OMP_CLAUSE_ALLOCATE, OMP_CLAUSE_ALLOCATE_ALLOCATOR, OMP_CLAUSE_ASYNC, OMP_CLAUSE_AUTO, OMP_CLAUSE_BIND, OMP_CLAUSE_CHAIN, OMP_CLAUSE_CODE, OMP_CLAUSE_COLLAPSE, OMP_CLAUSE_COPYIN, OMP_CLAUSE_COPYPRIVATE, OMP_CLAUSE_DECL, OMP_CLAUSE_DEFAULT, OMP_CLAUSE_DEFAULTMAP, OMP_CLAUSE_DEPEND, OMP_CLAUSE_DETACH, OMP_CLAUSE_DEVICE, OMP_CLAUSE_DIST_SCHEDULE, OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR, OMP_CLAUSE_DOACROSS, OMP_CLAUSE_ENTER, OMP_CLAUSE_FILTER, OMP_CLAUSE_FINAL, OMP_CLAUSE_FINALIZE, OMP_CLAUSE_FIRSTPRIVATE, OMP_CLAUSE_FOR, OMP_CLAUSE_FROM, OMP_CLAUSE_GANG, OMP_CLAUSE_GANG_STATIC_EXPR, OMP_CLAUSE_GRAINSIZE, OMP_CLAUSE_HAS_DEVICE_ADDR, OMP_CLAUSE_HINT, OMP_CLAUSE_IF, OMP_CLAUSE_IF_PRESENT, OMP_CLAUSE_IN_REDUCTION, OMP_CLAUSE_INBRANCH, OMP_CLAUSE_INDEPENDENT, OMP_CLAUSE_IS_DEVICE_PTR, OMP_CLAUSE_LASTPRIVATE, OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ, OMP_CLAUSE_LINEAR, OMP_CLAUSE_LINEAR_GIMPLE_SEQ, OMP_CLAUSE_LINEAR_STEP, OMP_CLAUSE_LINK, OMP_CLAUSE_MAP, OMP_CLAUSE_MERGEABLE, OMP_CLAUSE_NOGROUP, OMP_CLAUSE_NOHOST, OMP_CLAUSE_NONTEMPORAL, OMP_CLAUSE_NOTINBRANCH, OMP_CLAUSE_NOWAIT, OMP_CLAUSE_NUM_GANGS, OMP_CLAUSE_NUM_TASKS, OMP_CLAUSE_NUM_TEAMS, OMP_CLAUSE_NUM_THREADS, OMP_CLAUSE_NUM_WORKERS, OMP_CLAUSE_OPERAND, OMP_CLAUSE_ORDER, OMP_CLAUSE_ORDERED, OMP_CLAUSE_PARALLEL, OMP_CLAUSE_PRIORITY, OMP_CLAUSE_PRIVATE, OMP_CLAUSE_PROC_BIND, OMP_CLAUSE_REDUCTION, OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER, OMP_CLAUSE_REDUCTION_GIMPLE_INIT, OMP_CLAUSE_REDUCTION_GIMPLE_MERGE, OMP_CLAUSE_REDUCTION_PLACEHOLDER, OMP_CLAUSE_SAFELEN, OMP_CLAUSE_SCHEDULE, OMP_CLAUSE_SCHEDULE_CHUNK_EXPR, OMP_CLAUSE_SECTIONS, OMP_CLAUSE_SELF, OMP_CLAUSE_SEQ, OMP_CLAUSE_SHARED, OMP_CLAUSE_SHARED_READONLY, OMP_CLAUSE_SIMD, OMP_CLAUSE_SIMDLEN, OMP_CLAUSE_SIZE, OMP_CLAUSE_TASK_REDUCTION, OMP_CLAUSE_TASKGROUP, OMP_CLAUSE_THREAD_LIMIT, OMP_CLAUSE_THREADS, OMP_CLAUSE_TILE, OMP_CLAUSE_TO, OMP_CLAUSE_UNIFORM, OMP_CLAUSE_UNTIED, OMP_CLAUSE_USE_DEVICE_ADDR, OMP_CLAUSE_USE_DEVICE_PTR, OMP_CLAUSE_VECTOR, OMP_CLAUSE_VECTOR_LENGTH, OMP_CLAUSE_WAIT, OMP_CLAUSE_WORKER, nesting_info::suppress_expansion, TREE_CODE, TREE_OPERAND, TREE_STATIC, VAR_P, walk_body(), and walk_tree.

Referenced by convert_nonlocal_reference_stmt().

◆ convert_nonlocal_reference_op()

static tree convert_nonlocal_reference_op ( tree * tp,
int * walk_subtrees,
void * data )
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, build_simple_mem_ref_notrap(), nesting_info::context, convert_nonlocal_reference_op(), current_function_decl, DECL_EXTERNAL, decl_function_context(), DECL_NAME, DECL_UID, FORCED_LABEL, get_frame_field(), get_nonlocal_debug_decl(), ggc_alloc(), gsi_gimplify_val(), handled_component_p(), i, IDENTIFIER_POINTER, init_tmp_var(), internal_error(), IS_TYPE_OR_DECL_P, lookup_field_for_decl(), NULL, NULL_TREE, nesting_info::outer, recompute_tree_invariant_for_addr_expr(), save_tmp_var(), nesting_info::suppress_expansion, TREE_CODE, TREE_OPERAND, TREE_STATIC, use_pointer_in_frame(), and walk_tree.

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

◆ convert_nonlocal_reference_stmt()

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(), CONSTRUCTOR_ELT, CONSTRUCTOR_ELTS, nesting_info::context, convert_nonlocal_omp_clauses(), convert_nonlocal_reference_op(), convert_nonlocal_reference_stmt(), DECL_CHAIN, DECL_EXTERNAL, decl_function_context(), DECL_P, DECL_SIZE_UNIT, declare_vars(), decls, FOR_EACH_CONSTRUCTOR_VALUE, get_chain_decl(), get_nonlocal_debug_decl(), ggc_alloc(), gimple_assign_lhs(), gimple_bind_vars(), gimple_build_nop(), gimple_clobber_p(), gimple_goto_dest(), gimple_location(), gimple_omp_body(), gimple_omp_body_ptr(), gimple_omp_for_clauses_ptr(), gimple_omp_scope_clauses_ptr(), gimple_omp_sections_clauses_ptr(), gimple_omp_single_clauses_ptr(), gimple_omp_target_clauses(), gimple_omp_target_clauses_ptr(), gimple_omp_target_set_clauses(), gimple_omp_taskgroup_clauses_ptr(), gimple_omp_taskreg_clauses(), gimple_omp_taskreg_clauses_ptr(), gimple_omp_taskreg_set_clauses(), gimple_omp_teams_clauses_ptr(), gimple_omp_teams_host(), gimple_seq_first_stmt(), gsi_replace(), gsi_stmt(), i, is_gimple_omp_offloaded(), NAMELIST_DECL_ASSOCIATED_DECL, nesting_info::new_local_var_chain, NULL, NULL_TREE, OMP_CLAUSE_CHAIN, OMP_CLAUSE_DECL, OMP_CLAUSE_FIRSTPRIVATE, OMP_CLAUSE_MAP, OMP_CLAUSE_SET_MAP_KIND, OMP_CLAUSE_SIZE, nesting_info::suppress_expansion, TREE_CODE, TREE_STATIC, VAR_P, walk_body(), and walk_gimple_omp_for().

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

◆ convert_tramp_reference_op()

static tree convert_tramp_reference_op ( tree * tp,
int * walk_subtrees,
void * data )
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 build1(), build_addr(), builtin_decl_implicit(), nesting_info::context, decl_function_context(), DECL_STATIC_CHAIN, FUNC_ADDR_BY_DESCRIPTOR, get_frame_field(), ggc_alloc(), gimple_build_call(), gsi_gimplify_val(), i, init_tmp_var(), init_tmp_var_with_call(), IS_TYPE_OR_DECL_P, lookup_descr_for_decl(), lookup_tramp_for_decl(), NULL_TREE, TRAMPOLINE_IMPL_HEAP, TREE_CODE, TREE_NO_TRAMPOLINE, TREE_OPERAND, and TREE_TYPE.

Referenced by convert_all_function_calls(), and convert_tramp_reference_stmt().

◆ convert_tramp_reference_stmt()

◆ create_field_for_decl()

static tree create_field_for_decl ( struct nesting_info * info,
tree decl,
tree type )
static
Given DECL, a nested function, create a field in the non-local
frame structure for this function.   

References DECL_NAME, get_frame_type(), ggc_alloc(), insert_field_into_struct(), make_node(), TREE_ADDRESSABLE, TREE_TYPE, and type().

Referenced by lookup_descr_for_decl(), and lookup_tramp_for_decl().

◆ create_nesting_tree()

◆ create_tmp_var_for()

static tree create_tmp_var_for ( struct nesting_info * info,
tree type,
const char * prefix )
static
Like create_tmp_var, except record the variable for registration at
the given nesting level.   

References nesting_info::context, create_tmp_var_raw(), DECL_CHAIN, DECL_CONTEXT, DECL_SEEN_IN_BIND_EXPR_P, gcc_assert, ggc_alloc(), nesting_info::new_local_var_chain, TREE_ADDRESSABLE, TREE_CODE, and TYPE_SIZE_UNIT.

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

◆ finalize_nesting_tree()

static void finalize_nesting_tree ( struct nesting_info * root)
static

◆ finalize_nesting_tree_1()

static void finalize_nesting_tree_1 ( struct nesting_info * root)
static
Do "everything else" to clean up or complete state collected by the various
walking passes -- create a field to hold the frame base address, 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_descr_created, nesting_info::any_parm_remapped, nesting_info::any_tramp_created, BLOCK_VARS, build3(), build_addr(), build_init_call_stmt(), build_int_cst(), builtin_decl_explicit(), builtin_decl_implicit(), nesting_info::chain_decl, nesting_info::chain_field, chainon(), nesting_info::context, nesting_info::debug_var_chain, DECL_ARGUMENTS, DECL_CHAIN, DECL_CONTEXT, DECL_INITIAL, DECL_NAME, DECL_ORIGINAL_TYPE, DECL_SOURCE_LOCATION, DECL_STATIC_CHAIN, DECL_STRUCT_FUNCTION, declare_vars(), dump_file, dump_flags, dump_function_to_file(), fixup_vla_decls(), fold_mem_refs(), nesting_info::frame_decl, nesting_info::frame_type, gcc_assert, get_chain_decl(), get_frame_field(), get_identifier(), ggc_alloc(), gimple_bind_block(), gimple_bind_body(), gimple_bind_set_body(), gimple_body(), gimple_build_assign(), gimple_build_call(), gimple_build_try(), gimple_seq_add_seq(), gimple_seq_add_stmt(), gimple_seq_first_stmt(), gimple_seq_first_stmt_as_a_bind(), GIMPLE_TRY_FINALLY, gsi_last(), i, init_tmp_var(), init_tmp_var_with_call(), nesting_info::inner, integer_zero_node, is_gimple_reg(), is_gimple_reg_type(), layout_decl(), layout_type(), lookup_descr_for_decl(), lookup_field_for_decl(), lookup_tramp_for_decl(), make_node(), nesting_info::mem_refs, nesting_copy_decl(), nesting_info::new_local_var_chain, nesting_info::nl_goto_field, NULL, NULL_TREE, nesting_info::outer, POINTER_TYPE_P, ptr_type_node, remap_decl(), remap_type(), remap_vla_decls(), nesting_copy_body_data::root, nesting_info::thunk_p, TRAMPOLINE_IMPL_HEAP, hash_set< KeyId, Lazy, Traits >::traverse(), TREE_ADDRESSABLE, TREE_CODE, TREE_TYPE, type(), TYPE_FIELDS, TYPE_NAME, use_pointer_in_frame(), variably_modified_type_p(), and y.

Referenced by finalize_nesting_tree().

◆ fixup_vla_decls()

static void fixup_vla_decls ( tree block)
static

◆ fold_mem_refs()

bool fold_mem_refs ( tree *const & e,
void * data )
Fold the MEM_REF *E.   

References CONST_CAST2, and fold().

Referenced by finalize_nesting_tree_1().

◆ free_nesting_tree()

static void free_nesting_tree ( struct nesting_info * root)
static

◆ get_chain_decl()

◆ get_chain_field()

static tree get_chain_field ( struct nesting_info * info)
static

◆ get_descriptor_type()

◆ get_frame_field()

static tree get_frame_field ( struct nesting_info * info,
tree target_context,
tree field,
gimple_stmt_iterator * gsi )
static

◆ get_frame_type()

static tree get_frame_type ( struct nesting_info * info)
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_raw(), DECL_CONTEXT, DECL_NAME, DECL_NONLOCAL_FRAME, DECL_SEEN_IN_BIND_EXPR_P, nesting_info::frame_decl, nesting_info::frame_type, free(), get_identifier(), ggc_alloc(), IDENTIFIER_POINTER, make_node(), NULL, TREE_ADDRESSABLE, type(), and TYPE_NAME.

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

◆ get_local_debug_decl()

◆ get_nl_goto_field()

static tree get_nl_goto_field ( struct nesting_info * info)
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(), DECL_NAME, get_frame_type(), get_identifier(), GET_MODE_SIZE(), ggc_alloc(), insert_field_into_struct(), make_node(), nesting_info::nl_goto_field, ptr_mode, ptr_type_node, SAVE_NONLOCAL, SET_DECL_ALIGN, size_int, TREE_ADDRESSABLE, TREE_TYPE, type(), TYPE_ALIGN, lang_hooks_for_types::type_for_mode, and lang_hooks::types.

Referenced by convert_nl_goto_reference().

◆ get_nonlocal_debug_decl()

◆ get_static_chain()

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 build3(), build_addr(), build_simple_mem_ref_notrap(), nesting_info::context, nesting_info::frame_decl, get_chain_decl(), get_chain_field(), ggc_alloc(), i, init_tmp_var(), NULL_TREE, nesting_info::outer, nesting_info::static_chain_added, and TREE_TYPE.

Referenced by convert_gimple_call().

◆ get_trampoline_type()

◆ gimplify_all_functions()

static void gimplify_all_functions ( struct cgraph_node * root)
static

◆ gsi_gimplify_val()

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().

◆ init_tmp_var()

◆ init_tmp_var_with_call()

◆ insert_field_into_struct()

◆ iter_nestinfo_next()

static struct nesting_info * iter_nestinfo_next ( struct nesting_info * node)
inlinestatic

◆ iter_nestinfo_start()

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

References nesting_info::inner.

Referenced by free_nesting_tree(), and iter_nestinfo_next().

◆ lookup_descr_for_decl()

static tree lookup_descr_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 descriptor for this function.   

References nesting_info::any_descr_created, create_field_for_decl(), get_descriptor_type(), ggc_alloc(), insert(), lookup_element_for_decl(), NULL_TREE, and TREE_VALUE.

Referenced by convert_tramp_reference_op(), and finalize_nesting_tree_1().

◆ lookup_element_for_decl()

static tree lookup_element_for_decl ( struct nesting_info * info,
tree decl,
enum insert_option insert )
static
Given DECL, a nested function, find or create an element in the
var map for this function.   

References build_tree_list(), hash_map< KeyId, Value, Traits >::get(), hash_map< KeyId, Value, Traits >::get_or_insert(), ggc_alloc(), insert(), NULL_TREE, and nesting_info::var_map.

Referenced by lookup_descr_for_decl(), and lookup_tramp_for_decl().

◆ lookup_field_for_decl()

◆ lookup_tramp_for_decl()

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, create_field_for_decl(), get_trampoline_type(), ggc_alloc(), insert(), lookup_element_for_decl(), NULL_TREE, and TREE_PURPOSE.

Referenced by convert_tramp_reference_op(), and finalize_nesting_tree_1().

◆ lower_nested_functions()

◆ maybe_record_nested_function()

◆ nesting_copy_decl()

static tree nesting_copy_decl ( tree decl,
copy_body_data * id )
static
A helper subroutine for debug_var_chain type remapping.   

References copy_decl_no_change(), DECL_ORIGINAL_TYPE, ggc_alloc(), remap_type(), TREE_CODE, and VAR_P.

Referenced by finalize_nesting_tree_1(), and remap_vla_decls().

◆ note_nonlocal_vla_type()

◆ remap_vla_decls()

◆ save_tmp_var()

static tree save_tmp_var ( struct nesting_info * info,
tree exp,
gimple_stmt_iterator * gsi )
static

◆ unnest_function()

◆ unnest_nesting_tree()

static void unnest_nesting_tree ( struct nesting_info * root)
static

◆ unnest_nesting_tree_1()

static void unnest_nesting_tree_1 ( struct nesting_info * root)
static

◆ use_pointer_in_frame()

static bool use_pointer_in_frame ( tree decl)
static

◆ walk_all_functions()

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 FOR_EACH_NEST_INFO, ggc_alloc(), and walk_function().

Referenced by lower_nested_functions().

◆ walk_body()

◆ walk_function()

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 ggc_alloc(), gimple_body(), gimple_set_body(), walk_stmt_info::info, and walk_body().

Referenced by convert_all_function_calls(), and walk_all_functions().

◆ walk_gimple_omp_for()

Variable Documentation

◆ descriptor_type

tree descriptor_type
static
Build or return the type used to represent a nested function descriptor.   

Referenced by get_descriptor_type().

◆ nested_function_sum

function_summary<nested_function_info *>* nested_function_sum = NULL
static
Nested function decomposition for GIMPLE.
Copyright (C) 2004-2024 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.   
Summary of nested functions.   

Referenced by nested_function_info::get(), nested_function_info::get_create(), nested_function_info::release(), and unnest_function().

◆ nesting_info_bitmap_obstack

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().

◆ trampoline_type

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

Referenced by get_trampoline_type().