DF_DU_CHAIN = 1, /* Build DU chains. */ DF_UD_CHAIN = 2 /* Build UD chains. */ }; enum df_scan_flags { /* Flags for the SCAN problem. */ DF_SCAN_EMPTY_ENTRY_EXIT = 1 /* Don't define any registers in the entry block; don't use any in the exit block. */ }; enum df_changeable_flags { /* Scanning flags. */ /* Flag to control the running of dce as a side effect of building LR. */ DF_LR_RUN_DCE = 1 << 0, /* Run DCE. */ DF_NO_HARD_REGS = 1 << 1, /* Skip hard registers in RD and CHAIN Building. */ DF_EQ_NOTES = 1 << 2, /* Build chains with uses present in EQUIV/EQUAL notes. */ DF_NO_REGS_EVER_LIVE = 1 << 3, /* Do not compute the regs_ever_live. */ /* Cause df_insn_rescan df_notes_rescan and df_insn_delete, to return immediately. This is used by passes that know how to update the scanning them selves. */ DF_NO_INSN_RESCAN = 1 << 4, /* Cause df_insn_rescan df_notes_rescan and df_insn_delete, to return after marking the insn for later processing. This allows all rescans to be batched. */ DF_DEFER_INSN_RESCAN = 1 << 5, /* Compute the reaching defs problem as "live and reaching defs" (LR&RD). A DEF is reaching and live at insn I if DEF reaches I and REGNO(DEF) is in LR_IN of the basic block containing I. */ DF_RD_PRUNE_DEAD_DEFS = 1 << 6, DF_VERIFY_SCHEDULED = 1 << 7 }; /* Two of these structures are inline in df, one for the uses and one for the defs. This structure is only contains the refs within the boundary of the df_set_blocks if that has been defined. */ struct df_ref_info { df_ref *refs; /* Ref table, indexed by id. */ unsigned int *begin; /* First ref_index for this pseudo. */ unsigned int *count; /* Count of refs for this pseudo. */ unsigned int refs_size; /* Size of currently allocated refs table. */ /* Table_size is the number of elements in the refs table. This will also be the width of the bitvectors in the rd and ru problems. Total_size is the number of refs. These will be the same if the focus has not been reduced by df_set_blocks. If the focus has been reduced, table_size will be smaller since it only contains the refs in the set blocks. */ unsigned int table_size; unsigned int total_size; enum df_ref_order ref_order; }; /* Three of these structures are allocated for every pseudo reg. One for the uses, one for the eq_uses and one for the defs. */ struct df_reg_info { /* Head of chain for refs of that type and regno. */ df_ref reg_chain; /* Number of refs in the chain. */ unsigned int n_refs; }; /*---------------------------------------------------------------------------- Problem data for the scanning dataflow problem. Unlike the other dataflow problems, the problem data for scanning is fully exposed and used by owners of the problem. ----------------------------------------------------------------------------*/ struct df_d { /* The set of problems to be solved is stored in two arrays. In PROBLEMS_IN_ORDER, the problems are stored in the order that they are solved. This is an internally dense array that may have nulls at the end of it. In PROBLEMS_BY_INDEX, the problem is stored by the value in df_problem.id. These are used to access the problem local data without having to search the first array. */ struct dataflow *problems_in_order[DF_LAST_PROBLEM_PLUS1]; struct dataflow *problems_by_index[DF_LAST_PROBLEM_PLUS1]; /* If not NULL, this subset of blocks of the program to be considered for analysis. At certain times, this will contain all the blocks in the function so it cannot be used as an indicator of if we are analyzing a subset. See analyze_subset. */ bitmap blocks_to_analyze; /* The following information is really the problem data for the scanning instance but it is used too often by the other problems to keep getting it from there. */ struct df_ref_info def_info; /* Def info. */ struct df_ref_info use_info; /* Use info. */ /* The following three arrays are allocated in parallel. They contain the sets of refs of each type for each reg. */ struct df_reg_info **def_regs; /* Def reg info. */ struct df_reg_info **use_regs; /* Eq_use reg info. */ struct df_reg_info **eq_use_regs; /* Eq_use info. */ unsigned int regs_size; /* Size of currently allocated regs table. */ unsigned int regs_inited; /* Number of regs with reg_infos allocated. */ struct df_insn_info **insns; /* Insn table, indexed by insn UID. */ unsigned int insns_size; /* Size of insn table. */ int num_problems_defined; bitmap_head hardware_regs_used; /* The set of hardware registers used. */ /* The set of hard regs that are in the artificial uses at the end of a regular basic block. */ bitmap_head regular_block_artificial_uses; /* The set of hard regs that are in the artificial uses at the end of a basic block that has an EH pred. */ bitmap_head eh_block_artificial_uses; /* The set of hardware registers live on entry to the function. */ bitmap entry_block_defs; bitmap exit_block_uses; /* The set of hardware registers used in exit block. */ /* Insns to delete, rescan or reprocess the notes at next df_rescan_all or df_process_deferred_rescans. */ bitmap_head insns_to_delete; bitmap_head insns_to_rescan; bitmap_head insns_to_notes_rescan; int *postorder; /* The current set of basic blocks in reverse postorder. */ vec postorder_inverted; /* The current set of basic blocks in reverse postorder of inverted CFG. */ int n_blocks; /* The number of blocks in reverse postorder. */ /* An array [FIRST_PSEUDO_REGISTER], indexed by regno, of the number of refs that qualify as being real hard regs uses. Artificial uses and defs as well as refs in eq notes are ignored. If the ref is a def, it cannot be a MAY_CLOBBER def. If the ref is a use, it cannot be the emim_reg_set or be the frame or arg pointer register. Uses in debug insns are ignored. IT IS NOT ACCEPTABLE TO MANUALLY CHANGE THIS ARRAY. This array always reflects the actual number of refs in the insn stream that satisfy the above criteria. */ unsigned int *hard_regs_live_count; /* This counter provides a way to totally order refs without using addresses. It is incremented whenever a ref is created. */ unsigned int ref_order; /* Problem specific control information. This is a combination of enum df_changeable_flags values. */ int changeable_flags : 8; /* If this is true, then only a subset of the blocks of the program is considered to compute the solutions of dataflow problems. */ bool analyze_subset; /* True if someone added or deleted something from regs_ever_live so that the entry and exit blocks need be reprocessed. */ bool redo_entry_and_exit; }; #define DF_SCAN_BB_INFO(BB) (df_scan_get_bb_info ((BB)->index)) #define DF_RD_BB_INFO(BB) (df_rd_get_bb_info ((BB)->index)) #define DF_LR_BB_INFO(BB) (df_lr_get_bb_info ((BB)->index)) #define DF_LIVE_BB_INFO(BB) (df_live_get_bb_info ((BB)->index)) #define DF_WORD_LR_BB_INFO(BB) (df_word_lr_get_bb_info ((BB)->index)) #define DF_MD_BB_INFO(BB) (df_md_get_bb_info ((BB)->index)) #define DF_MIR_BB_INFO(BB) (df_mir_get_bb_info ((BB)->index)) /* Most transformations that wish to use live register analysis will use these macros. This info is the and of the lr and live sets. */ #define DF_LIVE_IN(BB) (&DF_LIVE_BB_INFO (BB)->in) #define DF_LIVE_OUT(BB) (&DF_LIVE_BB_INFO (BB)->out) #define DF_MIR_IN(BB) (&DF_MIR_BB_INFO (BB)->in) #define DF_MIR_OUT(BB) (&DF_MIR_BB_INFO (BB)->out) /* These macros are used by passes that are not tolerant of uninitialized variables. This intolerance should eventually be fixed. */ #define DF_LR_IN(BB) (&DF_LR_BB_INFO (BB)->in) #define DF_LR_OUT(BB) (&DF_LR_BB_INFO (BB)->out) /* These macros are used by passes that are not tolerant of uninitialized variables. This intolerance should eventually be fixed. */ #define DF_WORD_LR_IN(BB) (&DF_WORD_LR_BB_INFO (BB)->in) #define DF_WORD_LR_OUT(BB) (&DF_WORD_LR_BB_INFO (BB)->out) /* Macros to access the elements within the ref structure. */ #define DF_REF_REAL_REG(REF) (GET_CODE ((REF)->base.reg) == SUBREG \ ? SUBREG_REG ((REF)->base.reg) : ((REF)->base.reg)) #define DF_REF_REGNO(REF) ((REF)->base.regno) #define DF_REF_REAL_LOC(REF) (GET_CODE (*((REF)->regular_ref.loc)) == SUBREG \ ? &SUBREG_REG (*((REF)->regular_ref.loc)) : ((REF)->regular_ref.loc)) #define DF_REF_REG(REF) ((REF)->base.reg) #define DF_REF_LOC(REF) (DF_REF_CLASS (REF) == DF_REF_REGULAR ? \ (REF)->regular_ref.loc : NULL) #define DF_REF_BB(REF) (DF_REF_IS_ARTIFICIAL (REF) \ ? (REF)->artificial_ref.bb \ : BLOCK_FOR_INSN (DF_REF_INSN (REF))) #define DF_REF_BBNO(REF) (DF_REF_BB (REF)->index) #define DF_REF_INSN_INFO(REF) ((REF)->base.insn_info) #define DF_REF_INSN(REF) ((REF)->base.insn_info->insn) #define DF_REF_INSN_UID(REF) (INSN_UID (DF_REF_INSN(REF))) #define DF_REF_CLASS(REF) ((REF)->base.cl) #define DF_REF_TYPE(REF) ((REF)->base.type) #define DF_REF_CHAIN(REF) ((REF)->base.chain) #define DF_REF_ID(REF) ((REF)->base.id) #define DF_REF_FLAGS(REF) ((REF)->base.flags) #define DF_REF_FLAGS_IS_SET(REF, v) ((DF_REF_FLAGS (REF) & (v)) != 0) #define DF_REF_FLAGS_SET(REF, v) (DF_REF_FLAGS (REF) |= (v)) #define DF_REF_FLAGS_CLEAR(REF, v) (DF_REF_FLAGS (REF) &= ~(v)) #define DF_REF_ORDER(REF) ((REF)->base.ref_order) /* If DF_REF_IS_ARTIFICIAL () is true, this is not a real definition/use, but an artificial one created to model always live registers, eh uses, etc. */ #define DF_REF_IS_ARTIFICIAL(REF) (DF_REF_CLASS (REF) == DF_REF_ARTIFICIAL) #define DF_REF_REG_MARK(REF) (DF_REF_FLAGS_SET ((REF),DF_REF_REG_MARKER)) #define DF_REF_REG_UNMARK(REF) (DF_REF_FLAGS_CLEAR ((REF),DF_REF_REG_MARKER)) #define DF_REF_IS_REG_MARKED(REF) (DF_REF_FLAGS_IS_SET ((REF),DF_REF_REG_MARKER)) #define DF_REF_NEXT_LOC(REF) ((REF)->base.next_loc) #define DF_REF_NEXT_REG(REF) ((REF)->base.next_reg) #define DF_REF_PREV_REG(REF) ((REF)->base.prev_reg) /* The following two macros may only be applied if one of DF_REF_SIGN_EXTRACT | DF_REF_ZERO_EXTRACT is true. */ #define DF_REF_EXTRACT_WIDTH(REF) ((REF)->extract_ref.width) #define DF_REF_EXTRACT_OFFSET(REF) ((REF)->extract_ref.offset) #define DF_REF_EXTRACT_MODE(REF) ((REF)->extract_ref.mode) /* Macros to determine the reference type. */ #define DF_REF_REG_DEF_P(REF) (DF_REF_TYPE (REF) == DF_REF_REG_DEF) #define DF_REF_REG_USE_P(REF) (!DF_REF_REG_DEF_P (REF)) #define DF_REF_REG_MEM_STORE_P(REF) (DF_REF_TYPE (REF) == DF_REF_REG_MEM_STORE) #define DF_REF_REG_MEM_LOAD_P(REF) (DF_REF_TYPE (REF) == DF_REF_REG_MEM_LOAD) #define DF_REF_REG_MEM_P(REF) (DF_REF_REG_MEM_STORE_P (REF) \ || DF_REF_REG_MEM_LOAD_P (REF)) #define DF_MWS_REG_DEF_P(MREF) (DF_MWS_TYPE (MREF) == DF_REF_REG_DEF) #define DF_MWS_REG_USE_P(MREF) (!DF_MWS_REG_DEF_P (MREF)) #define DF_MWS_NEXT(MREF) ((MREF)->next) #define DF_MWS_TYPE(MREF) ((MREF)->type) /* Macros to get the refs out of def_info or use_info refs table. If the focus of the dataflow has been set to some subset of blocks with df_set_blocks, these macros will only find the uses and defs in that subset of blocks. These macros should be used with care. The def macros are only usable after a call to df_maybe_reorganize_def_refs and the use macros are only usable after a call to df_maybe_reorganize_use_refs. HOWEVER, BUILDING AND USING THESE ARRAYS ARE A CACHE LOCALITY KILLER. */ #define DF_DEFS_TABLE_SIZE() (df->def_info.table_size) #define DF_DEFS_GET(ID) (df->def_info.refs[(ID)]) #define DF_DEFS_SET(ID,VAL) (df->def_info.refs[(ID)]=(VAL)) #define DF_DEFS_COUNT(ID) (df->def_info.count[(ID)]) #define DF_DEFS_BEGIN(ID) (df->def_info.begin[(ID)]) #define DF_USES_TABLE_SIZE() (df->use_info.table_size) #define DF_USES_GET(ID) (df->use_info.refs[(ID)]) #define DF_USES_SET(ID,VAL) (df->use_info.refs[(ID)]=(VAL)) #define DF_USES_COUNT(ID) (df->use_info.count[(ID)]) #define DF_USES_BEGIN(ID) (df->use_info.begin[(ID)]) /* Macros to access the register information from scan dataflow record. */ #define DF_REG_SIZE(DF) (df->regs_inited) #define DF_REG_DEF_GET(REG) (df->def_regs[(REG)]) #define DF_REG_DEF_CHAIN(REG) (df->def_regs[(REG)]->reg_chain) #define DF_REG_DEF_COUNT(REG) (df->def_regs[(REG)]->n_refs) #define DF_REG_USE_GET(REG) (df->use_regs[(REG)]) #define DF_REG_USE_CHAIN(REG) (df->use_regs[(REG)]->reg_chain) #define DF_REG_USE_COUNT(REG) (df->use_regs[(REG)]->n_refs) #define DF_REG_EQ_USE_GET(REG) (df->eq_use_regs[(REG)]) #define DF_REG_EQ_USE_CHAIN(REG) (df->eq_use_regs[(REG)]->reg_chain) #define DF_REG_EQ_USE_COUNT(REG) (df->eq_use_regs[(REG)]->n_refs) /* Macros to access the elements within the reg_info structure table. */ #define DF_REGNO_FIRST_DEF(REGNUM) \ (DF_REG_DEF_GET(REGNUM) ? DF_REG_DEF_GET (REGNUM) : 0) #define DF_REGNO_LAST_USE(REGNUM) \ (DF_REG_USE_GET(REGNUM) ? DF_REG_USE_GET (REGNUM) : 0) /* Macros to access the elements within the insn_info structure table. */ #define DF_INSN_SIZE() ((df)->insns_size) #define DF_INSN_INFO_GET(INSN) (df->insns[(INSN_UID (INSN))]) #define DF_INSN_INFO_SET(INSN,VAL) (df->insns[(INSN_UID (INSN))]=(VAL)) #define DF_INSN_INFO_LUID(II) ((II)->luid) #define DF_INSN_INFO_DEFS(II) ((II)->defs) #define DF_INSN_INFO_USES(II) ((II)->uses) #define DF_INSN_INFO_EQ_USES(II) ((II)->eq_uses) #define DF_INSN_INFO_MWS(II) ((II)->mw_hardregs) #define DF_INSN_LUID(INSN) (DF_INSN_INFO_LUID (DF_INSN_INFO_GET (INSN))) #define DF_INSN_DEFS(INSN) (DF_INSN_INFO_DEFS (DF_INSN_INFO_GET (INSN))) #define DF_INSN_USES(INSN) (DF_INSN_INFO_USES (DF_INSN_INFO_GET (INSN))) #define DF_INSN_EQ_USES(INSN) (DF_INSN_INFO_EQ_USES (DF_INSN_INFO_GET (INSN))) #define DF_INSN_UID_GET(UID) (df->insns[(UID)]) #define DF_INSN_UID_SET(UID,VAL) (df->insns[(UID)]=(VAL)) #define DF_INSN_UID_SAFE_GET(UID) (((unsigned)(UID) < DF_INSN_SIZE ()) \ ? DF_INSN_UID_GET (UID) \ : NULL) #define DF_INSN_UID_LUID(INSN) (DF_INSN_UID_GET (INSN)->luid) #define DF_INSN_UID_DEFS(INSN) (DF_INSN_UID_GET (INSN)->defs) #define DF_INSN_UID_USES(INSN) (DF_INSN_UID_GET (INSN)->uses) #define DF_INSN_UID_EQ_USES(INSN) (DF_INSN_UID_GET (INSN)->eq_uses) #define DF_INSN_UID_MWS(INSN) (DF_INSN_UID_GET (INSN)->mw_hardregs) #define FOR_EACH_INSN_INFO_DEF(ITER, INSN) \ for (ITER = DF_INSN_INFO_DEFS (INSN); ITER; ITER = DF_REF_NEXT_LOC (ITER)) #define FOR_EACH_INSN_INFO_USE(ITER, INSN) \ for (ITER = DF_INSN_INFO_USES (INSN); ITER; ITER = DF_REF_NEXT_LOC (ITER)) #define FOR_EACH_INSN_INFO_EQ_USE(ITER, INSN) \ for (ITER = DF_INSN_INFO_EQ_USES (INSN); ITER; ITER = DF_REF_NEXT_LOC (ITER)) #define FOR_EACH_INSN_INFO_MW(ITER, INSN) \ for (ITER = DF_INSN_INFO_MWS (INSN); ITER; ITER = DF_MWS_NEXT (ITER)) #define FOR_EACH_INSN_DEF(ITER, INSN) \ FOR_EACH_INSN_INFO_DEF(ITER, DF_INSN_INFO_GET (INSN)) #define FOR_EACH_INSN_USE(ITER, INSN) \ FOR_EACH_INSN_INFO_USE(ITER, DF_INSN_INFO_GET (INSN)) #define FOR_EACH_INSN_EQ_USE(ITER, INSN) \ FOR_EACH_INSN_INFO_EQ_USE(ITER, DF_INSN_INFO_GET (INSN)) #define FOR_EACH_ARTIFICIAL_USE(ITER, BB_INDEX) \ for (ITER = df_get_artificial_uses (BB_INDEX); ITER; \ ITER = DF_REF_NEXT_LOC (ITER)) #define FOR_EACH_ARTIFICIAL_DEF(ITER, BB_INDEX) \ for (ITER = df_get_artificial_defs (BB_INDEX); ITER; \ ITER = DF_REF_NEXT_LOC (ITER)) /* An obstack for bitmap not related to specific dataflow problems. This obstack should e.g. be used for bitmaps with a short life time such as temporary bitmaps. This obstack is declared in df-core.c. */ extern bitmap_obstack df_bitmap_obstack; /* One of these structures is allocated for every basic block. */ struct df_scan_bb_info { /* The entry block has many artificial defs and these are at the bottom of the block. Blocks that are targets of exception edges may have some artificial defs. These are logically located at the top of the block. Blocks that are the targets of non-local goto's have the hard frame pointer defined at the top of the block. */ df_ref artificial_defs; /* Blocks that are targets of exception edges may have some artificial uses. These are logically at the top of the block. Most blocks have artificial uses at the bottom of the block. */ df_ref artificial_uses; }; /* Reaching definitions. All bitmaps are indexed by the id field of the ref except sparse_kill which is indexed by regno. For the LR&RD problem, the kill set is not complete: It does not contain DEFs killed because the set register has died in the LR set. */ struct df_rd_bb_info { /* Local sets to describe the basic blocks. */ bitmap_head kill; bitmap_head sparse_kill; bitmap_head gen; /* The set of defs generated in this block. */ /* The results of the dataflow problem. */ bitmap_head in; /* At the top of the block. */ bitmap_head out; /* At the bottom of the block. */ }; /* Multiple reaching definitions. All bitmaps are referenced by the register number. */ struct df_md_bb_info { /* Local sets to describe the basic blocks. */ bitmap_head gen; /* Partial/conditional definitions live at BB out. */ bitmap_head kill; /* Other definitions that are live at BB out. */ bitmap_head init; /* Definitions coming from dominance frontier edges. */ /* The results of the dataflow problem. */ bitmap_head in; /* Just before the block itself. */ bitmap_head out; /* At the bottom of the block. */ }; /* Live registers, a backwards dataflow problem. All bitmaps are referenced by the register number. */ struct df_lr_bb_info { /* Local sets to describe the basic blocks. */ bitmap_head def; /* The set of registers set in this block - except artificial defs at the top. */ bitmap_head use; /* The set of registers used in this block. */ /* The results of the dataflow problem. */ bitmap_head in; /* Just before the block itself. */ bitmap_head out; /* At the bottom of the block. */ }; /* Uninitialized registers. All bitmaps are referenced by the register number. Anded results of the forwards and backward live info. Note that the forwards live information is not available separately. */ struct df_live_bb_info { /* Local sets to describe the basic blocks. */ bitmap_head kill; /* The set of registers unset in this block. Calls, for instance, unset registers. */ bitmap_head gen; /* The set of registers set in this block. */ /* The results of the dataflow problem. */ bitmap_head in; /* At the top of the block. */ bitmap_head out; /* At the bottom of the block. */ }; /* Live registers, a backwards dataflow problem. These bitmaps are indexed by 2 * regno for each pseudo and have two entries for each pseudo. Only pseudos that have a size of 2 * UNITS_PER_WORD are meaningfully tracked. */ struct df_word_lr_bb_info { /* Local sets to describe the basic blocks. */ bitmap_head def; /* The set of registers set in this block - except artificial defs at the top. */ bitmap_head use; /* The set of registers used in this block. */ /* The results of the dataflow problem. */ bitmap_head in; /* Just before the block itself. */ bitmap_head out; /* At the bottom of the block. */ }; /* Must-initialized registers. All bitmaps are referenced by the register number. */ struct df_mir_bb_info { /* Local sets to describe the basic blocks. */ bitmap_head kill; /* The set of registers unset in this block. Calls, for instance, unset registers. */ bitmap_head gen; /* The set of registers set in this block, excluding the ones killed later on in this block. */ /* The results of the dataflow problem. */ bitmap_head in; /* At the top of the block. */ bitmap_head out; /* At the bottom of the block. */ }; /* This is used for debugging and for the dumpers to find the latest instance so that the df info can be added to the dumps. This should not be used by regular code. */ extern struct df_d *df; #define df_scan (df->problems_by_index[DF_SCAN]) #define df_rd (df->problems_by_index[DF_RD]) #define df_lr (df->problems_by_index[DF_LR]) #define df_live (df->problems_by_index[DF_LIVE]) #define df_chain (df->problems_by_index[DF_CHAIN]) #define df_word_lr (df->problems_by_index[DF_WORD_LR]) #define df_note (df->problems_by_index[DF_NOTE]) #define df_md (df->problems_by_index[DF_MD]) #define df_mir (df->problems_by_index[DF_MIR]) /* This symbol turns on checking that each modification of the cfg has been identified to the appropriate df routines. It is not part of verification per se because the check that the final solution has not changed covers this. However, if the solution is not being properly recomputed because the cfg is being modified, adding in calls to df_check_cfg_clean can be used to find the source of that kind of problem. */ #if 0 #define DF_DEBUG_CFG #endif /* Functions defined in df-core.c. */ extern void df_add_problem (const struct df_problem *); extern int df_set_flags (int); extern int df_clear_flags (int); extern void df_set_blocks (bitmap); extern void df_remove_problem (struct dataflow *); extern void df_finish_pass (bool); extern void df_analyze_problem (struct dataflow *, bitmap, int *, int); extern void df_analyze (); extern void df_analyze_loop (struct loop *); extern int df_get_n_blocks (enum df_flow_dir); extern int *df_get_postorder (enum df_flow_dir); extern void df_simple_dataflow (enum df_flow_dir, df_init_function, df_confluence_function_0, df_confluence_function_n, df_transfer_function, bitmap, int *, int); extern void df_mark_solutions_dirty (void); extern bool df_get_bb_dirty (basic_block); extern void df_set_bb_dirty (basic_block); extern void df_compact_blocks (void); extern void df_bb_replace (int, basic_block); extern void df_bb_delete (int); extern void df_verify (void); #ifdef DF_DEBUG_CFG extern void df_check_cfg_clean (void); #endif extern df_ref df_bb_regno_first_def_find (basic_block, unsigned int); extern df_ref df_bb_regno_last_def_find (basic_block, unsigned int); extern df_ref df_find_def (rtx_insn *, rtx); extern bool df_reg_defined (rtx_insn *, rtx); extern df_ref df_find_use (rtx_insn *, rtx); extern bool df_reg_used (rtx_insn *, rtx); extern void df_worklist_dataflow (struct dataflow *,bitmap, int *, int); extern void df_print_regset (FILE *file, bitmap r); extern void df_print_word_regset (FILE *file, bitmap r); extern void df_dump (FILE *); extern void df_dump_region (FILE *); extern void df_dump_start (FILE *); extern void df_dump_top (basic_block, FILE *); extern void df_dump_bottom (basic_block, FILE *); extern void df_dump_insn_top (const rtx_insn *, FILE *); extern void df_dump_insn_bottom (const rtx_insn *, FILE *); extern void df_refs_chain_dump (df_ref, bool, FILE *); extern void df_regs_chain_dump (df_ref, FILE *); extern void df_insn_debug (rtx_insn *, bool, FILE *); extern void df_insn_debug_regno (rtx_insn *, FILE *); extern void df_regno_debug (unsigned int, FILE *); extern void df_ref_debug (df_ref, FILE *); extern void debug_df_insn (rtx_insn *); extern void debug_df_regno (unsigned int); extern void debug_df_reg (rtx); extern void debug_df_defno (unsigned int); extern void debug_df_useno (unsigned int); extern void debug_df_ref (df_ref); extern void debug_df_chain (struct df_link *); /* Functions defined in df-problems.c. */ extern struct df_link *df_chain_create (df_ref, df_ref); extern void df_chain_unlink (df_ref); extern void df_chain_copy (df_ref, struct df_link *); extern void df_grow_bb_info (struct dataflow *); extern void df_chain_dump (struct df_link *, FILE *); extern void df_print_bb_index (basic_block bb, FILE *file); extern void df_rd_add_problem (void); extern void df_rd_simulate_artificial_defs_at_top (basic_block, bitmap); extern void df_rd_simulate_one_insn (basic_block, rtx_insn *, bitmap); extern void df_lr_add_problem (void); extern void df_lr_verify_transfer_functions (void); extern void df_live_verify_transfer_functions (void); extern void df_live_add_problem (void); extern void df_live_set_all_dirty (void); extern void df_chain_add_problem (unsigned int); extern void df_word_lr_add_problem (void); extern bool df_word_lr_mark_ref (df_ref, bool, bitmap); extern bool df_word_lr_simulate_defs (rtx_insn *, bitmap); extern void df_word_lr_simulate_uses (rtx_insn *, bitmap); extern void df_word_lr_simulate_artificial_refs_at_top (basic_block, bitmap); extern void df_word_lr_simulate_artificial_refs_at_end (basic_block, bitmap); extern void df_note_add_problem (void); extern void df_md_add_problem (void); extern void df_md_simulate_artificial_defs_at_top (basic_block, bitmap); extern void df_md_simulate_one_insn (basic_block, rtx_insn *, bitmap); extern void df_mir_add_problem (void); extern void df_mir_simulate_one_insn (basic_block, rtx_insn *, bitmap, bitmap); extern void df_simulate_find_noclobber_defs (rtx_insn *, bitmap); extern void df_simulate_find_defs (rtx_insn *, bitmap); extern void df_simulate_defs (rtx_insn *, bitmap); extern void df_simulate_uses (rtx_insn *, bitmap); extern void df_simulate_initialize_backwards (basic_block, bitmap); extern void df_simulate_one_insn_backwards (basic_block, rtx_insn *, bitmap); extern void df_simulate_finalize_backwards (basic_block, bitmap); extern void df_simulate_initialize_forwards (basic_block, bitmap); extern void df_simulate_one_insn_forwards (basic_block, rtx_insn *, bitmap); extern void simulate_backwards_to_point (basic_block, regset, rtx); extern bool can_move_insns_across (rtx_insn *, rtx_insn *, rtx_insn *, rtx_insn *, basic_block, regset, regset, rtx_insn **); /* Functions defined in df-scan.c. */ extern void df_scan_alloc (bitmap); extern void df_scan_add_problem (void); extern void df_grow_reg_info (void); extern void df_grow_insn_info (void); extern void df_scan_blocks (void); extern void df_uses_create (rtx *, rtx_insn *, int); extern struct df_insn_info * df_insn_create_insn_record (rtx_insn *); extern void df_insn_delete (rtx_insn *); extern void df_bb_refs_record (int, bool); extern bool df_insn_rescan (rtx_insn *); extern bool df_insn_rescan_debug_internal (rtx_insn *); extern void df_insn_rescan_all (void); extern void df_process_deferred_rescans (void); extern void df_recompute_luids (basic_block); extern void df_insn_change_bb (rtx_insn *, basic_block); extern void df_maybe_reorganize_use_refs (enum df_ref_order); extern void df_maybe_reorganize_def_refs (enum df_ref_order); extern void df_ref_change_reg_with_loc (rtx, unsigned int); extern void df_notes_rescan (rtx_insn *); extern void df_hard_reg_init (void); extern void df_update_entry_block_defs (void); extern void df_update_exit_block_uses (void); extern void df_update_entry_exit_and_calls (void); extern bool df_hard_reg_used_p (unsigned int); extern unsigned int df_hard_reg_used_count (unsigned int); extern bool df_regs_ever_live_p (unsigned int); extern void df_set_regs_ever_live (unsigned int, bool); extern void df_compute_regs_ever_live (bool); extern void df_scan_verify (void);