GCC Middle and Back End API Reference
tree-cfg.h File Reference

Go to the source code of this file.


void init_empty_tree_cfg_for_function (struct function *)
void init_empty_tree_cfg (void)
void fold_cond_expr_cond (void)
void start_recording_case_labels (void)
void end_recording_case_labels (void)
basic_block label_to_block_fn (struct function *, tree)
void make_abnormal_goto_edges (basic_block, bool)
void cleanup_dead_labels (void)
void group_case_labels_stmt (gimple)
void group_case_labels (void)
void replace_uses_by (tree, tree)
basic_block single_noncomplex_succ (basic_block bb)
void notice_special_calls (gimple)
void clear_special_calls (void)
edge find_taken_edge (basic_block, tree)
void gimple_debug_bb (basic_block)
basic_block gimple_debug_bb_n (int)
void gimple_debug_cfg (int)
void gimple_dump_cfg (FILE *, int)
void dump_cfg_stats (FILE *)
void debug_cfg_stats (void)
bool stmt_can_make_abnormal_goto (gimple)
bool is_ctrl_stmt (gimple)
bool is_ctrl_altering_stmt (gimple)
bool simple_goto_p (gimple)
bool stmt_ends_bb_p (gimple)
void delete_tree_cfg_annotations (void)
gimple first_stmt (basic_block)
gimple last_stmt (basic_block)
gimple last_and_only_stmt (basic_block)
void verify_gimple_in_seq (gimple_seq)
void verify_gimple_in_cfg (struct function *)
tree gimple_block_label (basic_block)
void add_phi_args_after_copy_bb (basic_block)
void add_phi_args_after_copy (basic_block *, unsigned, edge)
bool gimple_duplicate_sese_region (edge, edge, basic_block *, unsigned, basic_block *, bool)
bool gimple_duplicate_sese_tail (edge, edge, basic_block *, unsigned, basic_block *)
void gather_blocks_in_sese_region (basic_block entry, basic_block exit, vec< basic_block > *bbs_p)
basic_block move_sese_region_to_fn (struct function *, basic_block, basic_block, tree)
void dump_function_to_file (tree, FILE *, int)
void debug_function (tree, int)
void print_loops_bb (FILE *, basic_block, int, int)
void print_loops (FILE *, int)
void debug (struct loop &ref)
void debug (struct loop *ptr)
void debug_verbose (struct loop &ref)
void debug_verbose (struct loop *ptr)
void debug_loops (int)
void debug_loop (struct loop *, int)
void debug_loop_num (unsigned, int)
void remove_edge_and_dominated_blocks (edge)
bool gimple_purge_dead_eh_edges (basic_block)
bool gimple_purge_all_dead_eh_edges (const_bitmap)
bool gimple_purge_dead_abnormal_call_edges (basic_block)
bool gimple_purge_all_dead_abnormal_call_edges (const_bitmap)
tree gimplify_build3 (gimple_stmt_iterator *, enum tree_code, tree, tree, tree, tree)
tree gimplify_build2 (gimple_stmt_iterator *, enum tree_code, tree, tree, tree)
tree gimplify_build1 (gimple_stmt_iterator *, enum tree_code, tree, tree)
void extract_true_false_edges_from_block (basic_block, edge *, edge *)
unsigned int execute_fixup_cfg (void)

Function Documentation

void add_phi_args_after_copy ( basic_block region_copy,
unsigned  n_region,
edge  e_copy 
   Blocks in REGION_COPY array of length N_REGION were created by
   duplication of basic blocks.  Add phi node arguments for edges
   going from these blocks.  If E_COPY is not NULL, also add
   phi node arguments for its destination.

Referenced by tm_memopt_clear_visited().

void add_phi_args_after_copy_bb ( basic_block  )
void cleanup_dead_labels ( void  )
   Cleanup redundant labels.  This is a three-step process:
     1) Find the leading label for each block.
     2) Redirect all references to labels to the leading labels.
     3) Cleanup all useless labels.  
     Find a suitable label for each block.  We use the first user-defined
     label if there is one, or otherwise just the first label we see.  
             If we have not yet seen a label for the current block,
             remember this one and see if there are more labels.  
             If we did see a label for the current block already, but it
             is an artificially created label, replace it if the current
             label is a user defined label.  
     Now redirect all jumps/branches to the selected label.
     First do so for each block ending in a control statement.  
               Replace all destination labels.  
           We have to handle gotos until they're removed, and we don't
           remove them until after we've created the CFG edges.  
     Do the same for the exception region tree labels.  
     Finally, purge dead labels.  All user-defined labels and labels that
     can be the target of non-local gotos and labels which have their
     address taken are preserved.  
         If the main label of the block is unused, we may still remove it.  

References gimple_asm_label_op(), and main_block_label().

void clear_special_calls ( void  )
   Clear flags set by notice_special_calls.  Used by dead code removal
   to update the flags.  
void debug ( struct loop ref)
void debug ( struct loop ptr)
void debug_cfg_stats ( void  )
   Dump CFG statistics on stderr.  Keep extern so that it's always
   linked in the final executable.  

References cfg_stats, gimple_label_label(), and cfg_stats_d::num_merged_labels.

void debug_function ( tree  ,
void debug_loop ( struct loop ,
void debug_loop_num ( unsigned  ,
void debug_loops ( int  )
void debug_verbose ( struct loop ref)
void debug_verbose ( struct loop ptr)
void delete_tree_cfg_annotations ( void  )
   Remove block annotations and other data structures.  
void dump_cfg_stats ( FILE *  )
void dump_function_to_file ( tree  ,
FILE *  ,
void end_recording_case_labels ( void  )
   Stop recording information mapping edges to case labels and
   remove any information we have recorded.  
unsigned int execute_fixup_cfg ( void  )
   IPA passes, compilation of earlier functions or inlining
   might have changed some properties, such as marked functions nothrow,
   pure, const or noreturn.
   Remove redundant edges and basic blocks, and create new ones if necessary.

   This pass can't be executed as stand alone pass from pass manager, because
   in between inlining and this fixup the verify_flow_info would fail.  
         If we have a basic block with no successors that does not
         end with a control statement or a noreturn call end it with
         a call to __builtin_unreachable.  This situation can occur
         when inlining a noreturn call that does in fact return.  
     We just processed all calls.  
     Dump a textual representation of the flowgraph.  
void extract_true_false_edges_from_block ( basic_block  b,
edge true_edge,
edge false_edge 
   Given a basic block B which ends with a conditional and has
   precisely two successors, determine which of the edges is taken if
   the conditional is true and which is taken if the conditional is
   false.  Set TRUE_EDGE and FALSE_EDGE appropriately.  

Referenced by associate_equivalences_with_edges(), check_forbidden_calls(), operand_equal_for_value_replacement(), and simple_mem_ref_in_stmt().

edge find_taken_edge ( basic_block  ,
gimple first_stmt ( basic_block  )
void fold_cond_expr_cond ( void  )
   Fold COND_EXPR_COND of each COND_EXPR.  
void gather_blocks_in_sese_region ( basic_block  entry,
basic_block  exit,
vec< basic_block > *  bbs_p 
   Add all the blocks dominated by ENTRY to the array BBS_P.  Stop
   adding blocks when the dominator traversal reaches EXIT.  This
   function silently assumes that ENTRY strictly dominates EXIT.  

Referenced by create_loads_and_stores_for_name(), and move_stmt_r().

tree gimple_block_label ( basic_block  )
void gimple_debug_bb ( basic_block  )
basic_block gimple_debug_bb_n ( int  )
void gimple_debug_cfg ( int  )
void gimple_dump_cfg ( FILE *  ,
bool gimple_duplicate_sese_region ( edge  entry,
edge  exit,
basic_block region,
unsigned  n_region,
basic_block region_copy,
bool  update_dominance 
   Duplicates a REGION (set of N_REGION basic blocks) with just a single
   important exit edge EXIT.  By important we mean that no SSA name defined
   inside region is live over the other exit edges of the region.  All entry
   edges to the region must go to ENTRY->dest.  The edge ENTRY is redirected
   to the duplicate of the region.  Dominance and loop information is
   updated if UPDATE_DOMINANCE is true, but not the SSA web.  If
   UPDATE_DOMINANCE is false then we assume that the caller will update the
   dominance information after calling this function.  The new basic
   blocks are stored to REGION_COPY in the same order as they had in REGION,
   provided that REGION_COPY is not NULL.
   The function returns false if it is unable to copy the region,
   true otherwise.  
     Some sanity checking.  Note that we do not check for all possible
     missuses of the functions.  I.e. if you ask to copy something weird,
     it will work, but the state of structures probably will not be
         We do not handle subloops, i.e. all the blocks must belong to the
         same loop.  
     In case the function is used for loop header copying (which is the primary
     use), ensure that EXIT and its copy will be new latch and entry edges.  
     Record blocks outside the region that are dominated by something
         Fix up corner cases, to avoid division by zero or creation of negative
         Fix up corner cases, to avoid division by zero or creation of negative
     Redirect the entry and add the phi node arguments.  
     Concerning updating of dominators:  We must recount dominators
     for entry block and its copy.  Anything that is outside of the
     region, but was dominated by something inside needs recounting as
     Add the other PHI node arguments.  
bool gimple_duplicate_sese_tail ( edge  entry,
edge  exit,
basic_block region,
unsigned  n_region,
basic_block region_copy 

Duplicates REGION consisting of N_REGION blocks. The new blocks are stored to REGION_COPY in the same order in that they appear in REGION, if REGION_COPY is not NULL. ENTRY is the entry to the region, EXIT an exit from it. The condition guarding EXIT is moved to ENTRY. Returns true if duplication succeeds, false otherwise.

For example,

some_code; if (cond) A; else B;

is transformed to

if (cond) { some_code; A; } else { some_code; B; }

     Record blocks outside the region that are dominated by something
         Fix up corner cases, to avoid division by zero or creation of negative
         Fix up corner cases, to avoid division by zero or creation of negative
     Create the switch block, and put the exit condition to it.  
     Register the new edge from SWITCH_BB in loop exit lists.  
     Add the PHI node arguments.  
     Get rid of now superfluous conditions and associated edges (and phi node
     The latch of ORIG_LOOP was copied, and so was the backedge 
     to the original header.  We redirect this backedge to EXIT_BB.  
     Anything that is outside of the region, but was dominated by something
     inside needs to update dominance info.  
     Update the SSA web.  

Referenced by create_loop_fn().

bool gimple_purge_all_dead_abnormal_call_edges ( const_bitmap  )
bool gimple_purge_all_dead_eh_edges ( const_bitmap  )
bool gimple_purge_dead_abnormal_call_edges ( basic_block  )
bool gimple_purge_dead_eh_edges ( basic_block  )
tree gimplify_build1 ( gimple_stmt_iterator gsi,
enum tree_code  code,
tree  type,
tree  a 
   Build a unary operation and gimplify it.  Emit code before GSI.
   Return the gimple_val holding the result.  

Referenced by expand_complex_libcall().

tree gimplify_build2 ( gimple_stmt_iterator gsi,
enum tree_code  code,
tree  type,
tree  a,
tree  b 
   Build a binary operation and gimplify it.  Emit code before GSI.
   Return the gimple_val holding the result.  

Referenced by add_rshift(), and expand_complex_libcall().

tree gimplify_build3 ( gimple_stmt_iterator gsi,
enum tree_code  code,
tree  type,
tree  a,
tree  b,
tree  c 
   Build a ternary operation and gimplify it.  Emit code before GSI.
   Return the gimple_val holding the result.  

References current_ir_type(), edge_def::dest, edge_def::edge_def_insns::g, edge_def::goto_locus, gt_pch_nx(), edge_def::insns, IR_GIMPLE, edge_def::edge_def_insns::r, and edge_def::src.

void group_case_labels ( void  )
   Look for blocks ending in a multiway branch (a GIMPLE_SWITCH),
   and scan the sorted vector of cases.  Combine the ones jumping to the
   same label.  

References edge_def::flags, gimple_phi_arg_edge(), replace_exp(), and virtual_operand_p().

void group_case_labels_stmt ( gimple  )
void init_empty_tree_cfg ( void  )
void init_empty_tree_cfg_for_function ( struct function )
bool is_ctrl_altering_stmt ( gimple  )
bool is_ctrl_stmt ( gimple  )
basic_block label_to_block_fn ( struct function ,
gimple last_and_only_stmt ( basic_block  )
gimple last_stmt ( basic_block  )
void make_abnormal_goto_edges ( basic_block  ,
basic_block move_sese_region_to_fn ( struct function dest_cfun,
basic_block  entry_bb,
basic_block  exit_bb,
tree  orig_block 
   Move a single-entry, single-exit region delimited by ENTRY_BB and
   EXIT_BB to function DEST_CFUN.  The whole region is replaced by a
   single basic block in the original CFG and the new basic block is
   returned.  DEST_CFUN must not have a CFG yet.

   Note that the region need not be a pure SESE region.  Blocks inside
   the region may contain calls to abort/exit.  The only restriction
   is that ENTRY_BB should be the only entry point and it must
   dominate EXIT_BB.

   Change TREE_BLOCK of all statements in ORIG_BLOCK to the new
   functions outermost BLOCK, move all subblocks of ORIG_BLOCK
   to the new function.

   All local variables referenced in the region are assumed to be in
   the corresponding BLOCK_VARS and unexpanded variable lists
   associated with DEST_CFUN.  
     If ENTRY does not strictly dominate EXIT, this cannot be an SESE
     Collect all the blocks in the region.  Manually add ENTRY_BB
     because it won't be added by dfs_enumerate_from.  
     The blocks that used to be dominated by something in BBS will now be
     dominated by the new block.  
     Detach ENTRY_BB and EXIT_BB from CFUN->CFG.  We need to remember
     the predecessor edges to ENTRY_BB and the successor edges to
     EXIT_BB so that we can re-attach them to the new basic block that
     will replace the region.  
     Switch context to the child function to initialize DEST_FN's CFG.  
     Initialize EH information for the new function.  
     Initialize an empty loop tree.  
     Move the outlined loop tree part.  
                 If the SESE region contains some bbs ending with
                 a noreturn call, those are considered to belong
                 to the outermost loop in saved_cfun, rather than
                 the entry_bb's loop_father.  
         Remove loop exits from the outlined region.  
     Adjust the number of blocks in the tree root of the outlined part.  
     Setup a mapping to be used by move_block_to_fn.  
     Move blocks from BBS into DEST_CFUN.  
         No need to update edge counts on the last block.  It has
         already been updated earlier when we detached the region from
         the original CFG.  
     Loop sizes are no longer correct, fix them up.  
     Rewire BLOCK_SUBBLOCKS of orig_block.  
     Rewire the entry and exit blocks.  The successor to the entry
     block turns into the successor of DEST_FN's ENTRY_BLOCK_PTR in
     the child function.  Similarly, the predecessor of DEST_FN's
     EXIT_BLOCK_PTR turns into the predecessor of EXIT_BLOCK_PTR.  We
     need to switch CFUN between DEST_CFUN and SAVED_CFUN so that the
     various CFG manipulation function get to the right CFG.

     FIXME, this is silly.  The CFG ought to become a parameter to
     these helpers.  
     Back in the original function, the SESE region has disappeared,
     create a new basic block in its place.  

References gimple_body(), gimple_seq_first_stmt(), gimple_seq_last_stmt(), and print_gimple_seq().

void notice_special_calls ( gimple  )
void print_loops ( FILE *  ,
void print_loops_bb ( FILE *  ,
basic_block  ,
int  ,
void remove_edge_and_dominated_blocks ( edge  )
void replace_uses_by ( tree  ,
bool simple_goto_p ( gimple  )
basic_block single_noncomplex_succ ( basic_block  bb)
void start_recording_case_labels ( void  )
   Start recording information mapping edges to case labels.  
bool stmt_can_make_abnormal_goto ( gimple  )
bool stmt_ends_bb_p ( gimple  )
void verify_gimple_in_cfg ( struct function )
void verify_gimple_in_seq ( gimple_seq  )