GCC Middle and Back End API Reference
cfgrtl.c File Reference
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "hard-reg-set.h"
#include "basic-block.h"
#include "bb-reorder.h"
#include "regs.h"
#include "flags.h"
#include "function.h"
#include "except.h"
#include "rtl-error.h"
#include "tm_p.h"
#include "obstack.h"
#include "insn-attr.h"
#include "insn-config.h"
#include "expr.h"
#include "target.h"
#include "common/common-target.h"
#include "cfgloop.h"
#include "ggc.h"
#include "tree-pass.h"
#include "df.h"
#include "gt-cfgrtl.h"
Include dependency graph for cfgrtl.c:

Functions

static rtx skip_insns_after_block (basic_block)
static void record_effective_endpoints (void)
static rtx label_for_bb (basic_block)
static void fixup_reorder_chain (void)
void verify_insn_chain (void)
static void fixup_fallthru_exit_predecessor (void)
static int can_delete_note_p (const_rtx)
static int can_delete_label_p (const_rtx)
static basic_block rtl_split_edge (edge)
static bool rtl_move_block_after (basic_block, basic_block)
static int rtl_verify_flow_info (void)
static basic_block cfg_layout_split_block (basic_block, void *)
static edge cfg_layout_redirect_edge_and_branch (edge, basic_block)
static basic_block cfg_layout_redirect_edge_and_branch_force (edge, basic_block)
static void cfg_layout_delete_block (basic_block)
static void rtl_delete_block (basic_block)
static basic_block rtl_redirect_edge_and_branch_force (edge, basic_block)
static edge rtl_redirect_edge_and_branch (edge, basic_block)
static basic_block rtl_split_block (basic_block, void *)
static void rtl_dump_bb (FILE *, basic_block, int, int)
static int rtl_verify_flow_info_1 (void)
static void rtl_make_forwarder_block (edge)
static int can_delete_note_p ()
static int can_delete_label_p ()
void delete_insn ()
void delete_insn_and_edges ()
void delete_insn_chain ()
basic_block create_basic_block_structure ()
static basic_block rtl_create_basic_block ()
static basic_block cfg_layout_create_basic_block ()
static void rtl_delete_block ()
void compute_bb_for_insn ()
unsigned int free_bb_for_insn ()
static unsigned int rest_of_pass_free_cfg ()
rtl_opt_passmake_pass_free_cfg ()
rtx entry_of_function ()
void emit_insn_at_entry ()
static void update_bb_for_insn_chain ()
void update_bb_for_insn ()
static bool flow_active_insn_p ()
bool contains_no_active_insn_p ()
bool forwarder_block_p ()
bool can_fallthru ()
static bool could_fall_through ()
rtx bb_note ()
static rtx first_insn_after_basic_block_note ()
static basic_block rtl_split_block ()
static bool unique_locus_on_edge_between_p ()
static void emit_nop_for_unique_locus_between ()
static void rtl_merge_blocks ()
static bool rtl_can_merge_blocks ()
rtx block_label ()
edge try_redirect_by_replacing_jump ()
static bool patch_jump_insn ()
static edge redirect_branch_edge ()
static void fixup_partition_crossing ()
static void fixup_new_cold_bb ()
static edge rtl_redirect_edge_and_branch ()
void emit_barrier_after_bb ()
basic_block force_nonfallthru_and_redirect ()
static basic_block rtl_force_nonfallthru ()
static basic_block rtl_redirect_edge_and_branch_force ()
static void rtl_tidy_fallthru_edge ()
static basic_block last_bb_in_partition ()
static basic_block rtl_split_edge ()
void insert_insn_on_edge ()
void commit_one_edge_insertion ()
void commit_edge_insertions ()
static void rtl_dump_bb ()
void print_rtl_with_bb ()
void update_br_prob_note ()
rtx get_last_bb_insn ()
static vec< basic_blockfind_partition_fixes ()
void fixup_partitions ()
static int verify_hot_cold_block_grouping ()
static int rtl_verify_edges ()
static int rtl_verify_bb_insns ()
static int rtl_verify_bb_pointers ()
static int rtl_verify_bb_insn_chain ()
static int rtl_verify_fallthru ()
static int rtl_verify_bb_layout ()
bool purge_dead_edges ()
bool purge_all_dead_edges ()
bool fixup_abnormal_edges ()
rtx unlink_insn_chain ()
static rtx skip_insns_after_block ()
static rtx label_for_bb ()
static unsigned int into_cfg_layout_mode ()
static unsigned int outof_cfg_layout_mode ()
rtl_opt_passmake_pass_into_cfg_layout_mode ()
rtl_opt_passmake_pass_outof_cfg_layout_mode ()
void relink_block_chain ()
static void force_one_exit_fallthru ()
static bool cfg_layout_can_duplicate_bb_p ()
rtx duplicate_insn_chain ()
static basic_block cfg_layout_duplicate_bb ()
void cfg_layout_initialize ()
void break_superblocks ()
void cfg_layout_finalize ()
static basic_block cfg_layout_split_block ()
static edge cfg_layout_redirect_edge_and_branch ()
static basic_block cfg_layout_redirect_edge_and_branch_force ()
static void cfg_layout_delete_block ()
static bool cfg_layout_can_merge_blocks_p ()
static void cfg_layout_merge_blocks ()
static basic_block cfg_layout_split_edge ()
static void rtl_make_forwarder_block ()
static bool rtl_block_empty_p ()
static basic_block rtl_split_block_before_cond_jump ()
static bool rtl_block_ends_with_call_p ()
static bool rtl_block_ends_with_condjump_p ()
static bool need_fake_edge_p ()
static int rtl_flow_call_edges_add ()
static void rtl_lv_add_condition_to_bb (basic_block first_head, basic_block second_head, basic_block cond_bb, void *comp_rtx)
static void rtl_extract_cond_bb_edges (basic_block b, edge *branch_edge, edge *fallthru_edge)
void init_rtl_bb_info ()
static bool rtl_can_remove_branch_p ()
static basic_block rtl_duplicate_bb ()
static void rtl_account_profile_record (basic_block bb, int after_pass, struct profile_record *record)

Variables

static rtx cfg_layout_function_footer
static rtx cfg_layout_function_header
struct cfg_hooks rtl_cfg_hooks
struct cfg_hooks cfg_layout_rtl_cfg_hooks

Function Documentation

rtx bb_note ( )

Return the NOTE_INSN_BASIC_BLOCK of BB.

References BB_END, DEBUG_INSN_P, NEXT_INSN, and PREV_INSN.

rtx block_label ( )

Return the label in the head of basic block BLOCK. Create one if it doesn't exist.

References BARRIER_P, BB_END, BB_FOOTER, delete_insn_chain(), LABEL_P, NEXT_INSN, and PREV_INSN.

void break_superblocks ( void  )

Splits superblocks.

static int can_delete_label_p ( const_rtx  )
static
static int can_delete_label_p ( )
static

True if a given label can be deleted.

User declared labels must be preserved.

static int can_delete_note_p ( const_rtx  )
static

Referenced by delete_insn_and_edges().

static int can_delete_note_p ( )
static

Return true if NOTE is not one of the ones that must be kept paired, so that we may simply delete it.

bool can_fallthru ( )

Return nonzero if we can reach target from src by falling through. FIXME: Make this a cfg hook.

??? Later we may add code to move jump tables offline.

References BB_HEAD, gcc_assert, LABEL_P, NEXT_INSN, and NOTE_INSN_BASIC_BLOCK_P.

static bool cfg_layout_can_duplicate_bb_p ( )
static

Return true in case it is possible to duplicate the basic block BB.

Do not attempt to duplicate tablejumps, as we need to unshare the dispatch table. This is difficult to do, as the instructions computing jump destination may be hoisted outside the basic block.

 Do not duplicate blocks containing insns that can't be copied.   
static bool cfg_layout_can_merge_blocks_p ( )
static

Return true when blocks A and B can be safely merged.

 If we are partitioning hot/cold basic blocks, we don't want to
 mess up unconditional or indirect jumps that cross between hot
 and cold sections.

 Basic block partitioning may result in some jumps that appear to
 be optimizable (or blocks that appear to be mergeable), but which really
 must be left untouched (they are required to make it safely across
 partition boundaries).  See  the comments at the top of
 bb-reorder.c:partition_hot_cold_basic_blocks for complete details.   
 Protect the loop latches.   
 If we would end up moving B's instructions, make sure it doesn't fall
 through into the exit block, since we cannot recover from a fallthrough
 edge into the exit block occurring in the middle of a function.   
 There must be exactly one edge in between the blocks.   
         Must be simple edge.   
         If the jump insn has side effects, we can't kill the edge.
         When not optimizing, try_redirect_by_replacing_jump will
         not allow us to redirect an edge by replacing a table jump.   

References BB_END, BB_HEAD, commit_edge_insertions(), const0_rtx, EXIT_BLOCK_PTR, find_edge(), gen_use(), insert_insn_on_edge(), keep_with_call_p(), need_fake_edge_p(), and PREV_INSN.

static basic_block cfg_layout_create_basic_block ( )
static
static void cfg_layout_delete_block ( basic_block  )
static
static void cfg_layout_delete_block ( )
static

Same as delete_basic_block but update cfg_layout structures.

static basic_block cfg_layout_duplicate_bb ( )
static

Create a duplicate of the basic block BB.

void cfg_layout_finalize ( void  )

Finalize the changes: reorder insn list according to the sequence specified by aux pointers, enter compensation code, rebuild scope forest.

void cfg_layout_initialize ( )

Main entry point to this module - initialize the datastructures for CFG layout changes. It keeps LOOPS up-to-date if not null.

FLAGS is a set of additional flags to pass to cleanup_cfg().

Make sure that the targets of non local gotos are marked.

References edge_def::dest, EXIT_BLOCK_PTR, find_fallthru_edge(), and basic_block_def::succs.

static void cfg_layout_merge_blocks ( )
static

Merge block A and B. The blocks must be mergeable.

 If there was a CODE_LABEL beginning B, delete it.   
 We should have fallthru edge in a, or we can do dummy redirection to get
 it cleaned up.   
 When not optimizing CFG and the edge is the only place in RTL which holds
 some unique locus, emit a nop with that locus in between.   
 Move things from b->footer after a->footer.   
 Move things from b->header before a->footer.
 Note that this may include dead tablejump data, but we don't clean
 those up until we go out of cfglayout mode.   
 In the case basic blocks are not adjacent, move them around.   
 Otherwise just re-associate the instructions.   
 emit_insn_after_noloc doesn't call df_insn_change_bb.
 We need to explicitly call.  
 Skip possible DELETED_LABEL insn.   
 If B was a forwarder block, propagate the locus on the edge.   
static edge cfg_layout_redirect_edge_and_branch ( edge  ,
basic_block   
)
static
static edge cfg_layout_redirect_edge_and_branch ( )
static

Redirect Edge to DEST.

 Redirect_edge_and_branch may decide to turn branch into fallthru edge
 in the case the basic block appears to be in sequence.  Avoid this
 transformation.   
     Redirect any branch edges unified with the fallthru one.   
     In case we are redirecting fallthru edge to the branch edge
     of conditional jump, remove it.   
         Find the edge that is different from E.   
 We don't want simplejumps in the insn stream during cfglayout.   

References BB_END, BB_HEAD, emit_insn_after_noloc(), and unlink_insn_chain().

static basic_block cfg_layout_redirect_edge_and_branch_force ( edge  ,
basic_block   
)
static
static basic_block cfg_layout_redirect_edge_and_branch_force ( )
static

Simple wrapper as we always can redirect fallthru edges.

References any_condjump_p(), last, and NONDEBUG_INSN_P.

static basic_block cfg_layout_split_block ( basic_block  ,
void *   
)
static
static basic_block cfg_layout_split_block ( )
static

Same as split_block but update cfg_layout structures.

References BB_FOOTER, BB_HEADER, last, NEXT_INSN, and PREV_INSN.

static basic_block cfg_layout_split_edge ( )
static

Split edge E.

void commit_edge_insertions ( void  )

Update the CFG for all queued instructions.

Optimization passes that invoke this routine can cause hot blocks previously reached by both hot and cold blocks to become dominated only by cold blocks. This will cause the verification below to fail, and lead to now cold code in the hot section. In some cases this may only be visible after newly unreachable blocks are deleted, which will be done by fixup_partitions.

Referenced by cfg_layout_can_merge_blocks_p().

void commit_one_edge_insertion ( )

Update the CFG for the instructions queued on edge E.

 Pull the insns off the edge now since the edge might go away.   
 Figure out where to put these insns.  If the destination has
 one predecessor, insert there.  Except for the exit block.   
     Get the location correct wrt a code label, and "nice" wrt
     a basic block note, and before everything else.   
 If the source has one successor and the edge is not abnormal,
 insert there.  Except for the entry block.
 Don't do this if the predecessor ends in a jump other than
 unconditional simple jump.  E.g. for asm goto that points all
 its labels at the fallthru basic block, we can't insert instructions
 before the asm goto, as the asm goto can have various of side effects,
 and can't emit instructions after the asm goto, as it must end
 the basic block.   
     It is possible to have a non-simple jump here.  Consider a target
     where some forms of unconditional jumps clobber a register.  This
     happens on the fr30 for example.

     We know this block has a single successor, so we can just emit
     the queued insns before the jump.   
         We'd better be fallthru, or we've lost track of what's what.   
 Otherwise we must split the edge.   
     If E crossed a partition boundary, we needed to make bb end in
     a region-crossing jump, even though it was originally fallthru.   
 Now that we've found the spot, do the insertion.   
     ??? Remove all outgoing edges from BB and add one for EXIT.
     This is not currently a problem because this only happens
     for the (single) epilogue, which already has a fallthru edge
     to EXIT.   

References df_dump_top().

void compute_bb_for_insn ( void  )

Records the basic block struct in BLOCK_FOR_INSN for every insn.

References crtl, df_analyze(), df_note_add_problem(), free_bb_for_insn(), and insert_section_boundary_note().

bool contains_no_active_insn_p ( )

Return true if the block has no effect and only forwards control flow to its single destination.

References active_insn_p(), BB_END, BB_HEAD, edge_def::dest, EXIT_BLOCK_PTR, edge_def::flags, FOR_EACH_EDGE, basic_block_def::next_bb, and basic_block_def::succs.

static bool could_fall_through ( )
static

Return nonzero if we could reach target from src by falling through, if the target was made adjacent. If we already have a fall-through edge to the exit block, we can't do that.

Referenced by make_pass_into_cfg_layout_mode().

basic_block create_basic_block_structure ( )

Create a new basic block consisting of the instructions between HEAD and END inclusive. This function is designed to allow fast BB construction - reuses the note and basic block struct in BB_NOTE, if any and do not grow BASIC_BLOCK chain and should be used directly only by CFG construction code. END can be NULL in to create new empty basic block before HEAD. Both END and HEAD can be NULL to create basic block at the end of INSN chain. AFTER is the basic block we should be put after.

     If we found an existing note, thread it back onto the chain.   
     Otherwise we must create a note and a basic block structure.   
 Always include the bb note in the block.   
 Tag the block so that we know it has been used when considering
 other basic block notes.   
void delete_insn ( )

Delete INSN by patching it out.

     Some labels can't be directly removed from the INSN chain, as they
     might be references via variables, constant pool etc.
     Convert them to the special NOTE_INSN_DELETED_LABEL note.   
         If the note following the label starts a basic block, and the
         label is a member of the same basic block, interchange the two.   
     If this insn has already been deleted, something is very wrong.   
 If deleting a jump, decrement the use count of the label.  Deleting
 the label itself should happen in the normal course of block merging.   
     If there are more targets, remove them too.   
 Also if deleting any insn that references a label as an operand.   
         When deleting code in bulk (e.g. removing many unreachable
         blocks) we can delete a label that's a target of the vector
         before deleting the vector itself.   

References BB_END, BB_HEAD, bb_note(), BLOCK_FOR_INSN, LABEL_NAME, NEXT_INSN, NOTE_DELETED_LABEL_NAME, NOTE_INSN_BASIC_BLOCK_P, NOTE_KIND, NULL, NULL_RTX, PUT_CODE, and reorder_insns_nobb().

Referenced by cond_exec_find_if_block(), count_reg_usage(), delete_insn_and_edges(), dse_step3(), lra_final_code_change(), maybe_fix_stack_asms(), merge_blocks_move_predecessor_nojumps(), prologue_epilogue_contains(), and reload_combine_recognize_const_pattern().

void delete_insn_and_edges ( )

Like delete_insn but also purge dead edges from BB.

References can_delete_note_p(), delete_insn(), NOTE_P, and PREV_INSN.

void delete_insn_chain ( )

Unlink a chain of insns between START and FINISH, leaving notes that must be paired. If CLEAR_BB is true, we set bb field for insns that cannot be removed to NULL.

Unchain the insns one by one. It would be quicker to delete all of these with a single unchaining, rather than one at a time, but we need to keep the NOTE's.

Referenced by block_label().

rtx duplicate_insn_chain ( )
 Avoid updating of boundaries of previous basic block.  The
 note will get removed from insn stream in fixup.   
 Create copy at the end of INSN chain.  The chain will
 be reordered later.   
         Don't duplicate label debug insns.   
         FALLTHRU  
         Avoid copying of dispatch tables.  We never duplicate
         tablejumps, so this can hit only in case the table got
         moved far from original jump.
         Avoid copying following barrier as well if any
         (and debug insns in between).   
             In case prologue is empty and function contain label
             in first BB, we may want to copy the block.   
             No problem to strip these.   
             There is always just single entry to function.   
             We should only switch text sections once.   
             All other notes should have already been eliminated.   

Referenced by record_insns().

void emit_barrier_after_bb ( )

Emit a barrier after BB, into the footer if we are in CFGLAYOUT mode.

References ASM_OPERANDS_LABEL, BB_HEAD, block_label(), edge_def::dest, LABEL_NUSES, and XEXP.

void emit_insn_at_entry ( )

Emit INSN at the entry point of the function, ensuring that it is only executed once per function.

References active_insn_p(), GET_CODE, and PATTERN.

static void emit_nop_for_unique_locus_between ( )
static

If the single edge between blocks A and B is the only place in RTL which holds some unique locus, emit a nop with that locus between the blocks.

rtx entry_of_function ( void  )

Return RTX to emit after when we want to emit code on the entry of function.

static vec<basic_block> find_partition_fixes ( )
static

Sanity check partition hotness to ensure that basic blocks in   the cold partition don't dominate basic blocks in the hot partition. If FLAG_ONLY is true, report violations as errors. Otherwise re-mark the dominated blocks as cold, since this is run after cfg optimizations that may make hot blocks previously reached by both hot and cold blocks now only reachable along cold paths.

 Callers check this.   
     Any blocks dominated by a block in the cold section
     must also be cold.   
         If son is not yet cold, then mark it cold here and
         enqueue it for further processing.   

References BB_END, error(), find_reg_note(), edge_def::flags, basic_block_def::index, JUMP_P, NULL_RTX, and edge_def::src.

static rtx first_insn_after_basic_block_note ( )
static

Return the INSN immediately following the NOTE_INSN_BASIC_BLOCK note associated with the BLOCK.

Get the first instruction in the block.

bool fixup_abnormal_edges ( void  )

This is used by a few passes that emit some instructions after abnormal calls, moving the basic block's end, while they in fact do want to emit them on the fallthru edge. Look for abnormal call edges, find backward the call in the block and insert the instructions on the edge instead.

Similarly, handle instructions throwing exceptions internally.

Return true when instructions have been found and inserted on edges.

     Look for cases we are interested in - calls or instructions causing
     exceptions.   
         Get past the new insns generated.  Allow notes, as the insns
         may be already deleted.   
                     Sometimes there's still the return value USE.
                     If it's placed after a trapping call (i.e. that
                     call is the last insn anyway), we have no fallthru
                     edge.  Simply delete this use and don't try to insert
                     on the non-existent edge.   
                         We're not deleting it, we're moving it.   
         It may be that we don't find any trapping insn.  In this
         case we discovered quite late that the insn that had been
         marked as can_throw_internal in fact couldn't trap at all.
         So we should in fact delete the EH edges out of the block.   
static void fixup_fallthru_exit_predecessor ( )
static

If we have assembler epilogues, the block falling through to exit must be the last one in the reordered chain when we reach final. Ensure that this condition is met.

This transformation is not valid before reload, because we might separate a call from the instruction that copies the return value.

     If the very first block is the one with the fall-through exit
     edge, we have to split that block.   
static void fixup_new_cold_bb ( )
static

Called when block BB has been reassigned to the cold partition, because it is now dominated by another cold block, to ensure that the region crossing attributes are updated.

 This is called when a hot bb is found to now be dominated
 by a cold bb and therefore needs to become cold. Therefore,
 its preds will no longer be region crossing. Any non-dominating
 preds that were previously hot would also have become cold
 in the caller for the same region. Any preds that were previously
 region-crossing will be adjusted in fixup_partition_crossing.   
 Possibly need to make bb's successor edges region crossing,
 or remove stale region crossing.   
     We can't have fall-through edges across partition boundaries.
     Note that force_nonfallthru will do any necessary partition
     boundary fixup by calling fixup_partition_crossing itself.   

References BB_END, block_label(), edge_def::count, find_reg_note(), gcc_assert, NULL_RTX, edge_def::probability, redirect_jump(), REG_BR_PROB_BASE, edge_def::src, unchecked_make_edge(), and XINT.

static void fixup_partition_crossing ( )
static

Called when edge E has been redirected to a new destination, in order to update the region crossing flag on the edge and jump.

If we redirected an existing edge, it may already be marked crossing, even though the new src is missing a reg crossing note. But make sure reg crossing note doesn't already exist before inserting.

     Remove the section crossing note from jump at end of
     src if it exists, and if no other successors are
     still crossing.   

References df_set_bb_dirty().

void fixup_partitions ( void  )

Perform cleanup on the hot/cold bb partitioning after optimization passes that modify the cfg.

 Delete any blocks that became unreachable and weren't
 already cleaned up, for example during edge forwarding
 and convert_jumps_to_returns. This will expose more
 opportunities for fixing the partition boundaries here.
 Also, the calculation of the dominance graph during verification
 will assert if there are unreachable nodes.   
 If there are partitions, do a sanity check on them: A basic block in

  a cold partition cannot dominate a basic block in a hot partition. Fixup any that now violate this requirement, as a result of edge forwarding and unreachable block deletion.  

 Do the partition fixup after all necessary blocks have been converted to
 cold, so that we only update the region crossings the minimum number of
 places, which can require forcing edges to be non fallthru.   

References error(), get_insns(), basic_block_def::index, print_rtl_with_bb(), and TDF_RTL.

static void fixup_reorder_chain ( )
static

Given a reorder chain, rearrange the code to match.

 First do the bulk reordering &ndash; rechain the blocks without regard to
 the needed changes to jumps and labels.   
 Now add jumps and labels as needed to match the blocks new
 outgoing edges.   
     Find the old fallthru edge, and another non-EH edge for
     a taken jump.   
             This might happen if the conditional jump has side
             effects and could therefore not be optimized away.
             Make the basic block to end with a barrier in order
             to prevent rtl_verify_flow_info from complaining.   
             If the old fallthru is still next, nothing to do.   
             The degenerated case of conditional jump jumping to the next
             instruction can happen for jumps with side effects.  We need
             to construct a forwarder block and this will be done just
             fine by force_nonfallthru below.   
             There is another special case: if *neither* block is next,
             such as happens at the very end of a function, then we'll
             need to add a new unconditional jump.  Choose the taken
             edge based on known or assumed probability.   
             If the "jumping" edge is a crossing edge, and the fall
             through edge is non-crossing, leave things as they are.   
             Otherwise we can try to invert the jump.  This will
             basically never fail, however, keep up the pretense.   
             If the old fallthru is still next or if
             asm goto doesn't have a fallthru (e.g. when followed by
             __builtin_unreachable ()), nothing to do.   
             Otherwise we'll have to use the fallthru fixup below.   
             Otherwise we have some return, switch or computed
             jump.  In the 99% case, there should not have been a
             fallthru edge.   
         No fallthru implies a noreturn function with EH edges, or
         something similarly bizarre.  In any case, we don't need to
         do anything.   
         If the fallthru block is still next, nothing to do.   
         A fallthru to exit block.   
     We got here if we need to add a new jump insn. 
     Note force_nonfallthru can delete E_FALL and thus we have to
     save E_FALL->src prior to the call to force_nonfallthru.   
         Don't process this new block.   
 Annoying special case - jump around dead jumptables left in the code.   
 Ensure goto_locus from edges has some instructions with that locus
 in RTL.   
                 Non-fallthru edges to the exit block cannot be split.   
             If there are other incoming edges to the destination block
             with the same goto locus, redirect them to the new block as
             well, this can prevent other such blocks from being created
             in subsequent iterations of the loop.   

References BB_END, edge_def::goto_locus, INSN_LOCATION, and edge_def::src.

static bool flow_active_insn_p ( )
static

Like active_insn_p, except keep the return value clobber around even after reload.

A clobber of the function return value exists for buggy programs that fail to return a value. Its effect is to keep the return value from being live across the entire function. If we allow it to be skipped, we introduce the possibility for register lifetime confusion.

basic_block force_nonfallthru_and_redirect ( )

Like force_nonfallthru below, but additionally performs redirection Used by redirect_edge_and_branch_force. JUMP_LABEL is used only when redirecting to the EXIT_BLOCK, it is either ret_rtx or simple_return_rtx, indicating which kind of returnjump to create. It should be NULL otherwise.

 In the case the last instruction is conditional jump to the next
 instruction, first redirect the jump itself and then continue
 by creating a basic block afterwards to redirect fallthru edge.   
         Update this to use GCOV_COMPUTE_SCALE.   
     Irritating special case - fallthru edge to the same block as abnormal
     edge.
     We can't redirect abnormal edge, but we still can split the fallthru
     one and create separate abnormal edge to original destination.
     This allows bb-reorder to make such edge non-fallthru.   
         We can't redirect the entry block.  Create an empty block
         at the start of the function which we use to add the new
         jump.   
         Change the existing edge's source to be the new block, and add
         a new edge from the entry block to the new block.   
 If e->src ends with asm goto, see if any of the ASM_OPERANDS_LABELs
 don't point to the target or fallthru label.   
     Create the new structures.   
     If the old block ended with a tablejump, skip its table
     by searching forward from there.  Otherwise start searching
     forward from the last instruction of the old block.   
     Make sure new block ends up in correct hot/cold section.   
     Wire edge in.   
     Redirect old edge.   
     If e->src was previously region crossing, it no longer is
     and the reg crossing note should be removed.   
     If asm goto has any label refs to target's label,
     add also edge from asm goto bb to target.   
 We might be in cfg layout mode, and if so, the following routine will
 insert the barrier correctly.   
static void force_one_exit_fallthru ( )
static

In case there are more than one fallthru predecessors of exit, force that there is only one.

Exit has several fallthru predecessors. Create a forwarder block for them.

 Fix up the chain of blocks &ndash; make FORWARDER immediately precede the
 exit block.   
bool forwarder_block_p ( )

Likewise, but protect loop latches, headers and preheaders. FIXME: Make this a cfg hook.

Protect loop latches, headers and preheaders.

unsigned int free_bb_for_insn ( void  )

Release the basic_block_for_insn array.

References OPTGROUP_NONE, RTL_PASS, and TV_NONE.

Referenced by compute_bb_for_insn().

rtx get_last_bb_insn ( )

Get the last insn associated with block BB (that includes barriers and tablejumps after BB).

Include any jump table following the basic block.

 Include any barriers that may follow the basic block.   

References any_condjump_p(), BB_END, BRANCH_EDGE, EDGE_COUNT, error(), find_reg_note(), edge_def::flags, FOR_EACH_EDGE, JUMP_P, NULL, NULL_RTX, PROFILE_ABSENT, profile_status, basic_block_def::succs, and XINT.

void init_rtl_bb_info ( )
void insert_insn_on_edge ( )

Queue instructions for insertion on an edge between two basic blocks. The new instructions and basic blocks (if any) will not appear in the CFG until commit_edge_insertions is called.

We cannot insert instructions on an abnormal critical edge. It will be easier to find the culprit if we die now.

References alloca, indent, and last.

static unsigned int into_cfg_layout_mode ( )
static
static rtx label_for_bb ( basic_block  )
static
static rtx label_for_bb ( )
static

Locate or create a label for a given basic block.

References basic_block_def::aux, BB_HEADER, cfg_layout_function_header, ENTRY_BLOCK_PTR, NEXT_INSN, NULL, and set_first_insn().

static basic_block last_bb_in_partition ( )
static

Locate the last bb in the same partition as START_BB.

Return bb before EXIT_BLOCK_PTR.

rtl_opt_pass* make_pass_free_cfg ( )
rtl_opt_pass* make_pass_outof_cfg_layout_mode ( )
static bool need_fake_edge_p ( )
static

Return true if we need to add fake edge to exit. Helper function for rtl_flow_call_edges_add.

Referenced by cfg_layout_can_merge_blocks_p().

static unsigned int outof_cfg_layout_mode ( )
static
static bool patch_jump_insn ( )
static

Subroutine of redirect_branch_edge that tries to patch the jump instruction INSN so that it reaches block NEW. Do this only when it originally reached block OLD. Return true if this worked or the original target wasn't OLD, return false if redirection doesn't work.

 Recognize a tablejump and adjust all matching cases.   
     Handle casesi dispatch insns.   
     ?? We may play the games with moving the named labels from
     one basic block to the other in case only one computed_jump is
     available.   
         A return instruction can't be redirected.   
         If the insn doesn't go where we think, we're confused.   
         If the substitution doesn't succeed, die.  This can happen
         if the back end emitted unrecognizable instructions or if
         target is exit block on some arches.   
void print_rtl_with_bb ( )

Like dump_function_to_file, but for RTL. Print out dataflow information for the start of each basic block. FLAGS are the TDF_* masks documented in dumpfile.h.

After freeing the CFG, we still have BLOCK_FOR_INSN set on most insns, but the CFG is not maintained so the basic block info is not reliable. Therefore it's omitted from the dumps.

References BB_PARTITION, BB_SET_PARTITION, error(), and basic_block_def::index.

Referenced by fixup_partitions().

bool purge_all_dead_edges ( void  )

Search all basic blocks for potentially dead edges and purge them. Return true if some edge has been eliminated.

Referenced by split_live_ranges_for_shrink_wrap().

bool purge_dead_edges ( )

Assume that the preceding pass has possibly eliminated jump instructions or converted the unconditional jumps. Eliminate the edges from CFG. Return true if any edges are eliminated.

 If this instruction cannot trap, remove REG_EH_REGION notes.   
 Cleanup abnormal edges caused by exceptions or non-local gotos.   
     There are three types of edges we need to handle correctly here: EH
     edges, abnormal call EH edges, and abnormal call non-EH edges.  The
     latter can appear when nonlocal gotos are used.   
     We do care only about conditional jumps and simplejumps.   
     Branch probability/prediction notes are defined only for
     condjumps.  We've possibly turned condjump into simplejump.   
         Avoid abnormal flags to leak from computed jumps turned
         into simplejumps.   
         See if this edge is one we should keep.   
           A conditional jump can fall through into the next
           block, so we should keep the edge.   
           If the destination block is the target of the jump,
           keep the edge.   
           If the destination block is the exit block, and this
           instruction is a return, then keep the edge.   
           Keep the edges that correspond to exceptions thrown by
           this instruction and rematerialize the EDGE_ABNORMAL
           flag we just cleared above.   
         We do not need this edge.   
     Redistribute probabilities.   
         Update these to use GCOV_COMPUTE_SCALE.   
     First, there should not be any EH or ABCALL edges resulting
     from non-local gotos and the like.  If there were, we shouldn't
     have created the sibcall in the first place.  Second, there
     should of course never have been a fallthru edge.   
 If we don't see a jump insn, we don't know exactly why the block would
 have been broken at this point.  Look for a simple, non-fallthru edge,
 as these are only created by conditional branches.  If we find such an
 edge we know that there used to be a jump here and can then safely
 remove all non-fallthru edges.   
 Remove all but the fake and fallthru edges.  The fake edge may be
 the only successor for this block in the case of noreturn
 calls.   
static void record_effective_endpoints ( )
static

Locate the effective beginning and end of the insn chain for each block, as defined by skip_insns_after_block above.

No basic blocks at all?

static edge redirect_branch_edge ( )
static

Redirect edge representing branch of (un)conditional jump or tablejump, NULL on failure

We can only redirect non-fallthru edges of jump insn.

   When expanding this BB might actually contain multiple
   jumps (i.e. not yet split by find_many_sub_basic_blocks).
   Redirect all of those that match our label.   
void relink_block_chain ( )

Link the basic blocks in the correct order, compacting the basic block queue while at it. If STAY_IN_CFGLAYOUT_MODE is false, this function also clears the basic block header and footer fields.

This function is usually called after a pass (e.g. tracer) finishes some transformations while in cfglayout mode. The required sequence of the basic blocks is in a linked list along the bb->aux field. This functions re-links the basic block prev_bb and next_bb pointers accordingly, and it compacts and renumbers the blocks.

FIXME: This currently works only for RTL, but the only RTL-specific bits are the STAY_IN_CFGLAYOUT_MODE bits. The tracer pass was moved to GIMPLE a long time ago, but it doesn't relink the basic block chain. It could do that (to give better initial RTL) if this function is made IR-agnostic (and moved to cfganal.c or cfg.c while at it).

 Maybe dump the re-ordered sequence.   
 Now reorder the blocks.   
 Then, clean up the aux fields.   
 Maybe reset the original copy tables, they are not valid anymore
 when we renumber the basic blocks in compact_blocks.  If we are
 are going out of cfglayout mode, don't re-allocate the tables.   
 Finally, put basic_block_info in the new order.   
static unsigned int rest_of_pass_free_cfg ( )
static
static void rtl_account_profile_record ( basic_block  bb,
int  after_pass,
struct profile_record record 
)
static

Do book-keeping of basic block BB for the profile consistency checker. If AFTER_PASS is 0, do pre-pass accounting, or if AFTER_PASS is 1 then do post-pass accounting. Store the counting in RECORD.

static bool rtl_block_empty_p ( )
static

Return true if BB contains only labels or non-executable instructions.

static bool rtl_block_ends_with_call_p ( )
static

Return 1 if BB ends with a call, possibly followed by some instructions that must stay with the call, 0 otherwise.

static bool rtl_block_ends_with_condjump_p ( )
static
static bool rtl_can_merge_blocks ( )
static

Return true when block A and B can be merged.

 If we are partitioning hot/cold basic blocks, we don't want to
 mess up unconditional or indirect jumps that cross between hot
 and cold sections.

 Basic block partitioning may result in some jumps that appear to
 be optimizable (or blocks that appear to be mergeable), but which really
 must be left untouched (they are required to make it safely across
 partition boundaries).  See  the comments at the top of
 bb-reorder.c:partition_hot_cold_basic_blocks for complete details.   
 Protect the loop latches.   
 There must be exactly one edge in between the blocks.   
         Must be simple edge.   
         If the jump insn has side effects,
         we can't kill the edge.   
static bool rtl_can_remove_branch_p ( )
static

Returns true if it is possible to remove edge E by redirecting it to the destination of the other edge from E->src.

The conditions are taken from try_redirect_by_replacing_jump.

static basic_block rtl_create_basic_block ( )
static

Create new basic block consisting of instructions in between HEAD and END and place it to the BB chain after block AFTER. END can be NULL to create a new empty basic block before HEAD. Both END and HEAD can be NULL to create basic block at the end of INSN chain.

Grow the basic block array if needed.

static void rtl_delete_block ( basic_block  )
static
static void rtl_delete_block ( )
static

Delete the insns in a (non-live) block. We physically delete every non-deleted-note insn, and update the flow graph appropriately.

Return nonzero if we deleted an exception handler. ??? Preserving all such notes strikes me as wrong. It would be nice to post-process the stream to remove empty blocks, loops, ranges, etc.

If the head of this block is a CODE_LABEL, then it might be the label for an exception handler which can't be reached. We need to remove the label from the exception_handler_label list.

 Selectively delete the entire chain.   

References BB_END, BB_HEAD, BLOCK_FOR_INSN, and NEXT_INSN.

static void rtl_dump_bb ( FILE *  ,
basic_block  ,
int  ,
int   
)
static
static void rtl_dump_bb ( )
static

Print out RTL-specific basic block information (live information at start and end with TDF_DETAILS). FLAGS are the TDF_* masks documented in dumpfile.h.

References next_nonnote_insn_bb().

static basic_block rtl_duplicate_bb ( )
static
static void rtl_extract_cond_bb_edges ( basic_block  b,
edge branch_edge,
edge fallthru_edge 
)
static

Given a block B with unconditional branch at its end, get the store the return the branch edge and the fall-thru edge in BRANCH_EDGE and FALLTHRU_EDGE respectively.

static int rtl_flow_call_edges_add ( )
static

Add fake edges to the function exit for any non constant and non noreturn calls, volatile inline assembly in the bitmap of blocks specified by BLOCKS or to the whole CFG if BLOCKS is zero. Return the number of blocks that were split.

The goal is to expose cases in which entering a basic block does not imply that all subsequent instructions must be executed.

 In the last basic block, before epilogue generation, there will be
 a fallthru edge to EXIT.  Special care is required if the last insn
 of the last basic block is a call because make_edge folds duplicate
 edges, which would result in the fallthru edge also being marked
 fake, which would result in the fallthru edge being removed by
 remove_fake_edges, which would result in an invalid CFG.

 Moreover, we can't elide the outgoing fake edge, since the block
 profiler needs to take this into account in order to solve the minimal
 spanning tree in the case that the call doesn't return.

 Handle this by adding a dummy instruction in a new last basic block.   
     Back up past insns that must be kept in the same block as a call.   
 Now add fake edges to the function exit for any non constant
 calls since there is no way that we can determine if they will
 return or not...   
             Don't split the block between a call and an insn that should
             remain in the same block as the call.   
             The handling above of the final block before the epilogue
             should be enough to verify that there is no edge to the exit
             block in CFG already.  Calling make_edge in such case would
             cause us to mark that edge as fake and remove it later.   
             Note that the following may create a new basic block
             and renumber the existing basic blocks.   
static basic_block rtl_force_nonfallthru ( )
static

Edge E is assumed to be fallthru edge. Emit needed jump instruction (and possibly create new basic block) to make edge non-fallthru. Return newly created BB or NULL if none.

References BB_COPY_PARTITION, BB_END, create_basic_block(), NEXT_INSN, and edge_def::src.

static void rtl_lv_add_condition_to_bb ( basic_block  first_head,
basic_block  second_head,
basic_block  cond_bb,
void *  comp_rtx 
)
static

Add COMP_RTX as a condition at end of COND_BB. FIRST_HEAD is the conditional branch target, SECOND_HEAD should be the fall-thru there is no need to handle this here the loop versioning code handles this. the reason for SECON_HEAD is that it is needed for condition in trees, and this should be of the same type since it is a hook.

Add the new cond , in the new head.

static void rtl_make_forwarder_block ( edge  )
static
static void rtl_make_forwarder_block ( )
static

Do postprocessing after making a forwarder block joined by edge FALLTHRU.

static void rtl_merge_blocks ( )
static

Blocks A and B are to be merged into a single block A. The insns are already contiguous.

 If there was a CODE_LABEL beginning B, delete it.   
     Detect basic blocks with nothing but a label.  This can happen
     in particular at the end of a function.   
 Delete the basic block note and handle blocks containing just that
 note.   
 If there was a jump out of A, delete it.   
 Delete everything marked above as well as crap that might be
 hanging out between the two blocks.   
 When not optimizing CFG and the edge is the only place in RTL which holds
 some unique locus, emit a nop with that locus in between.   
 Reassociate the insns of B with A.   
     Move any deleted labels and other notes between the end of A
     and the debug insns that make up B after the debug insns,
     bringing the debug insns into A while keeping the notes after
     the end of A.   
 If B was a forwarder block, propagate the locus on the edge.   
static bool rtl_move_block_after ( basic_block  bb,
basic_block  after 
)
static

Should move basic block BB after basic block AFTER. NIY.

References EDGE_CRITICAL_P, edge_def::flags, and gcc_assert.

static edge rtl_redirect_edge_and_branch ( edge  ,
basic_block   
)
static
static edge rtl_redirect_edge_and_branch ( )
static

Attempt to change code to redirect edge E to TARGET. Don't do that on expense of adding new instructions or reordering basic blocks.

Function can be also called with edge destination equivalent to the TARGET. Then it should try the simplifications and do nothing if none is possible.

Return edge representing the branch if transformation succeeded. Return NULL on failure. We still return NULL in case E already destinated TARGET and we didn't managed to simplify instruction stream.

static basic_block rtl_redirect_edge_and_branch_force ( edge  ,
basic_block   
)
static
static basic_block rtl_redirect_edge_and_branch_force ( )
static

Redirect edge even at the expense of creating new jump insn or basic block. Return new basic block if created, NULL otherwise. Conversion must be possible.

In case the edge redirection failed, try to force it to be non-fallthru and redirect newly created simplejump.

References BB_COPY_PARTITION, create_basic_block(), edge_def::dest, and basic_block_def::prev_bb.

static basic_block rtl_split_block ( basic_block  ,
void *   
)
static
static basic_block rtl_split_block ( )
static

Creates a new basic block just after basic block B by splitting everything after specified instruction I.

    If the block contains only debug insns, insn would have
    been NULL in a non-debug compilation, and then we'd end
    up emitting a DELETED note.  For -fcompare-debug
    stability, emit the note too.   
 We probably should check type of the insn so that we do not create
 inconsistent cfg.  It is checked in verify_flow_info anyway, so do not
 bother.   


 Create the new basic block.   
 Redirect the outgoing edges.   
 The new block starts off being dirty.   

References BB_END, BB_HEAD, EDGE_SUCC, INSN_HAS_LOCATION, INSN_LOCATION, LOCATION_LOCUS, NEXT_INSN, NONDEBUG_INSN_P, PREV_INSN, and UNKNOWN_LOCATION.

static basic_block rtl_split_block_before_cond_jump ( )
static

Split a basic block if it ends with a conditional branch and if the other part of the block is not empty.

Did not find everything.

static basic_block rtl_split_edge ( edge  )
static
static basic_block rtl_split_edge ( )
static

Split a (typically critical) edge. Return the new block. The edge must not be abnormal.

??? The code generally expects to be called on critical edges. The case of a block ending in an unconditional jump to a block with multiple predecessors is not handled optimally.

 Abnormal edges cannot be split.   
 We are going to place the new block in front of edge destination.
 Avoid existence of fallthru predecessors.   
 Create the basic block note.   
 If this is a fall through edge to the exit block, the blocks might be
 not adjacent, and the right place is after the source.   
         If this is post-bb reordering, and the edge crosses a partition
         boundary, the new block needs to be inserted in the bb chain
         at the end of the src partition (since we put the new bb into
         that partition, see below). Otherwise we may end up creating
         an extra partition crossing in the chain, which is illegal.
         It can't go after the src, because src may have a fall-through
         to a different block.   
             The instruction following the last bb in partition should
             be a barrier, since it cannot end in a fall-through.   
         Put the split bb into the src partition, to avoid creating
         a situation where a cold bb dominates a hot bb, in the case
         where src is cold and dest is hot. The src will dominate
         the new bb (whereas it might not have dominated dest).   
 Can't allow a region crossing edge to be fallthrough.   
 For non-fallthru edges, we must adjust the predecessor's
 jump instruction to target our new block.   
         For asm goto even splitting of fallthru edge might
         need insn patching, as other labels might point to the
         old label.   

References BB_HEAD, edge_def::dest, get_last_insn(), LABEL_P, NEXT_INSN, NOTE_INSN_BASIC_BLOCK_P, and PREV_INSN.

static void rtl_tidy_fallthru_edge ( )
static

The given edge should potentially be a fallthru edge. If that is in fact true, delete the jump and barriers that are in the way.

 ??? In a late-running flow pass, other folks may have deleted basic
 blocks by nopping out blocks, leaving multiple BARRIERs between here
 and the target label. They ought to be chastised and fixed.

 We can also wind up with a sequence of undeletable labels between
 one block and the next.

 So search through a sequence of barriers, labels, and notes for
 the head of block C and assert that we really do fall through.   
 Remove what will soon cease being the jump insn from the source block.
 If block B consisted only of this single jump, turn it into a deleted
 note.   
 Selectively unlink the sequence.   
static int rtl_verify_bb_insn_chain ( )
static

Walk the instruction chain and verify that bb head/end pointers are correct, and that instructions are in exactly one bb and have correct block pointers.

         Verify the end of the basic block is in the INSN chain.   
           And that the code outside of basic blocks has NULL bb field.   
     Work backwards from the end to the head of the basic block
     to verify the head is in the RTL chain.   
         While walking over the insn chain, verify insns appear
         in only one basic block.   
     Check that the code before the first basic block has NULL
     bb field.   
static int rtl_verify_bb_insns ( )
static

Checks on the instructions within blocks. Currently checks that each block starts with a basic block note, and that basic block notes and control flow jumps are not found in the middle of the block.

     Now check the header of basic
     block.  It ought to contain optional CODE_LABEL followed
     by NOTE_BASIC_BLOCK.   
       Do checks for empty blocks here.   
 Clean up.   
static int rtl_verify_bb_layout ( )
static

Verify that blocks are laid out in consecutive order. While walking the instructions, verify that all expected instructions are inside the basic blocks, and that all returns are followed by barriers.

An ADDR_VEC is placed outside any basic block.

             But in any case, non-deletable labels can appear anywhere.   

References ei_next().

static int rtl_verify_bb_pointers ( )
static

Verify that block pointers for instructions in basic blocks, headers and footers are set appropriately.

Check the general integrity of the basic blocks.

 Clean up.   

References BARRIER_P, error(), basic_block_def::index, and NOTE_INSN_BASIC_BLOCK_P.

static int rtl_verify_edges ( )
static

Perform several checks on the edges out of each block, such as the consistency of the branch probabilities, the correctness of hot/cold partition crossing edges, and the number of expected successor edges. Also verify that the dominance relationship between hot/cold blocks is sane.

If there are partitions, do a sanity check on them: A basic block in   a cold partition cannot dominate a basic block in a hot partition.  

 Clean up.   

References BB_END, BB_HEAD, control_flow_insn_p(), error(), fatal_insn, basic_block_def::index, INSN_UID, LABEL_P, NEXT_INSN, NOTE_BASIC_BLOCK, and NOTE_INSN_BASIC_BLOCK_P.

static int rtl_verify_fallthru ( )
static

Verify that fallthru edges point to adjacent blocks in layout order and that barriers exist after non-fallthru blocks.

Ensure existence of barrier in BB with no fallthru edges.

static int rtl_verify_flow_info ( )
static

Verify the CFG and RTL consistency common for both underlying RTL and cfglayout RTL, plus consistency checks specific to linearized RTL mode.

Currently it does following checks:

  • all checks of rtl_verify_flow_info_1
  • test head/end pointers
  • check that blocks are laid out in consecutive order
  • check that all insns are in the basic blocks (except the switch handling code, barriers and notes)
  • check that all returns are followed by barriers
  • check that all fallthru edge points to the adjacent blocks
  • verify that there is a single hot/cold partition boundary after bbro
static int rtl_verify_flow_info_1 ( )
static

Verify the CFG and RTL consistency common for both underlying RTL and cfglayout RTL.

Currently it does following checks:

  • overlapping of basic blocks
  • insns with wrong BLOCK_FOR_INSN pointers
  • headers of basic blocks (the NOTE_INSN_BASIC_BLOCK note)
  • tails of basic blocks (ensure that boundary is necessary)
  • scans body of the basic block for JUMP_INSN, CODE_LABEL and NOTE_INSN_BASIC_BLOCK
  • verify that no fall_thru edge crosses hot/cold partition boundaries
  • verify that there are no pending RTL branch predictions
  • verify that hot blocks are not dominated by cold blocks

In future it can be extended check a lot of other stuff as well (reachability of basic blocks, life information, etc. etc.).

References fatal_insn, GET_CODE, JUMP_TABLE_DATA_P, and NEXT_INSN.

Referenced by rtl_block_ends_with_condjump_p().

static rtx skip_insns_after_block ( basic_block  )
static
static rtx skip_insns_after_block ( )
static

Skip over inter-block insns occurring after BB which are typically associated with BB (e.g., barriers). If there are any such insns, we return the last one. Otherwise, we return the end of BB.

It is possible to hit contradictory sequence. For instance:

jump_insn NOTE_INSN_BLOCK_BEG barrier

Where barrier belongs to jump_insn, but the note does not. This can be created by removing the basic block originally following NOTE_INSN_BLOCK_BEG. In such case reorder the notes.

edge try_redirect_by_replacing_jump ( )

Attempt to perform edge redirection by replacing possibly complex jump instruction by unconditional jump or removing jump completely. This can apply only if all edges now point to the same block. The parameters and return values are equivalent to redirect_edge_and_branch.

 If we are partitioning hot/cold basic blocks, we don't want to
 mess up unconditional or indirect jumps that cross between hot
 and cold sections.

 Basic block partitioning may result in some jumps that appear to
 be optimizable (or blocks that appear to be mergeable), but which really
 must be left untouched (they are required to make it safely across
 partition boundaries).  See  the comments at the top of
 bb-reorder.c:partition_hot_cold_basic_blocks for complete details.   
 We can replace or remove a complex jump only when we have exactly
 two edges.  Also, if we have exactly one outgoing edge, we can
 redirect that.   
     Verify that all targets will be TARGET.  Specifically, the
     edge that is not E must also go to TARGET.   
 Avoid removing branch with side effects.   
 In case we zap a conditional jump, we'll need to kill
 the cc0 setter too.   
 See if we can create the fallthru edge.   
     Selectively unlink whole insn chain.   
         Remove barriers but keep jumptables.   
 If this already is simplejump, redirect it.   
 Cannot do anything for target exit block.   
 Or replace possibly complicated jump insn by simple jump insn.   
     Recognize a tablejump that we are converting to a
     simple jump and remove its associated CODE_LABEL
     and ADDR_VEC or ADDR_DIFF_VEC.   
             Move the jump before barrier so that the notes
             which originally were or were created before jump table are
             inside the basic block.   
 Keep only one edge out and set proper flags.   
static bool unique_locus_on_edge_between_p ( )
static

Return true if the single edge between blocks A and B is the only place in RTL which holds some unique locus.

First scan block A backward.

 Then scan block B forward.   
rtx unlink_insn_chain ( )

Cut the insns from FIRST to LAST out of the insns stream.

Referenced by cfg_layout_redirect_edge_and_branch().

void update_bb_for_insn ( )

Update BLOCK_FOR_INSN of insns in BB to BB, and notify df of the change.

static void update_bb_for_insn_chain ( )
static

Update BLOCK_FOR_INSN of insns between BEGIN and END (or BARRIER if found) and notify df of the bb change. The insn chain range is inclusive (i.e. both BEGIN and END will be updated.

void update_br_prob_note ( )

Update the branch probability of BB if a REG_BR_PROB is present.

static int verify_hot_cold_block_grouping ( )
static

Verify, in the basic block chain, that there is at most one switch between hot/cold partitions. This condition will not be true until after reorder_basic_blocks is called.

Even after bb reordering is complete, we go into cfglayout mode again (in compgoto). Ensure we don't call this before going back into linearized RTL when any layout fixes would have been committed.

DEBUG_FUNCTION void verify_insn_chain ( )

Perform sanity checks on the insn chain.

  1. Check that next/prev pointers are consistent in both the forward and reverse direction.
  2. Count insns in chain, going both directions, and check if equal.
  3. Check that get_last_insn () returns the actual end of chain.

Variable Documentation

rtx cfg_layout_function_footer
static

Control flow graph manipulation code for GNU compiler. Copyright (C) 1987-2013 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 that are aware of the RTL intermediate language.

Available functionality:

  • Basic CFG/RTL manipulation API documented in cfghooks.h
  • CFG-aware instruction chain manipulation delete_insn, delete_insn_chain
  • Edge splitting and committing to edges insert_insn_on_edge, commit_edge_insertions
  • CFG updating after insn simplification purge_dead_edges, purge_all_dead_edges
  • CFG fixing after coarse manipulation fixup_abnormal_edges

Functions not supposed for generic use:

  • Infrastructure to determine quickly basic block for insn compute_bb_for_insn, update_bb_for_insn, set_block_for_insn,
  • Edge redirection with updating and optimizing of insn chain block_label, tidy_fallthru_edge, force_nonfallthru Holds the interesting leading and trailing notes for the function. Only applicable if the CFG is in cfglayout mode.
rtx cfg_layout_function_header
static

Referenced by label_for_bb().

struct cfg_hooks cfg_layout_rtl_cfg_hooks

Implementation of CFG manipulation for cfg layout RTL, where basic block connected via fallthru edges does not have to be adjacent. This representation will hopefully become the default one in future version of the compiler.

struct cfg_hooks rtl_cfg_hooks

Implementation of CFG manipulation for linearized RTL.

Referenced by set_cfg_hooks().