GCC Middle and Back End API Reference
nesting_info Struct Reference
Collaboration diagram for nesting_info:

Data Fields

struct nesting_infoouter
 
struct nesting_infoinner
 
struct nesting_infonext
 
hash_map< tree, tree > * field_map
 
hash_map< tree, tree > * var_map
 
hash_set< tree * > * mem_refs
 
bitmap suppress_expansion
 
tree context
 
tree new_local_var_chain
 
tree debug_var_chain
 
tree frame_type
 
tree frame_decl
 
tree chain_field
 
tree chain_decl
 
tree nl_goto_field
 
bool thunk_p
 
bool any_parm_remapped
 
bool any_tramp_created
 
bool any_descr_created
 
char static_chain_added
 

Detailed Description

The object of this pass is to lower the representation of a set of nested
functions in order to expose all of the gory details of the various
nonlocal references.  We want to do this sooner rather than later, in
order to give us more freedom in emitting all of the functions in question.

Back in olden times, when gcc was young, we developed an insanely
complicated scheme whereby variables which were referenced nonlocally
were forced to live in the stack of the declaring function, and then
the nested functions magically discovered where these variables were
placed.  In order for this scheme to function properly, it required
that the outer function be partially expanded, then we switch to
compiling the inner function, and once done with those we switch back
to compiling the outer function.  Such delicate ordering requirements
makes it difficult to do whole translation unit optimizations
involving such functions.

The implementation here is much more direct.  Everything that can be
referenced by an inner function is a member of an explicitly created
structure herein called the "nonlocal frame struct".  The incoming
static chain for a nested function is a pointer to this struct in
the parent.  In this way, we settle on known offsets from a known
base, and so are decoupled from the logic that places objects in the
function's stack frame.  More importantly, we don't have to wait for
that to happen -- since the compilation of the inner function is no
longer tied to a real stack frame, the nonlocal frame struct can be
allocated anywhere.  Which means that the outer function is now
inlinable.

Theory of operation here is very simple.  Iterate over all the
statements in all the functions (depth first) several times,
allocating structures and fields on demand.  In general we want to
examine inner functions first, so that we can avoid making changes
to outer functions which are unnecessary.

The order of the passes matters a bit, in that later passes will be
skipped if it is discovered that the functions don't actually interact
at all.  That is, they're nested in the lexical sense but could have
been written as independent functions without change.   

Field Documentation

◆ any_descr_created

bool nesting_info::any_descr_created

◆ any_parm_remapped

bool nesting_info::any_parm_remapped

◆ any_tramp_created

bool nesting_info::any_tramp_created

◆ chain_decl

tree nesting_info::chain_decl

◆ chain_field

tree nesting_info::chain_field

◆ context

◆ debug_var_chain

tree nesting_info::debug_var_chain

◆ field_map

hash_map<tree, tree>* nesting_info::field_map

◆ frame_decl

◆ frame_type

tree nesting_info::frame_type

◆ inner

◆ mem_refs

◆ new_local_var_chain

◆ next

struct nesting_info* nesting_info::next

◆ nl_goto_field

tree nesting_info::nl_goto_field

◆ outer

◆ static_chain_added

◆ suppress_expansion

◆ thunk_p

◆ var_map


The documentation for this struct was generated from the following file: