GCC Middle and Back End API Reference
cfg.cc File Reference
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "hard-reg-set.h"
#include "tree.h"
#include "cfghooks.h"
#include "df.h"
#include "cfganal.h"
#include "cfgloop.h"
#include "dumpfile.h"
#include "cfg-flags.def"
Include dependency graph for cfg.cc:

Macros

#define DEF_EDGE_FLAG(NAME, IDX)   #NAME ,
 
#define DEF_BASIC_BLOCK_FLAG(NAME, IDX)   #NAME ,
 

Typedefs

typedef hash_map< int_hash< int, -1, -2 >, int > copy_map_t
 

Functions

void init_flow (struct function *the_fun)
 
static void free_edge (function *fn, edge e)
 
static void free_block (basic_block bb)
 
void free_cfg (struct function *fn)
 
basic_block alloc_block (void)
 
void link_block (basic_block b, basic_block after)
 
void unlink_block (basic_block b)
 
void compact_blocks (void)
 
void expunge_block (basic_block b)
 
static void connect_src (edge e)
 
static void connect_dest (edge e)
 
static void disconnect_src (edge e)
 
static void disconnect_dest (edge e)
 
edge unchecked_make_edge (basic_block src, basic_block dst, int flags)
 
edge cached_make_edge (sbitmap edge_cache, basic_block src, basic_block dst, int flags)
 
edge make_edge (basic_block src, basic_block dest, int flags)
 
edge make_single_succ_edge (basic_block src, basic_block dest, int flags)
 
void remove_edge_raw (edge e)
 
void redirect_edge_succ (edge e, basic_block new_succ)
 
void redirect_edge_pred (edge e, basic_block new_pred)
 
void clear_bb_flags (void)
 
static void check_bb_profile (basic_block bb, FILE *file, int indent)
 
void dump_edge_info (FILE *file, edge e, dump_flags_t flags, int do_succ)
 
DEBUG_FUNCTION void debug (edge_def &ref)
 
DEBUG_FUNCTION void debug (edge_def *ptr)
 
static void debug_slim (edge e)
 
static void alloc_aux_for_block (basic_block bb, int size)
 
void alloc_aux_for_blocks (int size)
 
void clear_aux_for_blocks (void)
 
void free_aux_for_blocks (void)
 
void alloc_aux_for_edge (edge e, int size)
 
void alloc_aux_for_edges (int size)
 
void clear_aux_for_edges (void)
 
void free_aux_for_edges (void)
 
DEBUG_FUNCTION void debug_bb (basic_block bb)
 
DEBUG_FUNCTION basic_block debug_bb_n (int n)
 
DEBUG_FUNCTION void debug_bb (basic_block bb, dump_flags_t flags)
 
DEBUG_FUNCTION basic_block debug_bb_n (int n, dump_flags_t flags)
 
void dump_bb_info (FILE *outf, basic_block bb, int indent, dump_flags_t flags, bool do_header, bool do_footer)
 
void brief_dump_cfg (FILE *file, dump_flags_t flags)
 
void set_edge_probability_and_rescale_others (edge e, profile_probability new_prob)
 
void update_bb_profile_for_threading (basic_block bb, profile_count count, edge taken_edge)
 
void scale_bbs_frequencies_profile_count (basic_block *bbs, int nbbs, profile_count num, profile_count den)
 
void scale_bbs_frequencies (basic_block *bbs, int nbbs, profile_probability p)
 
void initialize_original_copy_tables (void)
 
void reset_original_copy_tables (void)
 
void free_original_copy_tables (void)
 
bool original_copy_tables_initialized_p (void)
 
static void copy_original_table_clear (copy_map_t *tab, unsigned obj)
 
static void copy_original_table_set (copy_map_t *tab, unsigned obj, unsigned val)
 
void set_bb_original (basic_block bb, basic_block original)
 
basic_block get_bb_original (basic_block bb)
 
void set_bb_copy (basic_block bb, basic_block copy)
 
basic_block get_bb_copy (basic_block bb)
 
void set_loop_copy (class loop *loop, class loop *copy)
 
class loopget_loop_copy (class loop *loop)
 
void scale_strictly_dominated_blocks (basic_block bb, profile_count num, profile_count den)
 

Variables

static struct obstack block_aux_obstack
 
static voidfirst_block_aux_obj = 0
 
static struct obstack edge_aux_obstack
 
static voidfirst_edge_aux_obj = 0
 
static copy_map_tbb_original
 
static copy_map_tbb_copy
 
static copy_map_tloop_copy
 

Macro Definition Documentation

◆ DEF_BASIC_BLOCK_FLAG

#define DEF_BASIC_BLOCK_FLAG ( NAME,
IDX )   #NAME ,

◆ DEF_EDGE_FLAG

#define DEF_EDGE_FLAG ( NAME,
IDX )   #NAME ,

Typedef Documentation

◆ copy_map_t

typedef hash_map<int_hash<int, -1, -2>, int> copy_map_t
Data structures used to maintain mapping between basic blocks and
copies.   

Function Documentation

◆ alloc_aux_for_block()

static void alloc_aux_for_block ( basic_block bb,
int size )
static
Allocate a memory block of SIZE as BB->aux.  The obstack must
be first initialized by alloc_aux_for_blocks.   

References basic_block_def::aux, block_aux_obstack, first_block_aux_obj, gcc_assert, and ggc_alloc().

Referenced by alloc_aux_for_blocks().

◆ alloc_aux_for_blocks()

void alloc_aux_for_blocks ( int size)

◆ alloc_aux_for_edge()

void alloc_aux_for_edge ( edge e,
int size )
Allocate a memory edge of SIZE as E->aux.  The obstack must
be first initialized by alloc_aux_for_edges.   

References edge_aux_obstack, first_edge_aux_obj, gcc_assert, and ggc_alloc().

Referenced by alloc_aux_for_edges().

◆ alloc_aux_for_edges()

void alloc_aux_for_edges ( int size)
Initialize the edge_aux_obstack and if SIZE is nonzero, call
alloc_aux_for_edge for each basic edge.   

References alloc_aux_for_edge(), cfun, edge_aux_obstack, ENTRY_BLOCK_PTR_FOR_FN, EXIT_BLOCK_PTR_FOR_FN, first_edge_aux_obj, FOR_BB_BETWEEN, FOR_EACH_EDGE, gcc_assert, gcc_obstack_init, ggc_alloc(), initialized, and basic_block_def::succs.

Referenced by branch_prob(), and estimate_bb_frequencies().

◆ alloc_block()

◆ brief_dump_cfg()

void brief_dump_cfg ( FILE * file,
dump_flags_t flags )
Dumps a brief description of cfg to FILE.   

References cfun, dump_bb_info(), FOR_EACH_BB_FN, and TDF_DETAILS.

Referenced by gimple_dump_cfg().

◆ cached_make_edge()

edge cached_make_edge ( sbitmap edge_cache,
basic_block src,
basic_block dst,
int flags )
Create an edge connecting SRC and DST with FLAGS optionally using
edge cache CACHE.  Return the new edge, NULL if already exist.   

References bitmap_bit_p, bitmap_set_bit, cfun, ENTRY_BLOCK_PTR_FOR_FN, EXIT_BLOCK_PTR_FOR_FN, find_edge(), ggc_alloc(), basic_block_def::index, make_edge(), NULL, and unchecked_make_edge().

Referenced by make_edges(), and make_label_edge().

◆ check_bb_profile()

static void check_bb_profile ( basic_block bb,
FILE * file,
int indent )
static
Check the consistency of profile information.  We can't do that
in verify_flow_info, as the counts may get invalid for incompletely
solved graphs, later eliminating of conditionals or roundoff errors.
It is still practical to have them reported for debugging of simple
testcases.   

References alloca, profile_probability::always(), BB_PARTITION, basic_block_def::count, current_function_decl, DECL_STRUCT_FUNCTION, profile_count::dump(), ENTRY_BLOCK_PTR_FOR_FN, EXIT_BLOCK_PTR_FOR_FN, FOR_EACH_EDGE, ggc_alloc(), profile_probability::never(), basic_block_def::preds, probably_never_executed_bb_p(), probably_never_executed_edge_p(), PROFILE_ABSENT, profile_status_for_fn, REG_BR_PROB_BASE, basic_block_def::succs, and profile_count::zero().

Referenced by dump_bb_info().

◆ clear_aux_for_blocks()

◆ clear_aux_for_edges()

◆ clear_bb_flags()

◆ compact_blocks()

◆ connect_dest()

static void connect_dest ( edge e)
inlinestatic

◆ connect_src()

static void connect_src ( edge e)
inlinestatic
Connect E to E->src.   

References df_mark_solutions_dirty(), and vec_safe_push().

Referenced by redirect_edge_pred(), and unchecked_make_edge().

◆ copy_original_table_clear()

static void copy_original_table_clear ( copy_map_t * tab,
unsigned obj )
static
Removes the value associated with OBJ from table TAB.   

References ggc_alloc(), and original_copy_tables_initialized_p().

Referenced by set_loop_copy().

◆ copy_original_table_set()

static void copy_original_table_set ( copy_map_t * tab,
unsigned obj,
unsigned val )
static
Sets the value associated with OBJ in table TAB to VAL.
Do nothing when data structures are not initialized.   

References ggc_alloc(), and original_copy_tables_initialized_p().

Referenced by set_bb_copy(), set_bb_original(), and set_loop_copy().

◆ debug() [1/2]

◆ debug() [2/2]

DEBUG_FUNCTION void debug ( edge_def * ptr)

References debug, and ggc_alloc().

◆ debug_bb() [1/2]

◆ debug_bb() [2/2]

DEBUG_FUNCTION void debug_bb ( basic_block bb,
dump_flags_t flags )
Print BB with specified FLAGS.   

References dump_bb(), and ggc_alloc().

◆ debug_bb_n() [1/2]

DEBUG_FUNCTION basic_block debug_bb_n ( int n)

References BASIC_BLOCK_FOR_FN, cfun, and debug_bb().

◆ debug_bb_n() [2/2]

DEBUG_FUNCTION basic_block debug_bb_n ( int n,
dump_flags_t flags )
Print basic block numbered N with specified FLAGS.   

References BASIC_BLOCK_FOR_FN, cfun, and debug_bb().

◆ debug_slim()

static void debug_slim ( edge e)
static

References ggc_alloc().

Referenced by debug_helper(), debug_helper(), and debug_helper().

◆ disconnect_dest()

static void disconnect_dest ( edge e)
inlinestatic
Disconnect edge E from E->dest.   

References df_mark_solutions_dirty(), EDGE_COUNT, EDGE_PRED, and basic_block_def::preds.

Referenced by redirect_edge_succ(), and remove_edge_raw().

◆ disconnect_src()

static void disconnect_src ( edge e)
inlinestatic

◆ dump_bb_info()

void dump_bb_info ( FILE * outf,
basic_block bb,
int indent,
dump_flags_t flags,
bool do_header,
bool do_footer )
Dumps cfg related information about basic block BB to OUTF.
If HEADER is true, dump things that appear before the instructions
contained in BB.  If FOOTER is true, dump things that appear after.
Flags are the TDF_* masks as documented in dumpfile.h.
NB: With TDF_DETAILS, it is assumed that cfun is available, so
that maybe_hot_bb_p and probably_never_executed_bb_p don't ICE.   

References alloca, BB_ALL_FLAGS, bb_loop_depth(), cfun, check_bb_profile(), basic_block_def::count, current_function_decl, DECL_STRUCT_FUNCTION, profile_count::dump(), dump_edge_info(), basic_block_def::flags, FOR_EACH_EDGE, fputc(), gcc_assert, ggc_alloc(), i, basic_block_def::index, profile_count::initialized_p(), maybe_hot_bb_p(), basic_block_def::next_bb, NULL, basic_block_def::preds, basic_block_def::prev_bb, probably_never_executed_bb_p(), basic_block_def::succs, and TDF_DETAILS.

Referenced by brief_dump_cfg(), dump_bb(), and print_rtl_with_bb().

◆ dump_edge_info()

◆ expunge_block()

void expunge_block ( basic_block b)
Remove block B from the basic block array.   

References b, cfun, n_basic_blocks_for_fn, NULL, SET_BASIC_BLOCK_FOR_FN, and unlink_block().

Referenced by delete_basic_block(), and merge_blocks().

◆ free_aux_for_blocks()

void free_aux_for_blocks ( void )

◆ free_aux_for_edges()

void free_aux_for_edges ( void )
Free data allocated in edge_aux_obstack and clear AUX pointers
of all edges.   

References clear_aux_for_edges(), edge_aux_obstack, first_edge_aux_obj, gcc_assert, ggc_alloc(), and NULL.

Referenced by branch_prob(), and estimate_bb_frequencies().

◆ free_block()

static void free_block ( basic_block bb)
static
Free basic block BB.   

References ggc_free(), NULL, basic_block_def::preds, basic_block_def::succs, and vec_free().

Referenced by free_cfg().

◆ free_cfg()

◆ free_edge()

static void free_edge ( function * fn,
edge e )
static
Helper function for remove_edge and free_cffg.  Frees edge structure
without actually removing it from the pred/succ arrays.   

References ggc_free(), and n_edges_for_fn.

Referenced by free_cfg(), and remove_edge_raw().

◆ free_original_copy_tables()

◆ get_bb_copy()

◆ get_bb_original()

◆ get_loop_copy()

◆ init_flow()

void init_flow ( struct function * the_fun)
Control flow graph manipulation code for GNU compiler.
   Copyright (C) 1987-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/>.   
This file contains low level functions to manipulate the CFG and
 analyze it.  All other modules should not transform the data structure
 directly and use abstraction instead.  The file is supposed to be
 ordered bottom-up and should not contain any code dependent on a
 particular intermediate language (RTL or trees).

 Available functionality:
   - Initialization/deallocation
       init_flow, free_cfg
   - Low level basic block manipulation
       alloc_block, expunge_block
   - Edge manipulation
       make_edge, make_single_succ_edge, cached_make_edge, remove_edge
       - Low level edge redirection (without updating instruction chain)
           redirect_edge_succ, redirect_edge_succ_nodup, redirect_edge_pred
   - Dumping and debugging
       dump_flow_info, debug_flow_info, dump_edge_info
   - Allocation of AUX fields for basic blocks
       alloc_aux_for_blocks, free_aux_for_blocks, alloc_aux_for_block
   - clear_bb_flags
   - Consistency checking
       verify_flow_info
   - Dumping and debugging
       print_rtl_with_bb, dump_bb, debug_bb, debug_bb_n

 TODO: Document these "Available functionality" functions in the files
 that implement them.
Called once at initialization time.   

References alloc_block(), BB_ALL_FLAGS, EDGE_ALL_FLAGS, ENTRY_BLOCK, ENTRY_BLOCK_PTR_FOR_FN, EXIT_BLOCK, EXIT_BLOCK_PTR_FOR_FN, ggc_alloc(), n_edges_for_fn, and profile_count::uninitialized().

Referenced by init_empty_tree_cfg_for_function().

◆ initialize_original_copy_tables()

◆ link_block()

◆ make_edge()

edge make_edge ( basic_block src,
basic_block dest,
int flags )
Create an edge connecting SRC and DEST with flags FLAGS.  Return newly
created edge or NULL if already exist.   

References find_edge(), NULL, and unchecked_make_edge().

Referenced by add_test(), branch_fixup(), branch_prob(), cached_make_edge(), cfg_layout_split_edge(), rt_bb_visited::check(), combine_blocks(), connect_infinite_loops_to_exit(), connect_loops(), convert_if_conditions_to_switch(), copy_cfg_body(), copy_edges_for_bb(), create_cond_insert_point(), create_empty_if_region_on_edge(), create_empty_loop_on_edge(), create_parallel_loop(), tree_switch_conversion::switch_decision_tree::do_jump_if_equal(), do_split_loop_on_cond(), back_jt_path_registry::duplicate_thread_path(), edge_before_returns_twice_call(), tree_switch_conversion::jump_table_cluster::emit(), tree_switch_conversion::bit_test_cluster::emit(), tree_switch_conversion::switch_decision_tree::emit_cmp_and_jump_insns(), execute_sm_if_changed(), expand_complex_div_wide(), expand_gimple_tailcall(), expand_oacc_for(), expand_omp_atomic_pipeline(), expand_omp_for_generic(), expand_omp_for_init_counts(), expand_omp_for_init_vars(), expand_omp_for_ordered_loops(), expand_omp_for_static_chunk(), expand_omp_for_static_nochunk(), expand_omp_ordered_sink(), expand_omp_sections(), expand_omp_simd(), expand_omp_target(), expand_omp_taskloop_for_inner(), expand_omp_taskloop_for_outer(), expand_omp_taskreg(), expand_parallel_call(), expand_thunk(), expand_transaction(), extract_omp_for_update_vars(), find_bb_boundaries(), force_nonfallthru_and_redirect(), tree_switch_conversion::switch_conversion::gen_inbound_check(), gimple_divmod_fixed_value(), gimple_duplicate_sese_tail(), gimple_flow_call_edges_add(), gimple_gen_ic_func_profiler(), gimple_gen_time_profiler(), gimple_ic(), gimple_lower_bitint(), gimple_mod_pow2(), gimple_mod_subtract(), gimple_stringop_fixed_value(), handle_abnormal_edges(), tree_switch_conversion::bit_test_cluster::hoist_edge_and_branch_if_true(), hoist_guard(), init_lowered_empty_function(), input_cfg(), insert_check_and_trap(), insert_cond_bb(), rt_bb_visited::insert_exit_check_on_edge(), lv_adjust_loop_entry_edge(), make_cond_expr_edges(), make_edges(), make_edges(), make_edges_bb(), make_eh_dispatch_edges(), make_eh_edge(), make_gimple_asm_edges(), make_gimple_switch_edges(), make_goto_expr_edges(), make_single_succ_edge(), move_sese_in_condition(), move_sese_region_to_fn(), oacc_entry_exit_single_gang(), omp_make_gimple_edges(), optimize_mask_stores(), peep2_attempt(), rtl_flow_call_edges_add(), shrink_wrap_one_built_in_call_with_conds(), simd_clone_adjust(), slpeel_add_loop_guard(), split_bb_make_tm_edge(), tree_transform_and_unroll_loop(), ubsan_expand_null_ifn(), ubsan_expand_ptr_ifn(), unloop_loops(), unroll_loop_runtime_iterations(), vect_loop_versioning(), worker_single_copy(), and worker_single_simple().

◆ make_single_succ_edge()

◆ original_copy_tables_initialized_p()

bool original_copy_tables_initialized_p ( void )
Return true iff we have had a call to initialize_original_copy_tables
without a corresponding call to free_original_copy_tables.   

References bb_copy, and NULL.

Referenced by copy_original_table_clear(), copy_original_table_set(), get_bb_copy(), get_bb_original(), get_loop_copy(), and relink_block_chain().

◆ redirect_edge_pred()

◆ redirect_edge_succ()

◆ remove_edge_raw()

void remove_edge_raw ( edge e)
This function will remove an edge from the flow graph.   

References cfun, disconnect_dest(), disconnect_src(), execute_on_shrinking_pred(), free_edge(), and remove_predictions_associated_with_edge().

Referenced by remove_edge().

◆ reset_original_copy_tables()

void reset_original_copy_tables ( void )
Reset the data structures to maintain mapping between blocks and
its copies.   

References bb_copy, bb_original, hash_map< KeyId, Value, Traits >::empty(), and loop_copy.

Referenced by vect_do_peeling().

◆ scale_bbs_frequencies()

void scale_bbs_frequencies ( basic_block * bbs,
int nbbs,
profile_probability p )
Multiply all frequencies of basic blocks in array BBS of length NBBS
by NUM/DEN, in profile_count arithmetic.  More accurate than previous
function but considerably slower.   

References count, ggc_alloc(), and i.

Referenced by duplicate_loop_body_to_header_edge(), hoist_guard(), scale_loop_frequencies(), and vect_do_peeling().

◆ scale_bbs_frequencies_profile_count()

void scale_bbs_frequencies_profile_count ( basic_block * bbs,
int nbbs,
profile_count num,
profile_count den )
Multiply all frequencies of basic blocks in array BBS of length NBBS
by NUM/DEN, in profile_count arithmetic.  More accurate than previous
function but considerably slower.   

References count, ggc_alloc(), i, and profile_count::zero().

Referenced by duplicate_loop_body_to_header_edge(), back_jt_path_registry::duplicate_thread_path(), and gimple_duplicate_sese_tail().

◆ scale_strictly_dominated_blocks()

void scale_strictly_dominated_blocks ( basic_block bb,
profile_count num,
profile_count den )
Scales the frequencies of all basic blocks that are strictly
dominated by BB by NUM/DEN.   

References profile_count::apply_scale(), CDI_DOMINATORS, basic_block_def::count, first_dom_son(), ggc_alloc(), next_dom_son(), loop::num, worklist, and profile_count::zero().

Referenced by fold_loop_internal_call().

◆ set_bb_copy()

void set_bb_copy ( basic_block bb,
basic_block copy )
Set copy for basic block.  Do nothing when data structures are not
initialized so passes not needing this don't need to care.   

References bb_copy, copy_original_table_set(), and basic_block_def::index.

Referenced by duplicate_block().

◆ set_bb_original()

void set_bb_original ( basic_block bb,
basic_block original )
Set original for basic block.  Do nothing when data structures are not
initialized so passes not needing this don't need to care.   

References bb_original, copy_original_table_set(), ggc_alloc(), and basic_block_def::index.

Referenced by duplicate_block().

◆ set_edge_probability_and_rescale_others()

void set_edge_probability_and_rescale_others ( edge e,
profile_probability new_prob )

◆ set_loop_copy()

◆ unchecked_make_edge()

edge unchecked_make_edge ( basic_block src,
basic_block dst,
int flags )
Create an edge connecting SRC and DEST with flags FLAGS.  Return newly
created edge.  Use this only if you are sure that this edge can't
possibly already exist.   

References cfun, connect_dest(), connect_src(), execute_on_growing_pred(), basic_block_def::flags, ggc_alloc(), n_edges_for_fn, and profile_probability::uninitialized().

Referenced by cached_make_edge(), function_reader::create_edges(), duplicate_block(), force_nonfallthru_and_redirect(), and make_edge().

◆ unlink_block()

void unlink_block ( basic_block b)
Unlink block B from chain.   

References b, and NULL.

Referenced by expunge_block(), gimple_find_sub_bbs(), gimple_move_block_after(), and merge_blocks_move_predecessor_nojumps().

◆ update_bb_profile_for_threading()

void update_bb_profile_for_threading ( basic_block bb,
profile_count count,
edge taken_edge )
An edge originally destinating BB of COUNT has been proved to
leave the block by TAKEN_EDGE.  Update profile of BB such that edge E can be
redirected to destination of TAKEN_EDGE.

This function may leave the profile inconsistent in the case TAKEN_EDGE
frequency or count is believed to be lower than COUNT
respectively.   

References profile_count::apply_scale(), basic_block_def::count, count, profile_probability::dump(), dump_file, gcc_assert, ggc_alloc(), profile_count::guessed(), basic_block_def::index, profile_count::initialized_p(), profile_probability::invert(), profile_count::nonzero_p(), set_edge_probability_and_rescale_others(), and profile_count::zero().

Referenced by back_jt_path_registry::duplicate_thread_path(), try_forward_edges(), and update_profile_after_ch().

Variable Documentation

◆ bb_copy

◆ bb_original

◆ block_aux_obstack

struct obstack block_aux_obstack
static
Simple routines to easily allocate AUX fields of basic blocks.   

Referenced by alloc_aux_for_block(), alloc_aux_for_blocks(), and free_aux_for_blocks().

◆ edge_aux_obstack

struct obstack edge_aux_obstack
static

◆ first_block_aux_obj

void* first_block_aux_obj = 0
static

◆ first_edge_aux_obj

void* first_edge_aux_obj = 0
static

◆ loop_copy