GCC Middle and Back End API Reference
df-scan.c File Reference

Data Structures

struct  df_collection_rec
struct  df_scan_problem_data

Macros

#define HAVE_epilogue   0
#define HAVE_prologue   0
#define HAVE_sibcall_epilogue   0
#define EPILOGUE_USES(REGNO)   0
#define df_scan_free_ref_vec(V)
#define df_scan_free_mws_vec(V)

Typedefs

typedef struct df_mw_hardregdf_mw_hardreg_ptr
typedef struct df_scan_bb_infodf_scan_bb_info_t

Functions

static void df_ref_record (enum df_ref_class, struct df_collection_rec *, rtx, rtx *, basic_block, struct df_insn_info *, enum df_ref_type, int ref_flags)
static void df_def_record_1 (struct df_collection_rec *, rtx *, basic_block, struct df_insn_info *, int ref_flags)
static void df_defs_record (struct df_collection_rec *, rtx, basic_block, struct df_insn_info *, int ref_flags)
static void df_uses_record (struct df_collection_rec *, rtx *, enum df_ref_type, basic_block, struct df_insn_info *, int ref_flags)
static void df_install_ref_incremental (df_ref)
static df_ref df_ref_create_structure (enum df_ref_class, struct df_collection_rec *, rtx, rtx *, basic_block, struct df_insn_info *, enum df_ref_type, int ref_flags)
static void df_insn_refs_collect (struct df_collection_rec *, basic_block, struct df_insn_info *)
static void df_canonize_collection_rec (struct df_collection_rec *)
static void df_get_regular_block_artificial_uses (bitmap)
static void df_get_eh_block_artificial_uses (bitmap)
static void df_record_entry_block_defs (bitmap)
static void df_record_exit_block_uses (bitmap)
static void df_get_exit_block_use_set (bitmap)
static void df_get_entry_block_def_set (bitmap)
static void df_grow_ref_info (struct df_ref_info *, unsigned int)
static void df_ref_chain_delete_du_chain (df_ref *)
static void df_ref_chain_delete (df_ref *)
static void df_refs_add_to_chains (struct df_collection_rec *, basic_block, rtx, unsigned int)
static bool df_insn_refs_verify (struct df_collection_rec *, basic_block, rtx, bool)
static void df_entry_block_defs_collect (struct df_collection_rec *, bitmap)
static void df_exit_block_uses_collect (struct df_collection_rec *, bitmap)
static void df_install_ref (df_ref, struct df_reg_info *, struct df_ref_info *, bool)
static int df_ref_compare (const void *, const void *)
static int df_mw_compare (const void *, const void *)
static void df_insn_info_delete (unsigned int)
static void df_scan_free_internal ()
static void df_scan_free_bb_info ()
void df_scan_alloc ()
static void df_scan_free ()
static void df_scan_start_dump ()
static void df_scan_start_block ()
void df_scan_add_problem ()
void df_grow_reg_info ()
static void df_grow_ref_info ()
static void df_check_and_grow_ref_info (struct df_ref_info *ref_info, unsigned bitmap_addend)
void df_grow_insn_info ()
void df_scan_blocks ()
void df_uses_create ()
df_ref df_ref_create (rtx reg, rtx *loc, rtx insn, basic_block bb, enum df_ref_type ref_type, int ref_flags)
static void df_install_ref_incremental ()
static void df_free_ref ()
static void df_reg_chain_unlink ()
static void df_ref_compress_rec ()
void df_ref_remove ()
struct df_insn_infodf_insn_create_insn_record ()
static void df_ref_chain_delete_du_chain ()
static void df_ref_chain_delete ()
static void df_mw_hardreg_chain_delete ()
static void df_insn_info_delete ()
void df_insn_delete ()
static void df_free_collection_rec ()
bool df_insn_rescan ()
bool df_insn_rescan_debug_internal ()
void df_insn_rescan_all ()
void df_process_deferred_rescans ()
static unsigned int df_count_refs (bool include_defs, bool include_uses, bool include_eq_uses)
static void df_reorganize_refs_by_reg_by_reg (struct df_ref_info *ref_info, bool include_defs, bool include_uses, bool include_eq_uses)
static void df_reorganize_refs_by_reg_by_insn (struct df_ref_info *ref_info, bool include_defs, bool include_uses, bool include_eq_uses)
static void df_reorganize_refs_by_reg (struct df_ref_info *ref_info, bool include_defs, bool include_uses, bool include_eq_uses)
static unsigned int df_add_refs_to_table (unsigned int offset, struct df_ref_info *ref_info, df_ref *ref_vec)
static unsigned int df_reorganize_refs_by_insn_bb (basic_block bb, unsigned int offset, struct df_ref_info *ref_info, bool include_defs, bool include_uses, bool include_eq_uses)
static void df_reorganize_refs_by_insn (struct df_ref_info *ref_info, bool include_defs, bool include_uses, bool include_eq_uses)
void df_maybe_reorganize_use_refs ()
void df_maybe_reorganize_def_refs ()
void df_insn_change_bb ()
static void df_ref_change_reg_with_loc_1 (struct df_reg_info *old_df, struct df_reg_info *new_df, int new_regno, rtx loc)
void df_ref_change_reg_with_loc ()
static unsigned int df_mw_hardreg_chain_delete_eq_uses ()
void df_notes_rescan ()
static bool df_ref_equal_p ()
static int df_ref_compare ()
static void df_swap_refs ()
static void df_sort_and_compress_refs ()
static bool df_mw_equal_p ()
static int df_mw_compare ()
static void df_sort_and_compress_mws ()
static void df_canonize_collection_rec ()
static df_refdf_install_refs (basic_block bb, const vec< df_ref, va_heap > *old_vec, struct df_reg_info **reg_info, struct df_ref_info *ref_info, bool is_notes)
static struct df_mw_hardreg ** df_install_mws ()
bool df_read_modify_subreg_p ()
static void df_find_hard_reg_defs_1 ()
static void df_find_hard_reg_defs ()
static void df_get_conditional_uses ()
static void df_get_call_refs (struct df_collection_rec *collection_rec, basic_block bb, struct df_insn_info *insn_info, int flags)
void df_recompute_luids ()
static void df_bb_refs_collect ()
void df_bb_refs_record ()
static void df_get_regular_block_artificial_uses ()
static void df_get_eh_block_artificial_uses ()
static void df_mark_reg ()
static void df_get_entry_block_def_set ()
static void df_record_entry_block_defs ()
void df_update_entry_block_defs ()
static void df_get_exit_block_use_set ()
static void df_exit_block_uses_collect ()
static void df_record_exit_block_uses ()
void df_update_exit_block_uses ()
void df_hard_reg_init ()
void df_update_entry_exit_and_calls ()
bool df_hard_reg_used_p ()
unsigned int df_hard_reg_used_count ()
bool df_regs_ever_live_p ()
void df_set_regs_ever_live ()
void df_compute_regs_ever_live ()
static unsigned int df_reg_chain_mark (df_ref refs, unsigned int regno, bool is_def, bool is_eq_use)
static void df_reg_chain_verify_unmarked ()
static bool df_refs_verify (const vec< df_ref, va_heap > *new_rec, df_ref *old_rec, bool abort_if_fail)
static bool df_mws_verify (const vec< df_mw_hardreg_ptr, va_heap > *new_rec, struct df_mw_hardreg **old_rec, bool abort_if_fail)
static bool df_bb_verify ()
static bool df_entry_block_bitmap_verify ()
static bool df_exit_block_bitmap_verify ()
void df_scan_verify ()

Variables

static HARD_REG_SET elim_reg_set
static df_ref df_null_ref_rec [1]
static struct df_mw_hardregdf_null_mw_rec [1]
static bool regs_ever_live [FIRST_PSEUDO_REGISTER]
static const unsigned int copy_defs = 0x1
static const unsigned int copy_uses = 0x2
static const unsigned int copy_eq_uses = 0x4
static const unsigned int copy_mw = 0x8
static const unsigned int copy_all
static struct df_problem problem_SCAN
static bool initialized = false

Macro Definition Documentation

#define df_scan_free_mws_vec (   V)
Value:
do { \
if (V && *V) \
free (V); \
} while (0)
#define df_scan_free_ref_vec (   V)
Value:
do { \
if (V && *V) \
free (V); \
} while (0)
   The following two macros free the vecs that hold either the refs or
   the mw refs.  They are a little tricky because the vec has 0
   elements is special and is not to be freed.  
#define EPILOGUE_USES (   REGNO)    0
#define HAVE_epilogue   0
#define HAVE_prologue   0
#define HAVE_sibcall_epilogue   0

Typedef Documentation

@verbatim 

Scanning of rtl for dataflow analysis. 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/.


Function Documentation

static unsigned int df_add_refs_to_table ( unsigned int  offset,
struct df_ref_info ref_info,
df_ref ref_vec 
)
static
   Add the refs in REF_VEC to the table in REF_INFO starting at OFFSET.  
static void df_bb_refs_collect ( )
static
   Collect all artificial refs at the block level for BB and add them
   to COLLECTION_REC.  
     Add the hard_frame_pointer if this block is the target of a
     non-local goto.  
     Add the artificial uses.  
void df_bb_refs_record ( )
   Record all the refs within the basic block BB_INDEX and scan the instructions if SCAN_INSNS.  
       Scan the block an insn at a time from beginning to end.  
               Record refs within INSN.  
     Other block level artificial refs 
     Now that the block has been processed, set the block as dirty so
     LR and LIVE will get it processed.  
static bool df_bb_verify ( )
static
   Return true if all refs in the basic block are correct and complete.
   Due to df_ref_chain_verify, it will cause all refs
   that are verified to have DF_REF_MARK bit set.  
     Scan the block, one insn at a time, from beginning to end.  
     Do the artificial defs and uses.  
static void df_canonize_collection_rec ( struct df_collection_rec )
static
static void df_canonize_collection_rec ( )
static
   Sort and remove duplicates from the COLLECTION_REC.  
static void df_check_and_grow_ref_info ( struct df_ref_info ref_info,
unsigned  bitmap_addend 
)
static
   Check and grow the ref information if necessary.  This routine
   guarantees total_size + BITMAP_ADDEND amount of entries in refs
   array.  It updates ref_info->refs_size only and does not change
   ref_info->total_size.  
void df_compute_regs_ever_live ( )
   Compute "regs_ever_live" information from the underlying df
   information.  Set the vector to all false if RESET.  
static unsigned int df_count_refs ( bool  include_defs,
bool  include_uses,
bool  include_eq_uses 
)
static
   Count the number of refs. Include the defs if INCLUDE_DEFS. Include
   the uses if INCLUDE_USES. Include the eq_uses if
   INCLUDE_EQ_USES.  
static void df_def_record_1 ( struct df_collection_rec collection_rec,
rtx loc,
basic_block  bb,
struct df_insn_info insn_info,
int  flags 
)
static
   Process all the registers defined in the rtx pointed by LOC.
   Autoincrement/decrement definitions will be picked up by df_uses_record.
   Any change here has to be matched in df_find_hard_reg_defs_1.  
     It is legal to have a set destination be a parallel. 
     At this point if we do not have a reg or a subreg, just return.  
         We want to keep sp alive everywhere - by making all
         writes to sp also use of sp. 
static void df_defs_record ( struct df_collection_rec collection_rec,
rtx  x,
basic_block  bb,
struct df_insn_info insn_info,
int  flags 
)
static
   Process all the registers defined in the pattern rtx, X.  Any change
   here has to be matched in df_find_hard_reg_defs.  
         No DEFs to record in other cases 
static bool df_entry_block_bitmap_verify ( )
static
   Returns true if the entry block has correct and complete df_ref set.
   If not it either aborts if ABORT_IF_FAIL is true or returns false.  
static void df_entry_block_defs_collect ( struct df_collection_rec collection_rec,
bitmap  entry_block_defs 
)
static
   Return the (conservative) set of hard registers that are defined on
   entry to the function.
   It uses df->entry_block_defs to determine which register
   reference to include.  

References df_exit_block_uses_collect(), and df_refs_add_to_chains().

static bool df_exit_block_bitmap_verify ( )
static
   Returns true if the exit block has correct and complete df_ref set.
   If not it either aborts if ABORT_IF_FAIL is true or returns false. 
static void df_exit_block_uses_collect ( struct df_collection_rec ,
bitmap   
)
static
static void df_exit_block_uses_collect ( )
static
   Return the refs of hard registers that are used in the exit block.
   It uses df->exit_block_uses to determine register to include.  
static void df_find_hard_reg_defs ( )
static
   Set bits in *DEFS for hard registers defined in the pattern X.  This
   has to match the logic in df_defs_record.  
         No DEFs to record in other cases 
static void df_find_hard_reg_defs_1 ( )
static
   Set bits in *DEFS for hard registers found in the rtx DST, which is the
   destination of a set or clobber.  This has to match the logic in
   df_defs_record_1.  
     It is legal to have a set destination be a parallel. 
     At this point if we do not have a reg or a subreg, just return.  

References DF_REF_SIGN_EXTRACT, DF_REF_ZERO_EXTRACT, and df_uses_record().

Referenced by df_read_modify_subreg_p().

static void df_free_collection_rec ( )
static
   Free all of the refs and the mw_hardregs in COLLECTION_REC.  
static void df_free_ref ( )
static

References df_d::def_info, df, and df_ref_info::refs.

static void df_get_call_refs ( struct df_collection_rec collection_rec,
basic_block  bb,
struct df_insn_info insn_info,
int  flags 
)
static
   Get call's extra defs and uses (track caller-saved registers). 
           The stack ptr is used (honorarily) by a CALL insn.  
             Calls to const functions cannot access any global registers and
             calls to pure functions cannot set them.  All other calls may
             reference any of the global registers, so they are recorded as
             used. 
                  no clobbers for regs that are the result of the call 
     Record the registers used to pass arguments, and explicitly
     noted as clobbered.  

References df_grow_insn_info(), df_insn_create_insn_record(), and df_insn_info::luid.

static void df_get_conditional_uses ( )
static
   For all DF_REF_CONDITIONAL defs, add a corresponding uses.  
static void df_get_eh_block_artificial_uses ( bitmap  )
static

Referenced by df_grow_insn_info().

static void df_get_eh_block_artificial_uses ( )
static
   Get the artificial use set for an eh block. 
     The following code (down through the arg_pointer setting APPEARS
     to be necessary because there is nothing that actually
     describes what the exception handling code may actually need
     to keep alive.  

References df_scan_bb_info::artificial_defs, bitmap_clear(), bitmap_copy(), bitmap_equal_p(), changed, df, df_bitmap_obstack, df_get_entry_block_def_set(), df_record_entry_block_defs(), df_ref_chain_delete(), df_ref_chain_delete_du_chain(), df_scan_get_bb_info(), df_set_bb_dirty(), df_d::entry_block_defs, refs, and df_scan_problem_data::reg_bitmaps.

static void df_get_entry_block_def_set ( bitmap  )
static
static void df_get_entry_block_def_set ( )
static
   Set the bit for regs that are considered being defined at the entry. 
     The always important stack pointer.  
     Once the prologue has been generated, all of these registers
     should just show up in the first regular block.  
         Defs for the callee saved registers are inserted so that the
         pushes have some defining location.  
     If the function has an incoming STATIC_CHAIN, it has to show up
     in the entry def set.  
         Any reference to any pseudo before reload is a potential
         reference of the frame pointer.  
         If they are different, also mark the hard frame pointer as live.  
     These registers are live everywhere.  
static void df_get_exit_block_use_set ( bitmap  )
static

Referenced by df_grow_insn_info().

static void df_get_exit_block_use_set ( )
static
   Set the bit for regs that are considered being used at the exit. 
     Stack pointer is always live at the exit.  
     Mark the frame pointer if needed at the end of the function.
     If we end up eliminating it, it will be removed from the live
     list of each basic block by reload.  
         If they are different, also mark the hard frame pointer as live.  
     Many architectures have a GP register even without flag_pic.
     Assume the pic register is not in use, or will be handled by
     other means, if it is not fixed.  
     Mark all global registers, and all registers used by the
     epilogue as being live at the end of the function since they
     may be referenced by our caller.  
         Mark all call-saved registers that we actually used.  
     Mark function return value.  

References df_insn_rescan(), df_update_entry_block_defs(), and df_update_exit_block_uses().

static void df_get_regular_block_artificial_uses ( bitmap  )
static

Referenced by df_grow_insn_info().

static void df_get_regular_block_artificial_uses ( )
static
   Get the artificial use set for a regular (i.e. non-exit/non-entry)
   block. 
       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 all-important stack pointer must always be live.  

References bitmap_set_bit().

static void df_grow_ref_info ( struct df_ref_info ,
unsigned  int 
)
static

Referenced by df_grow_ref_info().

static void df_grow_ref_info ( )
static
   Grow the ref information.  

References df_grow_ref_info(), and df_ref_info::total_size.

void df_grow_reg_info ( void  )
   First, grow the reg_info information.  If the current size is less than
   the number of pseudos, grow to 25% more than the number of
   pseudos.

   Second, assure that all of the slots up to max_reg_num have been
   filled with reg_info structures.  

Referenced by df_ref_change_reg_with_loc_1().

void df_hard_reg_init ( void  )
   Initialize some platform specific structures.  
     Record which registers will be eliminated.  We use this in
     mark_used_regs.  
unsigned int df_hard_reg_used_count ( )
   A count of the number of times REG is actually used in the some
   instruction.  There are a fair number of conditions that affect the
   setting of this array.  See the comment in df.h for
   df->hard_regs_live_count for the conditions that this array is
   set. 
bool df_hard_reg_used_p ( )
   Return true if hard REG is actually used in the some instruction.
   There are a fair number of conditions that affect the setting of
   this array.  See the comment in df.h for df->hard_regs_live_count
   for the conditions that this array is set. 

References df_insn_refs_collect().

void df_insn_change_bb ( )
   Change all of the basic block references in INSN to use the insn's
   current basic block.  This function is called from routines that move
   instructions from one block to another.  

Referenced by make_pass_free_cfg().

struct df_insn_info* df_insn_create_insn_record ( )
read
   Create the insn record for INSN.  If there was one there, zero it
   out.  

References df_reg_chain_unlink(), and free().

Referenced by df_get_call_refs(), and df_live_free_bb_info().

void df_insn_delete ( )
   Delete all of the refs information from INSN, either right now
   or marked for later in deferred mode.  
     ??? bb can be NULL after pass_free_cfg.  At that point, DF should
     not exist anymore (as mentioned in df-core.c: "The only requirement
     [for DF] is that there be a correct control flow graph."  Clearly
     that isn't the case after pass_free_cfg.  But DF is freed much later
     because some back-ends want to use DF info even though the CFG is
     already gone.  It's not clear to me whether that is safe, actually.
     In any case, we expect BB to be non-NULL at least up to register
     allocation, so disallow a non-NULL BB up to there.  Not perfect
     but better than nothing...  
     The block must be marked as dirty now, rather than later as in
     df_insn_rescan and df_notes_rescan because it may not be there at
     rescanning time and the mark would blow up.
     DEBUG_INSNs do not make a block's data flow solution dirty (at
     worst the LUIDs are no longer contiguous).  
     The client has deferred rescanning.  
static void df_insn_info_delete ( unsigned  int)
static
static void df_insn_info_delete ( )
static
   Delete all of the refs information from the insn with UID.
   Internal helper for df_insn_delete, df_insn_rescan, and other
   df-scan routines that don't have to work in deferred mode
   and do not have to mark basic blocks for re-processing.  
         In general, notes do not have the insn_info fields
         initialized.  However, combine deletes insns by changing them
         to notes.  How clever.  So we cannot just check if it is a
         valid insn before short circuiting this code, we need to see
         if we actually initialized it.  
static void df_insn_refs_collect ( struct df_collection_rec collection_rec,
basic_block  bb,
struct df_insn_info insn_info 
)
static
   Collect all refs in the INSN. This function is free of any
   side-effect - it will create and return a lists of df_ref's in the
   COLLECTION_REC without putting those refs into existing ref chains
   and reg chains. 
     Clear out the collection record.  
     Process REG_EQUIV/REG_EQUAL notes.  
             The frame ptr is used by a non-local goto.  
     For CALL_INSNs, first record DF_REF_BASE register defs, as well as
     uses from CALL_INSN_FUNCTION_USAGE. 
     Record other defs.  These should be mostly for DF_REF_REGULAR, so
     that a qsort on the defs is unnecessary in most cases.  
     Record the register uses.  
     DF_REF_CONDITIONAL needs corresponding USES. 

Referenced by df_hard_reg_used_p().

static bool df_insn_refs_verify ( struct df_collection_rec collection_rec,
basic_block  bb,
rtx  insn,
bool  abort_if_fail 
)
static
   Return true if the existing insn refs information is complete and
   correct. Otherwise (i.e. if there's any missing or extra refs),
   return the correct df_ref chain in REFS_RETURN.

   If ABORT_IF_FAIL, leave the refs that are verified (already in the
   ref chain) as DF_REF_MARKED(). If it's false, then it's a per-insn
   verification mode instead of the whole function, so unmark
   everything.

   If ABORT_IF_FAIL is set, this function never returns false.  
         The insn_rec was created but it was never filled out.  
     Unfortunately we cannot opt out early if one of these is not
     right because the marks will not get cleared.  
bool df_insn_rescan ( )
   Rescan INSN.  Return TRUE if the rescanning produced any changes.  
     The client has disabled rescanning and plans to do it itself.  
     The client has deferred rescanning.  
         If there's no change, return false. 
         There's change - we need to delete the existing info.
         Since the insn isn't moved, we can salvage its LUID.  

Referenced by df_get_exit_block_use_set(), df_insn_rescan_debug_internal(), and resolve_clobber().

void df_insn_rescan_all ( void  )
   Rescan all of the insns in the function.  Note that the artificial
   uses and defs are not touched.  This function will destroy def-use
   or use-def chains.  
static struct df_mw_hardreg** df_install_mws ( )
staticread
   This function takes the mws installs the entire group into the
   insn.  
static void df_install_ref ( df_ref  this_ref,
struct df_reg_info reg_info,
struct df_ref_info ref_info,
bool  add_to_table 
)
static
   Add the new df_ref to appropriate reg_info/ref_info chains.  
     Add the ref to the reg_{def,use,eq_use} chain.  
     We cannot actually link to the head of the chain.  
         Add the ref to the big array of defs.  

References count, df_null_mw_rec, and memcpy().

static void df_install_ref_incremental ( df_ref  )
static
static void df_install_ref_incremental ( )
static
     Do not add if ref is not in the right blocks.  
     By adding the ref directly, df_insn_rescan my not find any
     differences even though the block will have changed.  So we need
     to mark the block dirty ourselves.  
static df_ref* df_install_refs ( basic_block  bb,
const vec< df_ref, va_heap > *  old_vec,
struct df_reg_info **  reg_info,
struct df_ref_info ref_info,
bool  is_notes 
)
static
   This function takes one of the groups of refs (defs, uses or
   eq_uses) and installs the entire group into the insn.  It also adds
   each of these refs into the appropriate chains.  
         Do not add if ref is not in the right blocks.  
static void df_mark_reg ( )
static
   Mark a register in SET.  Hard registers in large modes get all
   of their component registers set as well.  

References bitmap_clear(), bitmap_set_bit(), and reload_completed.

void df_maybe_reorganize_def_refs ( )
   If the def refs in DF are not organized, reorganize them.  
void df_maybe_reorganize_use_refs ( )
   If the use refs in DF are not organized, reorganize them.  
static int df_mw_compare ( const void *  ,
const void *   
)
static
static int df_mw_compare ( )
static
   Compare MW1 and MW2 for sorting.  

References df, and df_d::hard_regs_live_count.

static bool df_mw_equal_p ( )
static
   Return true if the contents of two df_ref's are identical.
   It ignores DF_REF_MARKER.  
static void df_mw_hardreg_chain_delete ( )
static
static unsigned int df_mw_hardreg_chain_delete_eq_uses ( )
static
   Delete the mw_hardregs that point into the eq_notes.  
             Shove the remaining ones down one to fill the gap.  While
             this looks n**2, it is highly unusual to have any mw regs
             in eq_notes and the chances of more than one are almost
             non existent.  
static bool df_mws_verify ( const vec< df_mw_hardreg_ptr, va_heap > *  new_rec,
struct df_mw_hardreg **  old_rec,
bool  abort_if_fail 
)
static
   Verify that NEW_REC and OLD_REC have exactly the same members. 

References df_reg_chain_verify_unmarked().

void df_notes_rescan ( )
   Rescan only the REG_EQUIV/REG_EQUAL notes part of INSN.  
     The client has disabled rescanning and plans to do it itself.  
     Do nothing if the insn hasn't been emitted yet.  
     The client has deferred rescanning.  
         If the insn is set to be rescanned, it does not need to also
         be notes rescanned.  
         Process REG_EQUIV/REG_EQUAL notes 
         Find some place to put any new mw_hardregs.  
                 Append to the end of the existing record after
                 expanding it if necessary.  
                 No vector there. 

Referenced by emit_call_insn_before_setloc().

void df_process_deferred_rescans ( void  )
   Process all of the deferred rescans or deletions.  
     If someone changed regs_ever_live during this pass, fix up the
     entry and exit blocks.  
bool df_read_modify_subreg_p ( )
   A set to a non-paradoxical SUBREG for which the number of word_mode units
   covered by the outer mode is smaller than that covered by the inner mode,
   is a read-modify-write operation.
   This function returns true iff the SUBREG X is such a SUBREG.  

References df_find_hard_reg_defs_1().

Referenced by mark_hard_reg_live().

void df_recompute_luids ( )
   Recompute the luids for the insns in BB.  
     Scan the block an insn at a time from beginning to end.  
         Inserting labels does not always trigger the incremental
         rescanning.  
static void df_record_entry_block_defs ( bitmap  )
static
static void df_record_entry_block_defs ( )
static
   Record the (conservative) set of hard registers that are defined on
   entry to the function.  
     Process bb_refs chain 

References df_scan_bb_info::artificial_uses, bitmap_equal_p(), df, df_ref_chain_delete(), df_ref_chain_delete_du_chain(), df_scan_get_bb_info(), and df_d::exit_block_uses.

static void df_record_exit_block_uses ( bitmap  )
static

Referenced by df_grow_insn_info().

static void df_record_exit_block_uses ( )
static
   Record the set of hard registers that are used in the exit block.
   It uses df->exit_block_uses to determine which bit to include.  
     Process bb_refs chain 
static void df_ref_chain_delete ( df_ref )
static
static void df_ref_chain_delete ( )
static
   Delete all refs in the ref chain.  
     If the list is empty, it has a special shared element that is not
     to be deleted.  

References bitmap_clear_bit(), df_insn_info::defs, df, df_mw_hardreg_chain_delete(), df_d::insns_to_delete, df_d::insns_to_notes_rescan, df_d::insns_to_rescan, and df_insn_info::mw_hardregs.

static void df_ref_chain_delete_du_chain ( df_ref )
static
static void df_ref_chain_delete_du_chain ( )
static
   Delete all du chain (DF_REF_CHAIN()) of all refs in the ref chain.  
         CHAIN is allocated by DF_CHAIN. So make sure to
         pass df_scan instance for the problem.  

References df_scan_problem_data::mw_reg_pool, and pool_free().

void df_ref_change_reg_with_loc ( )
   Change the regno of all refs that contained LOC from OLD_REGNO to
   NEW_REGNO.  Refs that do not match LOC are not changed which means
   that artificial refs are not changed since they have no loc.  This
   call is to support the SET_REGNO macro. 
static void df_ref_change_reg_with_loc_1 ( struct df_reg_info old_df,
struct df_reg_info new_df,
int  new_regno,
rtx  loc 
)
static
   Helper function for df_ref_change_reg_with_loc.  
             Pull the_ref out of the old regno chain.  
             Put the ref into the new regno chain.  
             Need to sort the record again that the ref was in because
             the regno is a sorting key.  First, find the right
             record.  
             Find the length.  

References df, and df_grow_reg_info().

static int df_ref_compare ( const void *  ,
const void *   
)
static

Referenced by df_ref_equal_p().

static int df_ref_compare ( )
static
   Compare REF1 and REF2 for sorting.  This is only called from places
   where all of the refs are of the same type, in the same insn, and
   have the same bb.  So these fields are not checked.  
     Cannot look at the LOC field on artificial refs.  
         If two refs are identical except that one of them has is from
         a mw and one is not, we need to have the one with the mw
         first.  
static void df_ref_compress_rec ( )
static
df_ref df_ref_create ( rtx  reg,
rtx loc,
rtx  insn,
basic_block  bb,
enum df_ref_type  ref_type,
int  ref_flags 
)
   Create a new ref of type DF_REF_TYPE for register REG at address
   LOC within INSN of BB.  This function is only used externally.  
     You cannot hack artificial refs.  
static df_ref df_ref_create_structure ( enum df_ref_class  cl,
struct df_collection_rec collection_rec,
rtx  reg,
rtx loc,
basic_block  bb,
struct df_insn_info info,
enum df_ref_type  ref_type,
int  ref_flags 
)
static
   Allocate a ref and initialize its fields.  
     We need to clear this bit because fwprop, and in the future
     possibly other optimizations sometimes create new refs using ond
     refs as the model.  
     See if this ref needs to have DF_HARD_REG_LIVE bit set.  
static bool df_ref_equal_p ( )
static
   Return true if the contents of two df_ref's are identical.
   It ignores DF_REF_MARKER.  

References count, df_ref_compare(), and df_swap_refs().

static void df_ref_record ( enum df_ref_class  cl,
struct df_collection_rec collection_rec,
rtx  reg,
rtx loc,
basic_block  bb,
struct df_insn_info insn_info,
enum df_ref_type  ref_type,
int  ref_flags 
)
static
   Create new references of type DF_REF_TYPE for each part of register REG
   at address LOC within INSN of BB.  
          If this is a multiword hardreg, we create some extra
          datastructures that will enable us to easily build REG_DEAD
          and REG_UNUSED notes.  
             Sets to a subreg of a multiword register are partial.
             Sets to a non-subreg of a multiword register are not.  
void df_ref_remove ( )
   Unlink REF from all def-use/use-def chains, etc.  
     By deleting the ref directly, df_insn_rescan my not find any
     differences even though the block will have changed.  So we need
     to mark the block dirty ourselves.  
static void df_refs_add_to_chains ( struct df_collection_rec collection_rec,
basic_block  bb,
rtx  insn,
unsigned int  flags 
)
static
   Add a chain of df_refs to appropriate ref chain/reg_info/ref_info
   chains and update other necessary information.  
         If there is a vector in the collection rec, add it to the
         insn.  A null rec is a signal that the caller will handle the
         chain specially.  

References DF_HARD_REG_LIVE, DF_REF_MAY_CLOBBER, and elim_reg_set.

Referenced by df_entry_block_defs_collect().

static bool df_refs_verify ( const vec< df_ref, va_heap > *  new_rec,
df_ref old_rec,
bool  abort_if_fail 
)
static
   Verify that NEW_REC and OLD_REC have exactly the same members. 
         Abort if fail is called from the function level verifier.  If
         that is the context, mark this reg as being seem.  
static unsigned int df_reg_chain_mark ( df_ref  refs,
unsigned int  regno,
bool  is_def,
bool  is_eq_use 
)
static
@verbatim 

Mark all refs in the reg chain. Verify that all of the registers are in the correct chain.

         If there are no def-use or use-def chains, make sure that all
         of the chains are clear.  
         Check to make sure the ref is in the correct chain.  
static void df_reg_chain_unlink ( )
static
   Unlink and delete REF at the reg_use, reg_eq_use or reg_def chain.
   Also delete the def-use or use-def chain if it exists.  
     Delete any def-use or use-def chains that start here. It is
     possible that there is trash in this field.  This happens for
     insns that have been deleted when rescanning has been deferred
     and the chain problem has also been deleted.  The chain tear down
     code skips deleted insns.  
     Unlink from the reg chain.  If there is no prev, this is the
     first of the list.  If not, just join the next and prev.  

Referenced by df_insn_create_insn_record().

static void df_reg_chain_verify_unmarked ( )
static
   Verify that all of the registers in the chain are unmarked.  

Referenced by df_mws_verify().

bool df_regs_ever_live_p ( )
   Get the value of regs_ever_live[REGNO].  

Referenced by fprint_ul(), merge_overlapping_regs(), and reverse_equiv_p().

static void df_reorganize_refs_by_insn ( struct df_ref_info ref_info,
bool  include_defs,
bool  include_uses,
bool  include_eq_uses 
)
static
   Organize the refs by insn into the table in REF_INFO.  If
   blocks_to_analyze is defined, use that set, otherwise the entire
   program.  Include the defs if INCLUDE_DEFS. Include the uses if
   INCLUDE_USES. Include the eq_uses if INCLUDE_EQ_USES.  

Referenced by df_reorganize_refs_by_insn_bb().

static unsigned int df_reorganize_refs_by_insn_bb ( basic_block  bb,
unsigned int  offset,
struct df_ref_info ref_info,
bool  include_defs,
bool  include_uses,
bool  include_eq_uses 
)
static
static void df_reorganize_refs_by_reg ( struct df_ref_info ref_info,
bool  include_defs,
bool  include_uses,
bool  include_eq_uses 
)
static
   Take build ref table for either the uses or defs from the reg-use
   or reg-def chains.  

Referenced by df_reorganize_refs_by_insn_bb().

static void df_reorganize_refs_by_reg_by_insn ( struct df_ref_info ref_info,
bool  include_defs,
bool  include_uses,
bool  include_eq_uses 
)
static
   Take build ref table for either the uses or defs from the reg-use
   or reg-def chains.  This version processes the refs in insn order
   which is likely to be best if processing some segment of the
   function.  
     The bitmap size is not decremented when refs are deleted.  So
     reset it now that we have squished out all of the empty
     slots.  
static void df_reorganize_refs_by_reg_by_reg ( struct df_ref_info ref_info,
bool  include_defs,
bool  include_uses,
bool  include_eq_uses 
)
static
   Take build ref table for either the uses or defs from the reg-use
   or reg-def chains.  This version processes the refs in reg order
   which is likely to be best if processing the whole function.  
     The bitmap size is not decremented when refs are deleted.  So
     reset it now that we have squished out all of the empty
     slots.  
void df_scan_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 df_ref_info::begin, df_ref_info::count, df_d::def_info, df_d::def_regs, df, df_d::eq_use_regs, max_reg_num(), df_d::regs_size, df_d::use_info, and df_d::use_regs.

void df_scan_alloc ( )
   Allocate the problem data for the scanning problem.  This should be
   called when the problem is created or when the entire function is to
   be rescanned.  
     Given the number of pools, this is really faster than tearing
     everything apart.  

Referenced by duplicate_computed_gotos().

void df_scan_blocks ( void  )
   Rescan all of the block_to_analyze or all of the blocks in the
   function if df_set_blocks if blocks_to_analyze is NULL;  
     ENTRY and EXIT blocks have special defs/uses.  
     Regular blocks 

Referenced by duplicate_computed_gotos().

static void df_scan_free ( )
static
   Free all of the data associated with the scan problem.  

References df, df_print_regset(), df_d::hardware_regs_used, regs_invalidated_by_call_regset, and df_d::regular_block_artificial_uses.

static void df_scan_free_bb_info ( )
static
   Free basic block info.  
     See if bb_info is initialized.  
         Get rid of any artificial uses or defs.  
static void df_scan_free_internal ( )
static
   Internal function to shut down the scanning problem.  
     The vectors that hold the refs are not pool allocated because
     they come in many sizes.  This makes them impossible to delete
     all at once.  
         Skip the insns that have no insn_info or have been
         deleted.  
static void df_scan_start_block ( )
static
   Dump the bb_info for a given basic block. 
static void df_scan_start_dump ( )
static
   Dump the preamble for DF_SCAN dump. 
void df_scan_verify ( void  )
   Return true if df_ref information for all insns in all blocks are
   correct and complete.  
     Verification is a 4 step process. 
     (1) All of the refs are marked by going through the reg chains.  
     (2) There are various bitmaps whose value may change over the
     course of the compilation.  This step recomputes them to make
     sure that they have not slipped out of date.  
     Check artificial_uses bitmaps didn't change. 
     Verify entry block and exit block. These only verify the bitmaps,
     the refs are verified in df_bb_verify.  
     (3) All of the insns in all of the blocks are traversed and the
     marks are cleared both in the artificial refs attached to the
     blocks and the real refs inside the insns.  It is a failure to
     clear a mark that has not been set as this means that the ref in
     the block or insn was not in the reg chain.  
     (4) See if all reg chains are traversed a second time.  This time
     a check is made that the marks are clear. A set mark would be a
     from a reg that is not in any insn or basic block.  
void df_set_regs_ever_live ( )
   Set regs_ever_live[REGNO] to VALUE.  If this cause regs_ever_live
   to change, schedule that change for the next update.  

References df_scan_get_bb_info(), basic_block_def::index, and df_insn_info::insn.

Referenced by invoke_reorder_hooks().

static void df_sort_and_compress_mws ( )
static
   Sort and compress a set of refs.  
         Find the next ref that is not equal to the current ref.  
         Copy it down to the next position.  
static void df_sort_and_compress_refs ( )
static
   Sort and compress a set of refs.  
     If there are 1 or 0 elements, there is nothing to do.  
         If the array is already strictly ordered,
         which is the most common case for large COUNT case
         (which happens for CALL INSNs),
         no need to sort and filter out duplicate.
         Simply return the count.
         Make sure DF_GET_ADD_REFS adds refs in the increasing order
         of DF_REF_COMPARE.  
         Find the next ref that is not equal to the current ref.  
         Copy it down to the next position.  
static void df_swap_refs ( )
static

Referenced by df_ref_equal_p().

void df_update_entry_block_defs ( void  )
   Update the defs in the entry block.  

Referenced by df_get_exit_block_use_set().

void df_update_entry_exit_and_calls ( void  )
   Recompute the parts of scanning that are based on regs_ever_live
   because something changed in that array.  
     The call insns need to be rescanned because there may be changes
     in the set of registers clobbered across the call.  
void df_update_exit_block_uses ( void  )
   Update the uses in the exit block.  

Referenced by df_get_exit_block_use_set().

void df_uses_create ( )
   Create new refs under address LOC within INSN.  This function is
   only used externally.  REF_FLAGS must be either 0 or DF_REF_IN_NOTE,
   depending on whether LOC is inside PATTERN (INSN) or a note.  
static void df_uses_record ( struct df_collection_rec collection_rec,
rtx loc,
enum df_ref_type  ref_type,
basic_block  bb,
struct df_insn_info insn_info,
int  flags 
)
static
   Process all the registers used in the rtx at address LOC.  
         If we are clobbering a MEM, mark any registers inside the address
         as being used.  
         If we're clobbering a REG then we have a def so ignore.  
         While we're here, optimize this case.  
         In case the SUBREG is not of a REG, do not optimize.  
         ... Fall through ...  
           If the parameters to the zero or sign extract are
           constants, strip them off and recurse, otherwise there is
           no information that we can gain from this operation.  
                 Fall through.  
                   A strict_low_part uses the whole REG and not just the
                 SUBREG.  
           Traditional and volatile asm instructions must be
           considered to use and clobber all hard registers, all
           pseudo-registers and all of memory.  So must TRAP_IF and
           UNSPEC_VOLATILE operations.

           Consider for instance a volatile asm that changes the fpu
           rounding mode.  An insn should not be moved across this
           even if it only uses pseudo-regs because it might give an
           incorrectly rounded result.

           However, flow.c's liveness computation did *not* do this,
           giving the reasoning as " ?!? Unfortunately, marking all
           hard registers as live causes massive problems for the
           register allocator and marking all pseudos as live creates
           mountains of uninitialized variable warnings."

           In order to maintain the status quo with regard to liveness
           and uses, we do what flow.c did and just mark any regs we
           can find in ASM_OPERANDS as used.  In global asm insns are
           scanned and regs_asm_clobbered is filled out.

           For all ASM_OPERANDS, we must traverse the vector of input
           operands.  We can not just fall through here since then we
           would be confused by the ASM_INPUT rtx inside ASM_OPERANDS,
           which do not indicate traditional asms unlike their normal
           usage.  
         Catch the def of the register being modified.  
         ... Fall through to handle uses ...  
     Recursively scan the operands of this expression.  
               Tail recursive case: save a function call level.  

Referenced by df_find_hard_reg_defs_1().


Variable Documentation

const unsigned int copy_all
static
Initial value:
const unsigned int copy_defs = 0x1
static
   Flags used to tell df_refs_add_to_chains() which vectors it should copy. 
const unsigned int copy_eq_uses = 0x4
static
const unsigned int copy_mw = 0x8
static
const unsigned int copy_uses = 0x2
static
struct df_mw_hardreg* df_null_mw_rec[1]
static

Referenced by df_install_ref().

df_ref df_null_ref_rec[1]
static
HARD_REG_SET elim_reg_set
static
   The set of hard registers in eliminables[i].from. 

Referenced by df_refs_add_to_chains().

bool initialized = false
static
struct df_problem problem_SCAN
static
Initial value:
{
DF_SCAN,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
sizeof (struct df_scan_bb_info),
TV_DF_SCAN,
false
}
bool regs_ever_live[FIRST_PSEUDO_REGISTER]
static
   Indexed by hardware reg number, is true if that register is ever
   used in the current function.

   In df-scan.c, this is set up to record the hard regs used
   explicitly.  Reload adds in the hard regs used for holding pseudo
   regs.  Final uses it to generate the code in the function prologue
   and epilogue to save and restore registers as needed.