GCC Middle and Back End API Reference
df-problems.c File Reference
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "rtl.h"
#include "tm_p.h"
#include "insn-config.h"
#include "recog.h"
#include "function.h"
#include "regs.h"
#include "alloc-pool.h"
#include "flags.h"
#include "hard-reg-set.h"
#include "basic-block.h"
#include "sbitmap.h"
#include "bitmap.h"
#include "target.h"
#include "timevar.h"
#include "df.h"
#include "except.h"
#include "dce.h"
#include "valtrack.h"
#include "dumpfile.h"
Include dependency graph for df-problems.c:

Data Structures

struct  df_rd_problem_data
struct  df_lr_problem_data
struct  df_live_problem_data
struct  df_word_lr_problem_data
struct  df_md_problem_data

Macros

#define REG_DEAD_DEBUGGING   0
#define DF_SPARSE_THRESHOLD   32
#define df_chain_problem_p(FLAG)   (((enum df_chain_flags)df_chain->local_flags)&(FLAG))
#define MEMREF_NORMAL   1
#define MEMREF_VOLATILE   2

Functions

void df_chain_dump ()
void df_print_bb_index ()
static void df_rd_free_bb_info (basic_block bb, void *vbb_info)
static void df_rd_alloc ()
void df_rd_simulate_artificial_defs_at_top ()
void df_rd_simulate_one_insn (basic_block bb, rtx insn, bitmap local_rd)
static void df_rd_bb_local_compute_process_def (struct df_rd_bb_info *bb_info, df_ref *def_rec, int top_flag)
static void df_rd_bb_local_compute ()
static void df_rd_local_compute ()
static void df_rd_init_solution ()
static bool df_rd_confluence_n ()
static bool df_rd_transfer_function ()
static void df_rd_free ()
static void df_rd_start_dump ()
static void df_rd_dump_defs_set ()
static void df_rd_top_dump ()
static void df_rd_bottom_dump ()
void df_rd_add_problem ()
static void df_lr_free_bb_info (basic_block bb, void *vbb_info)
static void df_lr_alloc ()
static void df_lr_reset ()
static void df_lr_bb_local_compute ()
static void df_lr_local_compute ()
static void df_lr_init ()
static void df_lr_confluence_0 ()
static bool df_lr_confluence_n ()
static bool df_lr_transfer_function ()
static void df_lr_finalize ()
static void df_lr_free ()
static void df_lr_top_dump ()
static void df_lr_bottom_dump ()
static void df_lr_verify_solution_start ()
static void df_lr_verify_solution_end ()
void df_lr_add_problem ()
void df_lr_verify_transfer_functions ()
static void df_live_free_bb_info (basic_block bb, void *vbb_info)
static void df_live_alloc ()
static void df_live_reset ()
static void df_live_bb_local_compute ()
static void df_live_local_compute ()
static void df_live_init ()
static bool df_live_confluence_n ()
static bool df_live_transfer_function ()
static void df_live_finalize ()
static void df_live_free ()
static void df_live_top_dump ()
static void df_live_bottom_dump ()
static void df_live_verify_solution_start ()
static void df_live_verify_solution_end ()
void df_live_add_problem ()
void df_live_set_all_dirty ()
void df_live_verify_transfer_functions ()
struct df_linkdf_chain_create ()
static void df_chain_unlink_1 ()
void df_chain_unlink ()
void df_chain_copy (df_ref to_ref, struct df_link *from_ref)
static void df_chain_remove_problem ()
static void df_chain_fully_remove_problem ()
static void df_chain_alloc ()
static void df_chain_reset ()
static void df_chain_create_bb_process_use (bitmap local_rd, df_ref *use_rec, int top_flag)
static void df_chain_create_bb ()
static void df_chain_finalize ()
static void df_chain_free ()
static void df_chain_bb_dump ()
static void df_chain_top_dump ()
static void df_chain_bottom_dump ()
static void df_chain_insn_top_dump ()
static void df_chain_insn_bottom_dump ()
void df_chain_add_problem ()
static void df_word_lr_free_bb_info (basic_block bb, void *vbb_info)
static void df_word_lr_alloc ()
static void df_word_lr_reset ()
bool df_word_lr_mark_ref ()
static void df_word_lr_bb_local_compute ()
static void df_word_lr_local_compute ()
static void df_word_lr_init ()
static bool df_word_lr_confluence_n ()
static bool df_word_lr_transfer_function ()
static void df_word_lr_free ()
static void df_word_lr_top_dump ()
static void df_word_lr_bottom_dump ()
void df_word_lr_add_problem ()
bool df_word_lr_simulate_defs ()
void df_word_lr_simulate_uses ()
static void df_note_alloc ()
static void df_print_note ()
static bool df_ignore_stack_reg ()
static void df_remove_dead_and_unused_notes ()
static void df_remove_dead_eq_notes ()
static void df_set_note ()
static bool df_whole_mw_reg_unused_p (struct df_mw_hardreg *mws, bitmap live, bitmap artificial_uses)
static void df_set_unused_notes_for_mw (rtx insn, struct df_mw_hardreg *mws, bitmap live, bitmap do_not_gen, bitmap artificial_uses, struct dead_debug_local *debug)
static bool df_whole_mw_reg_dead_p (struct df_mw_hardreg *mws, bitmap live, bitmap artificial_uses, bitmap do_not_gen)
static void df_set_dead_notes_for_mw (rtx insn, struct df_mw_hardreg *mws, bitmap live, bitmap do_not_gen, bitmap artificial_uses, bool *added_notes_p)
static void df_create_unused_note (rtx insn, df_ref def, bitmap live, bitmap artificial_uses, struct dead_debug_local *debug)
static void df_note_bb_compute (unsigned int bb_index, bitmap live, bitmap do_not_gen, bitmap artificial_uses)
static void df_note_compute ()
static void df_note_free ()
void df_note_add_problem ()
void df_simulate_find_defs ()
static void df_simulate_find_uses ()
void df_simulate_find_noclobber_defs ()
void df_simulate_defs ()
void df_simulate_uses ()
static void df_simulate_fixup_sets ()
void df_simulate_initialize_backwards ()
void df_simulate_one_insn_backwards ()
void df_simulate_finalize_backwards ()
void df_simulate_initialize_forwards ()
void df_simulate_one_insn_forwards ()
static int find_memory ()
static void find_memory_stores (rtx x, const_rtx pat, void *data)
void simulate_backwards_to_point ()
bool can_move_insns_across (rtx from, rtx to, rtx across_from, rtx across_to, basic_block merge_bb, regset merge_live, regset other_branch_live, rtx *pmove_upto)
static void df_md_free_bb_info (basic_block bb, void *vbb_info)
static void df_md_alloc ()
void df_md_simulate_artificial_defs_at_top ()
void df_md_simulate_one_insn (basic_block bb, rtx insn, bitmap local_md)
static void df_md_bb_local_compute_process_def (struct df_md_bb_info *bb_info, df_ref *def_rec, int top_flag)
static void df_md_bb_local_compute ()
static void df_md_local_compute ()
static void df_md_reset ()
static bool df_md_transfer_function ()
static void df_md_init ()
static void df_md_confluence_0 ()
static bool df_md_confluence_n ()
static void df_md_free ()
static void df_md_top_dump ()
static void df_md_bottom_dump ()
void df_md_add_problem ()

Variables

static bitmap_head seen_in_block
static bitmap_head seen_in_insn
static struct df_problem problem_RD
static struct df_problem problem_LR
static bitmap_head df_live_scratch
static struct df_problem problem_LIVE
static struct df_problem problem_CHAIN
static struct df_problem problem_WORD_LR
static struct df_problem problem_NOTE
static bitmap_head df_md_scratch
static struct df_problem problem_MD

Macro Definition Documentation

#define df_chain_problem_p (   FLAG)    (((enum df_chain_flags)df_chain->local_flags)&(FLAG))
#define DF_SPARSE_THRESHOLD   32
#define MEMREF_NORMAL   1

Used by the next two functions to encode information about the memory references we found.

Referenced by df_simulate_defs(), and df_simulate_uses().

#define MEMREF_VOLATILE   2
#define REG_DEAD_DEBUGGING   0

Standard problems for dataflow support routines. Copyright (C) 1999-2013 Free Software Foundation, Inc. Originally contributed by Michael P. Hayes (m.hay.nosp@m.es@e.nosp@m.lec.c.nosp@m.ante.nosp@m.rbury.nosp@m..ac..nosp@m.nz, mhaye.nosp@m.s@re.nosp@m.dhat..nosp@m.com) Major rewrite contributed by Danny Berlin (dberl.nosp@m.in@d.nosp@m.berli.nosp@m.n.or.nosp@m.g) and Kenneth Zadeck (zadec.nosp@m.k@na.nosp@m.tural.nosp@m.brid.nosp@m.ge.co.nosp@m.m).

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/. Note that turning REG_DEAD_DEBUGGING on will cause gcc.c-torture/unsorted/dump-noaddr.c to fail because it prints addresses in the dumps.

Referenced by df_create_unused_note(), df_ignore_stack_reg(), df_note_bb_compute(), df_remove_dead_eq_notes(), df_set_unused_notes_for_mw(), df_whole_mw_reg_dead_p(), and df_word_lr_top_dump().


Function Documentation

bool can_move_insns_across ( rtx  from,
rtx  to,
rtx  across_from,
rtx  across_to,
basic_block  merge_bb,
regset  merge_live,
regset  other_branch_live,
rtx pmove_upto 
)

Return true if it is safe to move a group of insns, described by the range FROM to TO, backwards across another group of insns, described by ACROSS_FROM to ACROSS_TO. It is assumed that there are no insns between ACROSS_TO and FROM, but they may be in different basic blocks; MERGE_BB is the block from which the insns will be moved. The caller must pass in a regset MERGE_LIVE which specifies the registers live after TO.

This function may be called in one of two cases: either we try to move identical instructions from all successor blocks into their predecessor, or we try to move from only one successor block. If OTHER_BRANCH_LIVE is nonnull, it indicates that we're dealing with the second case. It should contain a set of registers live at the end of ACROSS_TO which must not be clobbered by moving the insns. In that case, we're also more careful about moving memory references and trapping insns.

We return false if it is not safe to move the entire group, but it may still be possible to move a subgroup. PMOVE_UPTO, if nonnull, is set to point at the last moveable insn in such a case.

 Find real bounds, ignoring debug insns.   
           Pure functions can read from memory.  Const functions can
           read from arguments that the ABI has forced onto the stack.
           Neither sort of read can be volatile.   
         This is used just to find sets of the stack pointer.   
 Collect:
 MERGE_SET = set of registers set in MERGE_BB
 MERGE_USE = set of registers used in MERGE_BB and live at its top
 MERGE_LIVE = set of registers live at the point inside the MERGE
 range that we've reached during scanning
 TEST_SET = set of registers set between ACROSS_FROM and ACROSS_END.
 TEST_USE = set of registers used between ACROSS_FROM and ACROSS_END,
 and live before ACROSS_FROM.   
 Compute the set of registers set and used in the ACROSS range.   
 Compute an upper bound for the amount of insns moved, by finding
 the first insn in MERGE that sets a register in TEST_USE, or uses
 a register in TEST_SET.  We also check for calls, trapping operations,
 and memory references.   
         We cannot move memory stores past each other, or move memory
         reads past stores, at least not without tracking them and
         calling true_dependence on every pair.

         If there is no other branch and no memory references or
         sets in the ACROSS range, we can move memory references
         freely, even volatile ones.

         Otherwise, the rules are as follows: volatile memory
         references and stores can't be moved at all, and any type
         of memory reference can't be moved if there are volatile
         accesses or stores in the ACROSS range.  That leaves
         normal reads, which can be moved, as the trapping case is
         dealt with elsewhere.   
             Catch sets of the stack pointer.   
         We're only interested in uses which use a value live at
         the top, not one previously set in this block.   
 Now, lower this upper bound by also taking into account that
 a range of insns moved across ACROSS must not leave a register
 live at the end that will be clobbered in ACROSS.  We need to
 find a point where TEST_SET & LIVE == 0.

 Insns in the MERGE range that set registers which are also set
 in the ACROSS range may still be moved as long as we also move
 later insns which use the results of the set, and make the
 register dead again.  This is verified by the condition stated
 above.  We only need to test it for registers that are set in
 the moved region.

 MERGE_LIVE is provided by the caller and holds live registers after
 TO.   
 We're not interested in registers that aren't set in the moved
 region at all.   
 For small register class machines, don't lengthen lifetimes of
 hard registers before reload.   
void df_chain_add_problem ( )

Create a new DATAFLOW instance and add it to an existing instance of DF. The returned structure is what is used to get at the solution.

Referenced by mark_artificial_uses().

static void df_chain_alloc ( )
static

Create def-use or use-def chains.

References df_chain_create_bb().

static void df_chain_bb_dump ( )
static

Debugging info.

Artificials are only hard regs.

Referenced by df_chain_create_bb().

static void df_chain_bottom_dump ( )
static
void df_chain_copy ( df_ref  to_ref,
struct df_link from_ref 
)

Copy the du or ud chain starting at FROM_REF and attach it to TO_REF.

struct df_link* df_chain_create ( )
read

Create a du or ud chain from SRC to DST and link it into SRC.

References BITMAP_FREE, df_chain, and df_chain_remove_problem().

static void df_chain_create_bb ( )
static

Create chains from reaching defs bitmaps for basic block BB.

 Since we are going forwards, process the artificial uses first
 then the artificial defs second.   
 Process the regular instructions next.   
       First scan the uses and link them up with the defs that remain
       in the cpy vector.   
       Since we are going forwards, process the defs second.   
 Create the chains for the artificial uses of the hard registers
 at the end of the block.   

References df_chain_bb_dump().

Referenced by df_chain_alloc().

static void df_chain_create_bb_process_use ( bitmap  local_rd,
df_ref use_rec,
int  top_flag 
)
static

Create the chains for a list of USEs.

Do not want to go through this for an uninitialized var.

References df_chain_dump(), df_get_artificial_uses(), DF_REF_CHAIN, DF_REF_FLAGS, DF_REF_REGNO, and basic_block_def::index.

Referenced by df_chain_remove_problem().

void df_chain_dump ( )

Generic versions to get the void* version of the block info. Only used inside the problem instance vectors. Dump a def-use or use-def chain for REF to FILE.

References DF_REF_BBNO, DF_REF_FLAGS, DF_REF_ID, DF_REF_IN_NOTE, DF_REF_INSN_UID, DF_REF_IS_ARTIFICIAL, DF_REF_REG_DEF_P, and df_link::ref.

Referenced by df_chain_create_bb_process_use(), df_chain_finalize(), df_dump_bb_problem_data(), and df_insn_debug_regno().

static void df_chain_finalize ( )
static

Create def-use chains from reaching use bitmaps for basic blocks in BLOCKS.

References df_d::changeable_flags, df, df_chain_dump(), DF_NO_HARD_REGS, DF_REF_CHAIN, DF_REF_FLAGS, DF_REF_READ_WRITE, DF_REF_REGNO, and HARD_REGISTER_NUM_P.

static void df_chain_free ( )
static

Free all storage associated with the problem.

static void df_chain_fully_remove_problem ( )
static

Remove the chain problem completely.

static void df_chain_insn_bottom_dump ( )
static
static void df_chain_insn_top_dump ( )
static
static void df_chain_reset ( )
static

Reset all of the chains when the set of basic blocks changes.

static void df_chain_top_dump ( )
static
void df_chain_unlink ( )

Delete a du or ud chain that leave or point to REF.

Delete the other side if it exists.

static void df_chain_unlink_1 ( )
static

Delete any du or ud chains that start at REF and point to TARGET.

static void df_create_unused_note ( rtx  insn,
df_ref  def,
bitmap  live,
bitmap  artificial_uses,
struct dead_debug_local debug 
)
static

Create a REG_UNUSED note if necessary for DEF in INSN updating LIVE. Do not generate notes for registers in ARTIFICIAL_USES.

References bitmap_bit_p, dead_debug_add(), dead_debug_insert_temp(), DEBUG_TEMP_BEFORE_WITH_REG, df_ignore_stack_reg(), df_ref_debug(), DF_REF_FLAGS, DF_REF_READ_WRITE, DF_REF_REGNO, dump_file, and REG_DEAD_DEBUGGING.

Referenced by df_set_dead_notes_for_mw().

static bool df_ignore_stack_reg ( )
inlinestatic

After reg-stack, the x86 floating point stack regs are difficult to analyze because of all of the pushes, pops and rotations. Thus, we just leave the notes alone.

References df_set_note(), df_whole_mw_reg_unused_p(), dump_file, df_mw_hardreg::end_regno, df_mw_hardreg::mw_reg, REG_DEAD_DEBUGGING, and df_mw_hardreg::start_regno.

Referenced by df_create_unused_note(), df_whole_mw_reg_dead_p(), and df_word_lr_top_dump().

void df_live_add_problem ( void  )

Create a new DATAFLOW instance and add it to an existing instance of DF. The returned structure is what is used to get at the solution.

These will be initialized when df_scan_blocks processes each block.

References DF_REF_CHAIN, df_link::next, NULL, and df_link::ref.

static void df_live_alloc ( )
static

Allocate or reset bitmaps for DF_LIVE blocks. The solution bits are not touched unless the block is new.

When bitmaps are already initialized, just clear them.

References bitmap_set_bit, DF_REF_CONDITIONAL, DF_REF_FLAGS_IS_SET, DF_REF_MAY_CLOBBER, DF_REF_MUST_CLOBBER, DF_REF_PARTIAL, DF_REF_REGNO, df_live_bb_info::gen, and df_live_bb_info::kill.

static void df_live_bb_local_compute ( )
static

Compute local uninitialized register info for basic block BB.

     Inserting labels does not always trigger the incremental
     rescanning.   
           All partial or conditional def
           seen are included in the gen set.  
           Only must clobbers for the entire reg destroy the
           value.   

References bitmap_ior_into(), edge_def::dest, df_live_get_bb_info(), edge_def::flags, df_live_bb_info::in, basic_block_def::index, df_live_bb_info::out, and edge_def::src.

Referenced by df_live_verify_solution_end().

static void df_live_bottom_dump ( )
static

Debugging info at bottom of bb.

static bool df_live_confluence_n ( )
static

Forward confluence function that ignores fake edges.

References df_print_regset(), df_live_problem_data::in, and basic_block_def::index.

static void df_live_finalize ( )
static

And the LR info with the must-initialized registers, to produce the LIVE info.

No register may reach a location where it is not used. Thus we trim the rr result to the places where it is used.

References bitmap_copy(), bitmap_initialize, df_live, DF_LIVE_IN, DF_LIVE_OUT, FOR_ALL_BB, df_live_problem_data::in, basic_block_def::index, last_basic_block, df_live_problem_data::live_bitmaps, and df_live_problem_data::out.

static void df_live_free ( )
static
static void df_live_free_bb_info ( basic_block  bb,
void *  vbb_info 
)
static
static void df_live_init ( )
static

Initialize the solution vectors.

No register may reach a location where it is not used. Thus we trim the rr result to the places where it is used.

static void df_live_local_compute ( )
static

Compute local uninitialized register info.

static void df_live_reset ( )
static
void df_live_set_all_dirty ( void  )

Set all of the blocks as dirty. This needs to be done if this problem is added after all of the insns have been scanned.

static void df_live_top_dump ( )
static

Debugging info at top of bb.

static bool df_live_transfer_function ( )
static

Transfer function for the forwards must-initialized problem.

We need to use a scratch set here so that the value returned from this function invocation properly reflects whether the sets changed in a significant way; i.e. not just because the lr set was anded in.

 No register may reach a location where it is not used.  Thus
 we trim the rr result to the places where it is used.   

References df_live, df_live_get_bb_info(), df_print_regset(), basic_block_def::index, df_live_bb_info::out, and df_live_problem_data::out.

static void df_live_verify_solution_end ( )
static

Compare the saved datastructure and the new solution to the dataflow equations.

Cannot delete them immediately because you may want to dump them if the comparison fails.

References bitmap_bit_p, bitmap_clear(), bitmap_copy(), bitmap_equal_p(), bitmap_set_bit, df_live, df_live_bb_local_compute(), df_live_get_bb_info(), df_scan_get_bb_info(), gcc_assert, df_live_bb_info::gen, basic_block_def::index, and df_live_bb_info::kill.

static void df_live_verify_solution_start ( )
static

Build the datastructure to verify that the solution to the dataflow equations is not dirty.

Set it true so that the solution is recomputed.

References bitmap_set_bit, df_live, FOR_ALL_BB, and basic_block_def::index.

void df_live_verify_transfer_functions ( void  )

Verify that all of the lr related info is consistent and correct.

         Make a copy of the transfer functions and then compute
         new ones to see if the transfer functions have
         changed.   
         If we do not have basic block info, the block must be in
         the list of dirty blocks or else some one has added a
         block behind our backs.  
     Make sure no one created a block without following
     procedures.   
 Make sure there are no dirty bits in blocks that have been deleted.   
void df_lr_add_problem ( void  )

Create a new DATAFLOW instance and add it to an existing instance of DF. The returned structure is what is used to get at the solution.

These will be initialized when df_scan_blocks processes each block.

static void df_lr_alloc ( )
static

Allocate or reset bitmaps for DF_LR blocks. The solution bits are not touched unless the block is new.

When bitmaps are already initialized, just clear them.

References bitmap_clear(), df_lr_get_bb_info(), EXECUTE_IF_SET_IN_BITMAP, gcc_assert, df_lr_bb_info::in, and df_lr_bb_info::out.

Referenced by df_lr_confluence_0().

static void df_lr_bb_local_compute ( )
static

Compute local live register info for basic block BB.

 Process the registers set in an exception handler.   
 Process the hardware registers that are always live.   
     Add use to set of uses in this BB.   
         If the def is to only part of the reg, it does
         not kill the other defs that reach here.   
         Add use to set of uses in this BB.   
 Process the registers set in an exception handler or the hard
 frame pointer if this block is the target of a non local
 goto.   
 If the df_live problem is not defined, such as at -O0 and -O1, we
 still need to keep the luids up to date.  This is normally done
 in the df_live problem since this problem has a forwards
 scan.   
static void df_lr_bottom_dump ( )
static

Debugging info at bottom of bb.

static void df_lr_confluence_0 ( )
static

Confluence function that processes infinite loops. This might be a noreturn function that throws. And even if it isn't, getting the unwind info right helps debugging.

References df, df_clear_flags(), df_lr, df_lr_alloc(), df_lr_finalize(), df_lr_local_compute(), DF_LR_RUN_DCE, df_set_flags(), df_worklist_dataflow(), df_d::n_blocks, and df_d::postorder.

static bool df_lr_confluence_n ( )
static

Confluence function that ignores fake edges.

Call-clobbered registers die across exception and call edges.

 ??? Abnormal call edges ignored for the moment, as this gets
 confused by sibling call edges, which crashes reg-stack.   
static void df_lr_finalize ( )
static

Run the fast dce as a side effect of building LR.

If dce deletes some instructions, we need to recompute the lr solution before proceeding further. The problem is that fast dce is a pessimestic dataflow algorithm. In the case where it deletes a statement S inside of a loop, the uses inside of S may not be deleted from the dataflow solution because they were carried around the loop. While it is conservatively correct to leave these extra bits, the standards of df require that we maintain the best possible (least fixed point) solution. The only way to do that is to redo the iteration from the beginning. See PR35805 for an example.

References df_print_regset(), df_lr_problem_data::in, and basic_block_def::index.

Referenced by df_lr_confluence_0().

static void df_lr_free ( )
static
static void df_lr_free_bb_info ( basic_block  bb,
void *  vbb_info 
)
static

Free basic block info.

References bitmap_clear(), df_lr_bb_info::def, and df_lr_bb_info::use.

static void df_lr_init ( )
static

Initialize the solution vectors.

References df_d::changeable_flags, df, df_lr, DF_LR_RUN_DCE, and run_fast_df_dce().

static void df_lr_local_compute ( )
static

Compute local live register info for each basic block within BLOCKS.

 The all-important stack pointer must always be live.   
 Global regs are always live, too.   
 Before reload, there are a few registers that must be forced
 live everywhere – which might not already be the case for
 blocks within infinite loops.   
     Any reference to any pseudo before reload is a potential
     reference of the frame pointer.   
     Any constant, or pseudo with constant equivalences, may
     require reloading from memory using the pic register.   
         The exit block is special for this problem and its bits are
         computed from thin air.   

References bitmap_clear(), bitmap_copy(), df_lr_get_bb_info(), EXECUTE_IF_SET_IN_BITMAP, df_lr_bb_info::in, df_lr_bb_info::out, and df_lr_bb_info::use.

Referenced by df_lr_confluence_0().

static void df_lr_reset ( )
static

Reset the global solution for recalculation.

static void df_lr_top_dump ( )
static

Debugging info at top of bb.

static bool df_lr_transfer_function ( )
static
static void df_lr_verify_solution_end ( )
static

Compare the saved datastructure and the new solution to the dataflow equations.

Do not check if the solution is still dirty. See the comment in df_lr_finalize for details.

 Cannot delete them immediately because you may want to dump them
 if the comparison fails.   

References BITMAP_ALLOC, df_add_problem(), df_bitmap_obstack, and df_lr.

static void df_lr_verify_solution_start ( )
static

Build the datastructure to verify that the solution to the dataflow equations is not dirty.

Set it true so that the solution is recomputed.

void df_lr_verify_transfer_functions ( void  )

Verify that all of the lr related info is consistent and correct.

         Make a copy of the transfer functions and then compute
         new ones to see if the transfer functions have
         changed.   
         If we do not have basic block info, the block must be in
         the list of dirty blocks or else some one has added a
         block behind our backs.  
     Make sure no one created a block without following
     procedures.   
 Make sure there are no dirty bits in blocks that have been deleted.   

References df_live_problem_data::in, df_live_problem_data::live_bitmaps, and df_live_problem_data::out.

void df_md_add_problem ( void  )

Create a new MD instance and add it to the existing instance of DF.

static void df_md_alloc ( )
static

Allocate or reset bitmaps for DF_MD. The solution bits are not touched unless the block is new.

When bitmaps are already initialized, just clear them.

References bitmap_copy(), df_md_get_bb_info(), df_md_transfer_function(), EXECUTE_IF_SET_IN_BITMAP, df_md_bb_info::in, and df_md_bb_info::init.

static void df_md_bb_local_compute ( )
static

Compute local multiple def info for basic block BB.

Artificials are only hard regs.

static void df_md_bb_local_compute_process_def ( struct df_md_bb_info bb_info,
df_ref def_rec,
int  top_flag 
)
static

When we find a clobber and a regular def, make sure the regular def wins.

static void df_md_bottom_dump ( )
static

Debugging info at bottom of bb.

static void df_md_confluence_0 ( )
static
static bool df_md_confluence_n ( )
static

In of target gets or of out of source.

static void df_md_free ( )
static

Free all storage associated with the problem.

static void df_md_free_bb_info ( basic_block  bb,
void *  vbb_info 
)
static
static void df_md_init ( )
static

Initialize the solution bit vectors for problem.

static void df_md_local_compute ( )
static

Compute local reaching def info for each basic block within BLOCKS.

Add each basic block's kills to the nodes in the frontier of the BB.

static void df_md_reset ( )
static

Reset the global solution for recalculation.

void df_md_simulate_artificial_defs_at_top ( )

Add the effect of the top artificial defs of BB to the multiple definitions bitmap LOCAL_MD.

void df_md_simulate_one_insn ( basic_block  bb,
rtx  insn,
bitmap  local_md 
)

Add the effect of the defs of INSN to the reaching definitions bitmap LOCAL_MD.

static void df_md_top_dump ( )
static

Debugging info at top of bb.

static bool df_md_transfer_function ( )
static

We need to use a scratch set here so that the value returned from this function invocation properly reflects whether the sets changed in a significant way; i.e. not just because the live set was anded in.

 Multiple definitions of a register are not relevant if it is not
 live.  Thus we trim the result to the places where it is live.   

Referenced by df_md_alloc().

void df_note_add_problem ( void  )

Create a new DATAFLOW instance and add it to an existing instance of DF. The returned structure is what is used to get at the solution.

References bitmap_set_bit, DF_REF_FLAGS, and DF_REF_REGNO.

Referenced by compute_bb_for_insn(), dse_step4(), and split_live_ranges_for_shrink_wrap().

static void df_note_alloc ( )
static
static void df_note_bb_compute ( unsigned int  bb_index,
bitmap  live,
bitmap  do_not_gen,
bitmap  artificial_uses 
)
static

Recompute the REG_DEAD and REG_UNUSED notes and compute register info: lifetime, bb, and number of defs and uses for basic block BB. The three bitvectors are scratch regs used here.

 Process the artificial defs and uses at the bottom of the block
 to begin processing.   
         Notes are not generated for any of the artificial registers
         at the bottom of the block.   
     Process the defs.   
         We only care about real sets for calls.  Clobbers cannot
         be depended on to really die.   
         All of the defs except the return value are some sort of
         clobber.  This code is for the return.   
         Regular insn.   
     Process the uses.   
                     We won't add REG_UNUSED or REG_DEAD notes for
                     these, so we don't have to mess with them in
                     debug insns either.   
             This register is now live.   
         ??? We could probably do better here, replacing dead
         registers with their definitions.   

References df_print_note(), DF_REF_LOC, DF_REF_REAL_LOC, DF_REF_REG, df_set_note(), REG_DEAD_DEBUGGING, and REG_NOTES.

static void df_note_compute ( )
static

Compute register info: lifetime, bb, and number of defs and uses.

??? Unlike fast DCE, we don't use global_debug for uses of dead pseudos in debug insns because we don't always (re)visit blocks with death points after visiting dead uses. Even changing this loop to postorder would still leave room for visiting a death point before visiting a subsequent debug use.

static void df_note_free ( )
static

Free all storage associated with the problem.

void df_print_bb_index ( )

Print some basic block info as part of df_dump.

static void df_print_note ( )
static

This is only used if REG_DEAD_DEBUGGING is in effect.

Referenced by df_note_bb_compute(), df_remove_dead_eq_notes(), and df_word_lr_top_dump().

void df_rd_add_problem ( void  )

Create a new RD instance and add it to the existing instance of DF.

static void df_rd_alloc ( )
static

Allocate or reset bitmaps for DF_RD blocks. The solution bits are not touched unless the block is new.

Because of the clustering of all use sites for the same pseudo, we have to process all of the blocks before doing the analysis.

     When bitmaps are already initialized, just clear them.   

References bitmap_initialize, bitmap_obstack_initialize(), df_rd_problem_data::dense_invalidated_by_call, df_rd, df_rd_problem_data::rd_bitmaps, and df_rd_problem_data::sparse_invalidated_by_call.

static void df_rd_bb_local_compute ( )
static

Compute local reaching def info for basic block BB.

 Artificials are only hard regs.   
     This complex dance with the two bitmaps is required because
     instructions can assign twice to the same pseudo.  This
     generally happens with calls that will have one def for the
     result and another def for the clobber.  If only one vector
     is used and the clobber goes first, the result will be
     lost.   
 Process the artificial defs at the top of the block last since we
 are going backwards through the block and these are logically at
 the start.   
static void df_rd_bb_local_compute_process_def ( struct df_rd_bb_info bb_info,
df_ref def_rec,
int  top_flag 
)
static

Process a list of DEFs for df_rd_bb_local_compute. This is a bit more complicated than just simulating, because we must produce the gen and kill sets and hence deal with the two possible representations of kill sets.

             Only the last def(s) for a regno in the block has any
             effect.   
                 The first def for regno in insn gets to knock out the
                 defs from other instructions.   
                     If the def is to only part of the reg, it does
                     not kill the other defs that reach here.   
                 All defs for regno in the instruction may be put into
                 the gen set.   

References bitmap_bit_p, bitmap_clear_range(), bitmap_set_bit, bitmap_set_range(), DF_REF_CONDITIONAL, DF_REF_FLAGS, DF_REF_ID, DF_REF_MAY_CLOBBER, DF_REF_MUST_CLOBBER, DF_REF_PARTIAL, DF_SPARSE_THRESHOLD, df_rd_bb_info::gen, df_rd_bb_info::kill, and df_rd_bb_info::sparse_kill.

static void df_rd_bottom_dump ( )
static

Debugging info at bottom of bb.

static bool df_rd_confluence_n ( )
static

In of target gets or of out of source.

static void df_rd_dump_defs_set ( )
static
static void df_rd_free ( )
static

Free all storage associated with the problem.

static void df_rd_free_bb_info ( basic_block  bb,
void *  vbb_info 
)
static

Free basic block info.

static void df_rd_init_solution ( )
static

Initialize the solution bit vectors for problem.

static void df_rd_local_compute ( )
static

Compute local reaching def info for each basic block within BLOCKS.

Set up the knockout bit vectors to be applied across EH_EDGES.

void df_rd_simulate_artificial_defs_at_top ( )

Add the effect of the top artificial defs of BB to the reaching definitions bitmap LOCAL_RD.

Referenced by df_chain_remove_problem().

void df_rd_simulate_one_insn ( basic_block  bb,
rtx  insn,
bitmap  local_rd 
)

Add the effect of the defs of INSN to the reaching definitions bitmap LOCAL_RD.

Referenced by df_chain_remove_problem().

static void df_rd_start_dump ( )
static

Debugging info.

static void df_rd_top_dump ( )
static

Debugging info at top of bb.

static bool df_rd_transfer_function ( )
static

Transfer function.

Note that TMP is not a temporary bitmap if we end up replacing OUT with TMP. Therefore, allocate TMP in the RD bitmaps obstack.

     Create a mask of DEFs for all registers live at the end of this
     basic block, and mask out DEFs of registers that are not live.
     Computing the mask looks costly, but the benefit of the pruning
     outweighs the cost.   
static void df_remove_dead_and_unused_notes ( )
static

Remove all of the REG_DEAD or REG_UNUSED notes from INSN.

After reg-stack, we need to ignore any unused notes for the stack registers.

         After reg-stack, we need to ignore any unused notes
         for the stack registers.   
static void df_remove_dead_eq_notes ( )
static

Remove REG_EQUAL/REG_EQUIV notes referring to dead pseudos using LIVE as the bitmap of currently live registers.

Remove the notes that refer to dead registers. As we have at most one REG_EQUAL/EQUIV note, all of EQ_USES will refer to this note so we need to purge the complete EQ_USES vector when removing the note using df_notes_rescan.

References bitmap_bit_p, df_print_note(), df_print_regset(), df_set_note(), df_whole_mw_reg_dead_p(), dump_file, df_mw_hardreg::end_regno, df_mw_hardreg::mw_reg, REG_DEAD_DEBUGGING, REG_NOTES, regno_reg_rtx, and df_mw_hardreg::start_regno.

static void df_set_dead_notes_for_mw ( rtx  insn,
struct df_mw_hardreg mws,
bitmap  live,
bitmap  do_not_gen,
bitmap  artificial_uses,
bool added_notes_p 
)
static

Set the REG_DEAD notes for the multiword hardreg use in INSN based on the bits in LIVE. DO_NOT_GEN is used to keep REG_DEAD notes from being set if the instruction both reads and writes the register.

Add a dead note for the entire multi word register.

References bitmap_set_bit, and df_create_unused_note().

static void df_set_note ( )
inlinestatic

Set a NOTE_TYPE note for REG in INSN.

Referenced by df_ignore_stack_reg(), df_note_bb_compute(), and df_remove_dead_eq_notes().

static void df_set_unused_notes_for_mw ( rtx  insn,
struct df_mw_hardreg mws,
bitmap  live,
bitmap  do_not_gen,
bitmap  artificial_uses,
struct dead_debug_local debug 
)
static

Set the REG_UNUSED notes for the multiword hardreg defs in INSN based on the bits in LIVE. Do not generate notes for registers in artificial uses. DO_NOT_GEN is updated so that REG_DEAD notes are not generated if the reg is both read and written by the instruction.

Only do this if the value is totally dead.

References bitmap_clear_bit(), DF_REF_FLAGS, DF_REF_REGNO, dump_file, and REG_DEAD_DEBUGGING.

Referenced by df_whole_mw_reg_dead_p().

void df_simulate_defs ( )

Simulate the effects of the defs of INSN on LIVE.

If the def is to only part of the reg, it does not kill the other defs that reach here.

References GET_CODE, MEM_P, MEM_READONLY_P, MEM_VOLATILE_P, MEMREF_NORMAL, and MEMREF_VOLATILE.

void df_simulate_finalize_backwards ( )

Apply the artificial uses and defs at the top of BB in a backwards direction.

void df_simulate_find_defs ( )

Find the set of DEFs for INSN.

References bitmap_set_bit, DF_REF_FLAGS, and DF_REF_REGNO.

void df_simulate_find_noclobber_defs ( )

Find the set of real DEFs, which are not clobbers, for INSN.

static void df_simulate_find_uses ( )
static

Find the set of uses for INSN. This includes partial defs.

Referenced by df_simulate_one_insn_forwards().

static void df_simulate_fixup_sets ( )
inlinestatic

Add back the always live regs in BB to LIVE.

These regs are considered always live so if they end up dying because of some def, we need to bring the back again.

References BB_END, bitmap_copy(), df_get_live_out(), df_simulate_initialize_backwards(), df_simulate_one_insn_backwards(), and PREV_INSN.

void df_simulate_initialize_backwards ( )

Apply the artificial uses and defs at the end of BB in a backwards direction.

References NEXT_INSN, NONDEBUG_INSN_P, and NULL_RTX.

Referenced by df_simulate_fixup_sets().

void df_simulate_initialize_forwards ( )

Initialize the LIVE bitmap, which should be copied from DF_LIVE_IN or DF_LR_IN for basic block BB, for forward scanning by marking artificial defs live.

void df_simulate_one_insn_backwards ( )

Simulate the backwards effects of INSN on the bitmap LIVE.

Referenced by df_simulate_fixup_sets().

void df_simulate_one_insn_forwards ( )

Simulate the forwards effects of INSN on the bitmap LIVE.

 Make sure that DF_NOTE really is an active df problem.   
 Note that this is the opposite as how the problem is defined, because
 in the LR problem defs _kill_ liveness.  However, they do so backwards,
 while here the scan is performed forwards!  So, first assume that the
 def is live, and if this is not true REG_UNUSED notes will rectify the
 situation.   
 Clear all of the registers that go dead.   

References bitmap_and_compl_into(), df_simulate_find_uses(), find_memory(), find_memory_stores(), for_each_rtx(), may_trap_or_fault_p(), MEMREF_VOLATILE, note_stores(), PATTERN, and volatile_insn_p().

void df_simulate_uses ( )

Simulate the effects of the uses of INSN on LIVE.

Add use to set of uses in this BB.

References GET_CODE, MEM_P, MEM_VOLATILE_P, MEMREF_NORMAL, MEMREF_VOLATILE, pflags, stack_pointer_rtx, and XEXP.

Referenced by find_if_case_2().

static bool df_whole_mw_reg_dead_p ( struct df_mw_hardreg mws,
bitmap  live,
bitmap  artificial_uses,
bitmap  do_not_gen 
)
static

A subroutine of df_set_dead_notes_for_mw, with a selection of its arguments. Return true if the register value described by MWS's mw_reg is known to be completely dead, and if mw_reg can therefore be used in a REG_DEAD note.

If MWS describes a partial reference, create REG_DEAD notes for individual hard registers.

 Likewise if some part of the register is not dead.   

References df_ignore_stack_reg(), DF_INSN_UID_DEFS, DF_INSN_UID_MWS, DF_MWS_REG_DEF_P, df_print_regset(), DF_REF_FLAGS_IS_SET, DF_REF_MAY_CLOBBER, DF_REF_MUST_CLOBBER, DF_REF_REGNO, df_set_unused_notes_for_mw(), dump_file, INSN_UID, REG_DEAD_DEBUGGING, and df_mw_hardreg::start_regno.

Referenced by df_remove_dead_eq_notes().

static bool df_whole_mw_reg_unused_p ( struct df_mw_hardreg mws,
bitmap  live,
bitmap  artificial_uses 
)
static

A subroutine of df_set_unused_notes_for_mw, with a selection of its arguments. Return true if the register value described by MWS's mw_reg is known to be completely unused, and if mw_reg can therefore be used in a REG_UNUSED note.

If MWS describes a partial reference, create REG_UNUSED notes for individual hard registers.

 Likewise if some part of the register is used.   

Referenced by df_ignore_stack_reg().

void df_word_lr_add_problem ( void  )

Create a new DATAFLOW instance and add it to an existing instance of DF. The returned structure is what is used to get at the solution.

These will be initialized when df_scan_blocks processes each block.

References bitmap_bit_p, DF_REF_FLAGS, DF_REF_IN_NOTE, DF_REF_LOC, DF_REF_REGNO, loc_mentioned_in_p(), and XEXP.

static void df_word_lr_alloc ( )
static

Allocate or reset bitmaps for DF_WORD_LR blocks. The solution bits are not touched unless the block is new.

Create the mapping from regnos to slots. This does not change unless the problem is destroyed and recreated. In particular, if we end up deleting the only insn that used a subreg, we do not want to redo the mapping because this would invalidate everything else.

     When bitmaps are already initialized, just clear them.   

References df_word_lr_bb_info::def, df_word_lr_mark_ref(), and df_word_lr_bb_info::use.

static void df_word_lr_bb_local_compute ( )
static

Compute local live register info for basic block BB.

Ensure that artificial refs don't contain references to pseudos.

         If the def is to only part of the reg, it does
         not kill the other defs that reach here.   

References df_print_word_regset(), df_word_lr_get_bb_info(), basic_block_def::index, and df_word_lr_bb_info::out.

static void df_word_lr_bottom_dump ( )
static

Debugging info at bottom of bb.

References XEXP.

static bool df_word_lr_confluence_n ( )
static

Confluence function that ignores fake edges.

References df_note.

static void df_word_lr_free ( )
static

Free all storage associated with the problem.

static void df_word_lr_free_bb_info ( basic_block  bb,
void *  vbb_info 
)
static

Free basic block info.

References DF_REF_REGNO, and gcc_assert.

static void df_word_lr_init ( )
static

Initialize the solution vectors.

static void df_word_lr_local_compute ( )
static

Compute local live register info for each basic block within BLOCKS.

bool df_word_lr_mark_ref ( )

Examine REF, and if it is for a reg we're interested in, set or clear the bits corresponding to its subwords from the bitmap according to IS_SET. LIVE is the bitmap we should update. We do not track hard regs or pseudos of any size other than 2 * UNITS_PER_WORD. We return true if we changed the bitmap, or if we encountered a register we're not tracking.

Left at -1 for whole accesses.

Referenced by df_word_lr_alloc().

static void df_word_lr_reset ( )
static

Reset the global solution for recalculation.

bool df_word_lr_simulate_defs ( )

Simulate the effects of the defs of INSN on LIVE. Return true if we changed any bits, which is used by the caller to determine whether a set is necessary. We also return true if there are other reasons not to delete an insn.

void df_word_lr_simulate_uses ( )

Simulate the effects of the uses of INSN on LIVE.

References add_reg_note(), DEBUG_INSN_P, and gcc_checking_assert.

static void df_word_lr_top_dump ( )
static

Debugging info at top of bb.

References df_ignore_stack_reg(), df_print_note(), free_EXPR_LIST_node(), REG_DEAD_DEBUGGING, REGNO, and XEXP.

static bool df_word_lr_transfer_function ( )
static

Transfer function.

References dump_file, INSN_UID, and print_rtl().

static int find_memory ( )
static

A subroutine of can_move_insns_across_p called through for_each_rtx. Return either MEMREF_NORMAL or MEMREF_VOLATILE if a memory is found.

Referenced by df_simulate_one_insn_forwards().

static void find_memory_stores ( rtx  x,
const_rtx  pat,
void *  data 
)
static

A subroutine of can_move_insns_across_p called through note_stores. DATA points to an integer in which we set either the bit for MEMREF_NORMAL or the bit for MEMREF_VOLATILE if we find a MEM of either kind.

Treat stores to SP as stores to memory, this will prevent problems when there are references to the stack frame.

Referenced by df_simulate_one_insn_forwards().

void simulate_backwards_to_point ( )

Scan BB backwards, using df_simulate functions to keep track of lifetimes, up to insn POINT. The result is stored in LIVE.

Scan and update life information until we reach the point we're interested in.


Variable Documentation

bitmap_head df_live_scratch
static

Scratch var used by transfer functions. This is used to implement an optimization to reduce the amount of space used to compute the combined lr and live analysis.

bitmap_head df_md_scratch
static

Scratch var used by transfer functions. This is used to do md analysis only for live registers.

struct df_problem problem_NOTE
static
Initial value:

All of the information associated every instance of the problem.

struct df_problem problem_RD
static
bitmap_head seen_in_block
static
bitmap_head seen_in_insn
static