GCC Middle and Back End API 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_hardreg * | df_mw_hardreg_ptr |
typedef struct df_scan_bb_info * | df_scan_bb_info_t |
Variables | |
static HARD_REG_SET | elim_reg_set |
static df_ref | df_null_ref_rec [1] |
static struct df_mw_hardreg * | df_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 |
#define df_scan_free_mws_vec | ( | V | ) |
#define df_scan_free_ref_vec | ( | V | ) |
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 |
Referenced by move_insn_for_shrink_wrap(), and reemit_insn_block_notes().
#define HAVE_sibcall_epilogue 0 |
typedef struct df_mw_hardreg* df_mw_hardreg_ptr |
@verbatim
Scanning of rtl for dataflow analysis. Copyright (C) 1999-2013 Free Software Foundation, Inc. Originally contributed by Michael P. Hayes (m.hay, es@e lec.c ante rbury .ac. nzmhaye) Major rewrite contributed by Danny Berlin ( s@re dhat. comdberl) and Kenneth Zadeck ( in@d berli n.or gzadec). k@na tural brid ge.co 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/.
typedef struct df_scan_bb_info* df_scan_bb_info_t |
|
static |
Add the refs in REF_VEC to the table in REF_INFO starting at OFFSET.
|
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 |
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 |
|
static |
Sort and remove duplicates from the COLLECTION_REC.
|
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 |
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 |
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 |
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 |
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 |
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 |
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 |
Referenced by df_entry_block_defs_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 |
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 |
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 |
Free all of the refs and the mw_hardregs in COLLECTION_REC.
|
static |
References df_d::def_info, df, and df_ref_info::refs.
|
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 |
For all DF_REF_CONDITIONAL defs, add a corresponding uses.
|
static |
Referenced by df_grow_insn_info().
|
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 |
Referenced by df_get_eh_block_artificial_uses(), and df_grow_insn_info().
|
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 |
Referenced by df_grow_insn_info().
|
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 |
Referenced by df_grow_insn_info().
|
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().
void df_grow_insn_info | ( | void | ) |
Grow the ref information. If the current size is less than the number of instructions, grow to 25% more than the number of instructions.
References bitmap_ior_into(), df_d::def_info, df, df_get_eh_block_artificial_uses(), df_get_entry_block_def_set(), df_get_exit_block_use_set(), df_get_regular_block_artificial_uses(), df_record_entry_block_defs(), df_record_exit_block_uses(), DF_REF_ORDER_NO_TABLE, df_set_bb_dirty(), df_d::eh_block_artificial_uses, df_d::entry_block_defs, df_d::exit_block_uses, df_ref_info::ref_order, df_d::regular_block_artificial_uses, and df_d::use_info.
Referenced by df_get_call_refs().
|
static |
Referenced by 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().
|
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 |
Referenced by df_insn_rescan_debug_internal().
|
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 |
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 |
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.
bool df_insn_rescan_debug_internal | ( | ) |
Same as df_insn_rescan, but don't mark the basic block as dirty.
References bitmap_clear(), bitmap_copy(), df_d::changeable_flags, df, df_bitmap_obstack, df_clear_flags(), DF_DEFER_INSN_RESCAN, df_insn_info_delete(), df_insn_rescan(), DF_NO_INSN_RESCAN, df_set_flags(), df_insn_info::insn, df_d::insns_to_delete, df_d::insns_to_notes_rescan, and df_d::insns_to_rescan.
|
staticread |
This function takes the mws installs the entire group into the insn.
|
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 |
|
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 |
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 |
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 |
|
static |
Compare MW1 and MW2 for sorting.
References df, and df_d::hard_regs_live_count.
|
static |
Return true if the contents of two df_ref's are identical. It ignores DF_REF_MARKER.
|
static |
Delete the hardreg chain.
References df_insn_info::defs, df_ref_chain_delete_du_chain(), df_insn_info::eq_uses, and df_insn_info::uses.
Referenced by df_ref_chain_delete().
|
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 |
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 |
Referenced by df_get_eh_block_artificial_uses(), and df_grow_insn_info().
|
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 |
Referenced by df_grow_insn_info().
|
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 |
Referenced by df_get_eh_block_artificial_uses(), and df_record_entry_block_defs().
|
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 |
Referenced by df_get_eh_block_artificial_uses(), df_mw_hardreg_chain_delete(), and df_record_entry_block_defs().
|
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 |
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 |
Referenced by df_ref_equal_p().
|
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 |
Remove REF from VEC.
References df_scan_bb_info::artificial_defs, df_insn_info::defs, and df_scan_get_bb_info().
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 |
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 |
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 |
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 |
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 |
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 |
@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 |
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 |
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 |
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 |
Count the number of refs in all of the insns of BB. Include the defs if INCLUDE_DEFS. Include the uses if INCLUDE_USES. Include the eq_uses if INCLUDE_EQ_USES.
References df, DF_REF_ORDER_BY_INSN, DF_REF_ORDER_BY_INSN_WITH_NOTES, DF_REF_ORDER_BY_REG, DF_REF_ORDER_BY_REG_WITH_NOTES, DF_REF_ORDER_NO_TABLE, DF_REF_ORDER_UNORDERED, DF_REF_ORDER_UNORDERED_WITH_NOTES, df_reorganize_refs_by_insn(), df_reorganize_refs_by_reg(), free(), df_ref_info::ref_order, df_ref_info::refs, df_ref_info::refs_size, and df_d::use_info.
|
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 |
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 |
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 |
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 |
Free basic block info.
See if bb_info is initialized.
Get rid of any artificial uses or defs.
|
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 |
Dump the bb_info for a given basic block.
|
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 |
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 |
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 |
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 |
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().
|
static |
|
static |
Flags used to tell df_refs_add_to_chains() which vectors it should copy.
|
static |
|
static |
|
static |
|
static |
Referenced by df_install_ref().
|
static |
|
static |
The set of hard registers in eliminables[i].from.
Referenced by df_refs_add_to_chains().
|
static |
|
static |
|
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.