GCC Middle and Back End API Reference
|
Data Structures | |
struct | df_rd_problem_data |
struct | df_lr_problem_data |
struct | df_live_problem_data |
struct | df_word_lr_problem_data |
struct | df_md_problem_data |
Variables | |
static bitmap_head | seen_in_block |
static bitmap_head | seen_in_insn |
static struct df_problem | problem_RD |
static struct df_problem | problem_LR |
static bitmap_head | df_live_scratch |
static struct df_problem | problem_LIVE |
static struct df_problem | problem_CHAIN |
static struct df_problem | problem_WORD_LR |
static struct df_problem | problem_NOTE |
static bitmap_head | df_md_scratch |
static struct df_problem | problem_MD |
bool can_move_insns_across | ( | rtx | from, |
rtx | to, | ||
rtx | across_from, | ||
rtx | across_to, | ||
basic_block | merge_bb, | ||
regset | merge_live, | ||
regset | other_branch_live, | ||
rtx * | pmove_upto | ||
) |
Return true if it is safe to move a group of insns, described by the range FROM to TO, backwards across another group of insns, described by ACROSS_FROM to ACROSS_TO. It is assumed that there are no insns between ACROSS_TO and FROM, but they may be in different basic blocks; MERGE_BB is the block from which the insns will be moved. The caller must pass in a regset MERGE_LIVE which specifies the registers live after TO. This function may be called in one of two cases: either we try to move identical instructions from all successor blocks into their predecessor, or we try to move from only one successor block. If OTHER_BRANCH_LIVE is nonnull, it indicates that we're dealing with the second case. It should contain a set of registers live at the end of ACROSS_TO which must not be clobbered by moving the insns. In that case, we're also more careful about moving memory references and trapping insns. We return false if it is not safe to move the entire group, but it may still be possible to move a subgroup. PMOVE_UPTO, if nonnull, is set to point at the last moveable insn in such a case.
Find real bounds, ignoring debug insns.
Pure functions can read from memory. Const functions can read from arguments that the ABI has forced onto the stack. Neither sort of read can be volatile.
This is used just to find sets of the stack pointer.
Collect: MERGE_SET = set of registers set in MERGE_BB MERGE_USE = set of registers used in MERGE_BB and live at its top MERGE_LIVE = set of registers live at the point inside the MERGE range that we've reached during scanning TEST_SET = set of registers set between ACROSS_FROM and ACROSS_END. TEST_USE = set of registers used between ACROSS_FROM and ACROSS_END, and live before ACROSS_FROM.
Compute the set of registers set and used in the ACROSS range.
Compute an upper bound for the amount of insns moved, by finding the first insn in MERGE that sets a register in TEST_USE, or uses a register in TEST_SET. We also check for calls, trapping operations, and memory references.
We cannot move memory stores past each other, or move memory reads past stores, at least not without tracking them and calling true_dependence on every pair. If there is no other branch and no memory references or sets in the ACROSS range, we can move memory references freely, even volatile ones. Otherwise, the rules are as follows: volatile memory references and stores can't be moved at all, and any type of memory reference can't be moved if there are volatile accesses or stores in the ACROSS range. That leaves normal reads, which can be moved, as the trapping case is dealt with elsewhere.
Catch sets of the stack pointer.
We're only interested in uses which use a value live at the top, not one previously set in this block.
Now, lower this upper bound by also taking into account that a range of insns moved across ACROSS must not leave a register live at the end that will be clobbered in ACROSS. We need to find a point where TEST_SET & LIVE == 0. Insns in the MERGE range that set registers which are also set in the ACROSS range may still be moved as long as we also move later insns which use the results of the set, and make the register dead again. This is verified by the condition stated above. We only need to test it for registers that are set in the moved region. MERGE_LIVE is provided by the caller and holds live registers after TO.
We're not interested in registers that aren't set in the moved region at all.
For small register class machines, don't lengthen lifetimes of hard registers before reload.
void df_chain_add_problem | ( | ) |
Create a new DATAFLOW instance and add it to an existing instance of DF. The returned structure is what is used to get at the solution.
Referenced by mark_artificial_uses().
|
static |
Create def-use or use-def chains.
References df_chain_create_bb().
|
static |
|
static |
References bitmap_clear(), df_word_lr_bb_info::def, and df_word_lr_bb_info::use.
Copy the du or ud chain starting at FROM_REF and attach it to TO_REF.
|
read |
Create a du or ud chain from SRC to DST and link it into SRC.
References df_chain_remove_problem(), and free().
|
static |
Create chains from reaching defs bitmaps for basic block BB.
Since we are going forwards, process the artificial uses first then the artificial defs second.
Create the chains for the artificial uses from the EH_USES at the beginning of the block.
Artificials are only hard regs.
Process the regular instructions next.
First scan the uses and link them up with the defs that remain in the cpy vector.
Since we are going forwards, process the defs second.
Create the chains for the artificial uses of the hard registers at the end of the block.
References df_chain_bb_dump().
Referenced by df_chain_alloc().
|
static |
Create the chains for a list of USEs.
Do not want to go through this for an uninitialized var.
References df_chain_dump(), df_get_artificial_uses(), and basic_block_def::index.
Referenced by df_chain_remove_problem().
void df_chain_dump | ( | ) |
Generic versions to get the void* version of the block info. Only used inside the problem instance vectors.
Dump a def-use or use-def chain for REF to FILE.
References DF_REF_IN_NOTE, and df_link::ref.
Referenced by df_chain_create_bb_process_use(), df_chain_finalize(), df_dump_bb_problem_data(), and df_insn_debug_regno().
|
static |
Create def-use chains from reaching use bitmaps for basic blocks in BLOCKS.
References df_d::changeable_flags, df, df_chain_dump(), DF_NO_HARD_REGS, and DF_REF_READ_WRITE.
|
static |
Free all storage associated with the problem.
|
static |
Remove the chain problem completely.
|
static |
References bitmap_clear(), df_word_lr_bb_info::def, and df_word_lr_bb_info::use.
|
static |
|
static |
Remove this problem from the stack of dataflow problems.
Wholesale destruction of the old chains.
References bitmap_clear(), bitmap_copy(), bitmap_default_obstack, bitmap_set_bit(), df_d::changeable_flags, df, df_chain_create_bb_process_use(), DF_EQ_NOTES, df_get_artificial_uses(), DF_NO_HARD_REGS, df_rd_get_bb_info(), df_rd_simulate_artificial_defs_at_top(), df_rd_simulate_one_insn(), df_rd_bb_info::in, and basic_block_def::index.
Referenced by df_chain_create().
|
static |
Reset all of the chains when the set of basic blocks changes.
|
static |
void df_chain_unlink | ( | ) |
Delete a du or ud chain that leave or point to REF.
Delete the other side if it exists.
|
static |
Delete any du or ud chains that start at REF and point to TARGET.
|
static |
Create a REG_UNUSED note if necessary for DEF in INSN updating LIVE. Do not generate notes for registers in ARTIFICIAL_USES.
References bitmap_bit_p(), dead_debug_add(), dead_debug_insert_temp(), DEBUG_TEMP_BEFORE_WITH_REG, df_ignore_stack_reg(), df_ref_debug(), DF_REF_READ_WRITE, and dump_file.
Referenced by df_set_dead_notes_for_mw().
|
inlinestatic |
After reg-stack, the x86 floating point stack regs are difficult to analyze because of all of the pushes, pops and rotations. Thus, we just leave the notes alone.
References df_set_note(), df_whole_mw_reg_unused_p(), dump_file, df_mw_hardreg::end_regno, df_mw_hardreg::mw_reg, and df_mw_hardreg::start_regno.
Referenced by df_create_unused_note(), df_whole_mw_reg_dead_p(), and df_word_lr_top_dump().
void df_live_add_problem | ( | void | ) |
Create a new DATAFLOW instance and add it to an existing instance of DF. The returned structure is what is used to get at the solution.
These will be initialized when df_scan_blocks processes each block.
References df_link::next, and df_link::ref.
|
static |
Allocate or reset bitmaps for DF_LIVE blocks. The solution bits are not touched unless the block is new.
When bitmaps are already initialized, just clear them.
References bitmap_set_bit(), DF_REF_CONDITIONAL, DF_REF_MAY_CLOBBER, DF_REF_MUST_CLOBBER, DF_REF_PARTIAL, df_live_bb_info::gen, and df_live_bb_info::kill.
|
static |
Compute local uninitialized register info for basic block BB.
Inserting labels does not always trigger the incremental rescanning.
All partial or conditional def seen are included in the gen set.
Only must clobbers for the entire reg destroy the value.
References bitmap_ior_into(), edge_def::dest, df_live_get_bb_info(), edge_def::flags, df_live_bb_info::in, basic_block_def::index, df_live_bb_info::out, and edge_def::src.
Referenced by df_live_verify_solution_end().
|
static |
Debugging info at bottom of bb.
|
static |
Forward confluence function that ignores fake edges.
References df_print_regset(), df_live_problem_data::in, and basic_block_def::index.
|
static |
And the LR info with the must-initialized registers, to produce the LIVE info.
No register may reach a location where it is not used. Thus we trim the rr result to the places where it is used.
References bitmap_copy(), df_live_problem_data::in, basic_block_def::index, df_live_problem_data::live_bitmaps, and df_live_problem_data::out.
|
static |
Free all storage associated with the problem.
References bitmap_equal_p(), df_live_problem_data::in, basic_block_def::index, and df_live_problem_data::out.
|
static |
Free basic block info.
References df_insn_create_insn_record(), and df_insn_info::luid.
|
static |
Initialize the solution vectors.
No register may reach a location where it is not used. Thus we trim the rr result to the places where it is used.
|
static |
Compute local uninitialized register info.
|
static |
Reset the global solution for recalculation.
References bitmap_and(), bitmap_clear(), df_live_get_bb_info(), df_lr_get_bb_info(), df_live_bb_info::gen, df_live_bb_info::in, df_lr_bb_info::out, and df_live_bb_info::out.
void df_live_set_all_dirty | ( | void | ) |
Set all of the blocks as dirty. This needs to be done if this problem is added after all of the insns have been scanned.
|
static |
Debugging info at top of bb.
|
static |
Transfer function for the forwards must-initialized problem.
We need to use a scratch set here so that the value returned from this function invocation properly reflects whether the sets changed in a significant way; i.e. not just because the lr set was anded in.
No register may reach a location where it is not used. Thus we trim the rr result to the places where it is used.
References df_live_get_bb_info(), df_print_regset(), basic_block_def::index, df_live_bb_info::out, and df_live_problem_data::out.
|
static |
Compare the saved datastructure and the new solution to the dataflow equations.
Cannot delete them immediately because you may want to dump them if the comparison fails.
References bitmap_bit_p(), bitmap_clear(), bitmap_copy(), bitmap_equal_p(), bitmap_set_bit(), df_live_bb_local_compute(), df_live_get_bb_info(), df_scan_get_bb_info(), df_live_bb_info::gen, basic_block_def::index, and df_live_bb_info::kill.
|
static |
Build the datastructure to verify that the solution to the dataflow equations is not dirty.
Set it true so that the solution is recomputed.
References bitmap_set_bit(), and basic_block_def::index.
void df_live_verify_transfer_functions | ( | void | ) |
Verify that all of the lr related info is consistent and correct.
Make a copy of the transfer functions and then compute new ones to see if the transfer functions have changed.
If we do not have basic block info, the block must be in the list of dirty blocks or else some one has added a block behind our backs.
Make sure no one created a block without following procedures.
Make sure there are no dirty bits in blocks that have been deleted.
void df_lr_add_problem | ( | void | ) |
Create a new DATAFLOW instance and add it to an existing instance of DF. The returned structure is what is used to get at the solution.
These will be initialized when df_scan_blocks processes each block.
|
static |
Allocate or reset bitmaps for DF_LR blocks. The solution bits are not touched unless the block is new.
When bitmaps are already initialized, just clear them.
References bitmap_clear(), df_lr_get_bb_info(), df_lr_bb_info::in, and df_lr_bb_info::out.
Referenced by df_lr_confluence_0().
|
static |
Compute local live register info for basic block BB.
Process the registers set in an exception handler.
Process the hardware registers that are always live.
Add use to set of uses in this BB.
If the def is to only part of the reg, it does not kill the other defs that reach here.
Add use to set of uses in this BB.
Process the registers set in an exception handler or the hard frame pointer if this block is the target of a non local goto.
Process the uses that are live into an exception handler.
Add use to set of uses in this BB.
If the df_live problem is not defined, such as at -O0 and -O1, we still need to keep the luids up to date. This is normally done in the df_live problem since this problem has a forwards scan.
|
static |
Debugging info at bottom of bb.
|
static |
Confluence function that processes infinite loops. This might be a noreturn function that throws. And even if it isn't, getting the unwind info right helps debugging.
References df, df_clear_flags(), df_lr_alloc(), df_lr_finalize(), df_lr_local_compute(), DF_LR_RUN_DCE, df_set_flags(), df_worklist_dataflow(), df_d::n_blocks, and df_d::postorder.
|
static |
Confluence function that ignores fake edges.
Call-clobbered registers die across exception and call edges.
??? Abnormal call edges ignored for the moment, as this gets confused by sibling call edges, which crashes reg-stack.
|
static |
Run the fast dce as a side effect of building LR.
If dce deletes some instructions, we need to recompute the lr solution before proceeding further. The problem is that fast dce is a pessimestic dataflow algorithm. In the case where it deletes a statement S inside of a loop, the uses inside of S may not be deleted from the dataflow solution because they were carried around the loop. While it is conservatively correct to leave these extra bits, the standards of df require that we maintain the best possible (least fixed point) solution. The only way to do that is to redo the iteration from the beginning. See PR35805 for an example.
References df_print_regset(), df_lr_problem_data::in, and basic_block_def::index.
Referenced by df_lr_confluence_0().
|
static |
Free all storage associated with the problem.
References bitmap_copy(), df_lr_problem_data::in, basic_block_def::index, df_lr_problem_data::lr_bitmaps, and df_lr_problem_data::out.
|
static |
Free basic block info.
References bitmap_clear(), df_lr_bb_info::def, and df_lr_bb_info::use.
|
static |
Initialize the solution vectors.
References df_d::changeable_flags, df, DF_LR_RUN_DCE, and run_fast_df_dce().
|
static |
Compute local live register info for each basic block within BLOCKS.
The all-important stack pointer must always be live.
Global regs are always live, too.
Before reload, there are a few registers that must be forced live everywhere -- which might not already be the case for blocks within infinite loops.
Any reference to any pseudo before reload is a potential reference of the frame pointer.
Pseudos with argument area equivalences may require reloading via the argument pointer.
Any constant, or pseudo with constant equivalences, may require reloading from memory using the pic register.
The exit block is special for this problem and its bits are computed from thin air.
References bitmap_clear(), bitmap_copy(), df_lr_get_bb_info(), df_lr_bb_info::in, df_lr_bb_info::out, and df_lr_bb_info::use.
Referenced by df_lr_confluence_0().
|
static |
Reset the global solution for recalculation.
|
static |
Debugging info at top of bb.
|
static |
Transfer function.
References df_lr_get_bb_info(), df_print_regset(), df_lr_bb_info::in, and basic_block_def::index.
|
static |
Compare the saved datastructure and the new solution to the dataflow equations.
Do not check if the solution is still dirty. See the comment in df_lr_finalize for details.
Cannot delete them immediately because you may want to dump them if the comparison fails.
References df_add_problem(), and df_bitmap_obstack.
|
static |
Build the datastructure to verify that the solution to the dataflow equations is not dirty.
Set it true so that the solution is recomputed.
void df_lr_verify_transfer_functions | ( | void | ) |
Verify that all of the lr related info is consistent and correct.
Make a copy of the transfer functions and then compute new ones to see if the transfer functions have changed.
If we do not have basic block info, the block must be in the list of dirty blocks or else some one has added a block behind our backs.
Make sure no one created a block without following procedures.
Make sure there are no dirty bits in blocks that have been deleted.
References df_live_problem_data::in, df_live_problem_data::live_bitmaps, and df_live_problem_data::out.
void df_md_add_problem | ( | void | ) |
Create a new MD instance and add it to the existing instance of DF.
|
static |
Allocate or reset bitmaps for DF_MD. The solution bits are not touched unless the block is new.
When bitmaps are already initialized, just clear them.
References bitmap_copy(), df_md_get_bb_info(), df_md_transfer_function(), df_md_bb_info::in, and df_md_bb_info::init.
|
static |
Compute local multiple def info for basic block BB.
Artificials are only hard regs.
|
static |
When we find a clobber and a regular def, make sure the regular def wins.
|
static |
Debugging info at bottom of bb.
|
static |
|
static |
In of target gets or of out of source.
|
static |
Free all storage associated with the problem.
|
static |
|
static |
Initialize the solution bit vectors for problem.
|
static |
Compute local reaching def info for each basic block within BLOCKS.
Add each basic block's kills to the nodes in the frontier of the BB.
|
static |
Reset the global solution for recalculation.
void df_md_simulate_artificial_defs_at_top | ( | ) |
Add the effect of the top artificial defs of BB to the multiple definitions bitmap LOCAL_MD.
void df_md_simulate_one_insn | ( | basic_block | bb, |
rtx | insn, | ||
bitmap | local_md | ||
) |
Add the effect of the defs of INSN to the reaching definitions bitmap LOCAL_MD.
|
static |
Debugging info at top of bb.
|
static |
We need to use a scratch set here so that the value returned from this function invocation properly reflects whether the sets changed in a significant way; i.e. not just because the live set was anded in.
Multiple definitions of a register are not relevant if it is not live. Thus we trim the result to the places where it is live.
Referenced by df_md_alloc().
void df_note_add_problem | ( | void | ) |
Create a new DATAFLOW instance and add it to an existing instance of DF. The returned structure is what is used to get at the solution.
References bitmap_set_bit().
Referenced by compute_bb_for_insn(), dse_step4(), and split_live_ranges_for_shrink_wrap().
|
static |
References DF_REF_PARTIAL, and df_mw_hardreg::flags.
|
static |
Recompute the REG_DEAD and REG_UNUSED notes and compute register info: lifetime, bb, and number of defs and uses for basic block BB. The three bitvectors are scratch regs used here.
Process the artificial defs and uses at the bottom of the block to begin processing.
Notes are not generated for any of the artificial registers at the bottom of the block.
Process the defs.
We only care about real sets for calls. Clobbers cannot be depended on to really die.
All of the defs except the return value are some sort of clobber. This code is for the return.
Regular insn.
Process the uses.
We won't add REG_UNUSED or REG_DEAD notes for these, so we don't have to mess with them in debug insns either.
This register is now live.
??? We could probably do better here, replacing dead registers with their definitions.
References df_print_note(), and df_set_note().
|
static |
Compute register info: lifetime, bb, and number of defs and uses.
??? Unlike fast DCE, we don't use global_debug for uses of dead pseudos in debug insns because we don't always (re)visit blocks with death points after visiting dead uses. Even changing this loop to postorder would still leave room for visiting a death point before visiting a subsequent debug use.
|
static |
Free all storage associated with the problem.
void df_print_bb_index | ( | ) |
Print some basic block info as part of df_dump.
|
static |
This is only used if REG_DEAD_DEBUGGING is in effect.
Referenced by df_note_bb_compute(), df_remove_dead_eq_notes(), and df_word_lr_top_dump().
void df_rd_add_problem | ( | void | ) |
Create a new RD instance and add it to the existing instance of DF.
|
static |
Allocate or reset bitmaps for DF_RD blocks. The solution bits are not touched unless the block is new.
Because of the clustering of all use sites for the same pseudo, we have to process all of the blocks before doing the analysis.
When bitmaps are already initialized, just clear them.
References bitmap_obstack_initialize(), df_rd_problem_data::dense_invalidated_by_call, df_rd_problem_data::rd_bitmaps, and df_rd_problem_data::sparse_invalidated_by_call.
|
static |
Compute local reaching def info for basic block BB.
Artificials are only hard regs.
This complex dance with the two bitmaps is required because instructions can assign twice to the same pseudo. This generally happens with calls that will have one def for the result and another def for the clobber. If only one vector is used and the clobber goes first, the result will be lost.
Process the artificial defs at the top of the block last since we are going backwards through the block and these are logically at the start.
|
static |
Process a list of DEFs for df_rd_bb_local_compute. This is a bit more complicated than just simulating, because we must produce the gen and kill sets and hence deal with the two possible representations of kill sets.
Only the last def(s) for a regno in the block has any effect.
The first def for regno in insn gets to knock out the defs from other instructions.
If the def is to only part of the reg, it does not kill the other defs that reach here.
All defs for regno in the instruction may be put into the gen set.
References bitmap_bit_p(), bitmap_clear_range(), bitmap_set_bit(), bitmap_set_range(), DF_REF_CONDITIONAL, DF_REF_MAY_CLOBBER, DF_REF_MUST_CLOBBER, DF_REF_PARTIAL, df_rd_bb_info::gen, df_rd_bb_info::kill, and df_rd_bb_info::sparse_kill.
|
static |
Debugging info at bottom of bb.
|
static |
In of target gets or of out of source.
|
static |
|
static |
Free all storage associated with the problem.
|
static |
Free basic block info.
|
static |
Initialize the solution bit vectors for problem.
|
static |
Compute local reaching def info for each basic block within BLOCKS.
Set up the knockout bit vectors to be applied across EH_EDGES.
void df_rd_simulate_artificial_defs_at_top | ( | ) |
Add the effect of the top artificial defs of BB to the reaching definitions bitmap LOCAL_RD.
Referenced by df_chain_remove_problem().
void df_rd_simulate_one_insn | ( | basic_block | bb, |
rtx | insn, | ||
bitmap | local_rd | ||
) |
Add the effect of the defs of INSN to the reaching definitions bitmap LOCAL_RD.
Referenced by df_chain_remove_problem().
|
static |
Debugging info.
|
static |
Debugging info at top of bb.
|
static |
Transfer function.
Note that TMP is _not_ a temporary bitmap if we end up replacing OUT with TMP. Therefore, allocate TMP in the RD bitmaps obstack.
Create a mask of DEFs for all registers live at the end of this basic block, and mask out DEFs of registers that are not live. Computing the mask looks costly, but the benefit of the pruning outweighs the cost.
|
static |
Remove all of the REG_DEAD or REG_UNUSED notes from INSN.
After reg-stack, we need to ignore any unused notes for the stack registers.
After reg-stack, we need to ignore any unused notes for the stack registers.
|
static |
Remove REG_EQUAL/REG_EQUIV notes referring to dead pseudos using LIVE as the bitmap of currently live registers.
Remove the notes that refer to dead registers. As we have at most one REG_EQUAL/EQUIV note, all of EQ_USES will refer to this note so we need to purge the complete EQ_USES vector when removing the note using df_notes_rescan.
References bitmap_bit_p(), df_print_note(), df_print_regset(), df_set_note(), df_whole_mw_reg_dead_p(), dump_file, df_mw_hardreg::end_regno, df_mw_hardreg::mw_reg, regno_reg_rtx, and df_mw_hardreg::start_regno.
|
static |
Set the REG_DEAD notes for the multiword hardreg use in INSN based on the bits in LIVE. DO_NOT_GEN is used to keep REG_DEAD notes from being set if the instruction both reads and writes the register.
Add a dead note for the entire multi word register.
References bitmap_set_bit(), and df_create_unused_note().
|
inlinestatic |
Set a NOTE_TYPE note for REG in INSN.
Referenced by df_ignore_stack_reg(), df_note_bb_compute(), and df_remove_dead_eq_notes().
|
static |
@verbatim
Set the REG_UNUSED notes for the multiword hardreg defs in INSN based on the bits in LIVE. Do not generate notes for registers in artificial uses. DO_NOT_GEN is updated so that REG_DEAD notes are not generated if the reg is both read and written by the instruction.
Only do this if the value is totally dead.
References bitmap_clear_bit(), and dump_file.
Referenced by df_whole_mw_reg_dead_p().
void df_simulate_defs | ( | ) |
Simulate the effects of the defs of INSN on LIVE.
If the def is to only part of the reg, it does not kill the other defs that reach here.
void df_simulate_finalize_backwards | ( | ) |
Apply the artificial uses and defs at the top of BB in a backwards direction.
void df_simulate_find_defs | ( | ) |
Find the set of DEFs for INSN.
References bitmap_set_bit().
Referenced by df_simulate_one_insn_forwards().
void df_simulate_find_noclobber_defs | ( | ) |
Find the set of real DEFs, which are not clobbers, for INSN.
|
static |
Find the set of uses for INSN. This includes partial defs.
Referenced by df_simulate_one_insn_forwards().
|
inlinestatic |
Add back the always live regs in BB to LIVE.
These regs are considered always live so if they end up dying because of some def, we need to bring the back again.
References bitmap_copy(), df_get_live_out(), df_simulate_initialize_backwards(), and df_simulate_one_insn_backwards().
void df_simulate_initialize_backwards | ( | ) |
Apply the artificial uses and defs at the end of BB in a backwards direction.
Referenced by df_simulate_fixup_sets().
void df_simulate_initialize_forwards | ( | ) |
Initialize the LIVE bitmap, which should be copied from DF_LIVE_IN or DF_LR_IN for basic block BB, for forward scanning by marking artificial defs live.
void df_simulate_one_insn_backwards | ( | ) |
Simulate the backwards effects of INSN on the bitmap LIVE.
Referenced by df_simulate_fixup_sets().
void df_simulate_one_insn_forwards | ( | ) |
Simulate the forwards effects of INSN on the bitmap LIVE.
Make sure that DF_NOTE really is an active df problem.
Note that this is the opposite as how the problem is defined, because in the LR problem defs _kill_ liveness. However, they do so backwards, while here the scan is performed forwards! So, first assume that the def is live, and if this is not true REG_UNUSED notes will rectify the situation.
Clear all of the registers that go dead.
References bitmap_and_compl_into(), bitmap_intersect_p(), df_simulate_find_defs(), df_simulate_find_uses(), find_memory(), find_memory_stores(), for_each_rtx(), may_trap_or_fault_p(), note_stores(), sets_cc0_p(), and volatile_insn_p().
void df_simulate_uses | ( | ) |
Simulate the effects of the uses of INSN on LIVE.
Add use to set of uses in this BB.
References pflags.
Referenced by find_if_case_2().
|
static |
A subroutine of df_set_dead_notes_for_mw, with a selection of its arguments. Return true if the register value described by MWS's mw_reg is known to be completely dead, and if mw_reg can therefore be used in a REG_DEAD note.
If MWS describes a partial reference, create REG_DEAD notes for individual hard registers.
Likewise if some part of the register is not dead.
References df_ignore_stack_reg(), df_print_regset(), DF_REF_MAY_CLOBBER, DF_REF_MUST_CLOBBER, df_set_unused_notes_for_mw(), dump_file, and df_mw_hardreg::start_regno.
Referenced by df_remove_dead_eq_notes().
|
static |
A subroutine of df_set_unused_notes_for_mw, with a selection of its arguments. Return true if the register value described by MWS's mw_reg is known to be completely unused, and if mw_reg can therefore be used in a REG_UNUSED note.
If MWS describes a partial reference, create REG_UNUSED notes for individual hard registers.
Likewise if some part of the register is used.
Referenced by df_ignore_stack_reg().
void df_word_lr_add_problem | ( | void | ) |
Create a new DATAFLOW instance and add it to an existing instance of DF. The returned structure is what is used to get at the solution.
These will be initialized when df_scan_blocks processes each block.
References bitmap_bit_p(), DF_REF_IN_NOTE, and loc_mentioned_in_p().
|
static |
Allocate or reset bitmaps for DF_WORD_LR blocks. The solution bits are not touched unless the block is new.
Create the mapping from regnos to slots. This does not change unless the problem is destroyed and recreated. In particular, if we end up deleting the only insn that used a subreg, we do not want to redo the mapping because this would invalidate everything else.
When bitmaps are already initialized, just clear them.
References df_word_lr_bb_info::def, df_word_lr_mark_ref(), and df_word_lr_bb_info::use.
|
static |
Compute local live register info for basic block BB.
Ensure that artificial refs don't contain references to pseudos.
If the def is to only part of the reg, it does not kill the other defs that reach here.
References df_print_word_regset(), df_word_lr_get_bb_info(), basic_block_def::index, and df_word_lr_bb_info::out.
|
static |
Debugging info at bottom of bb.
|
static |
Confluence function that ignores fake edges.
|
static |
Free all storage associated with the problem.
|
static |
Free basic block info.
|
static |
Initialize the solution vectors.
|
static |
Compute local live register info for each basic block within BLOCKS.
bool df_word_lr_mark_ref | ( | ) |
Examine REF, and if it is for a reg we're interested in, set or clear the bits corresponding to its subwords from the bitmap according to IS_SET. LIVE is the bitmap we should update. We do not track hard regs or pseudos of any size other than 2 * UNITS_PER_WORD. We return true if we changed the bitmap, or if we encountered a register we're not tracking.
Left at -1 for whole accesses.
Referenced by df_word_lr_alloc().
|
static |
Reset the global solution for recalculation.
bool df_word_lr_simulate_defs | ( | ) |
Simulate the effects of the defs of INSN on LIVE. Return true if we changed any bits, which is used by the caller to determine whether a set is necessary. We also return true if there are other reasons not to delete an insn.
void df_word_lr_simulate_uses | ( | ) |
Simulate the effects of the uses of INSN on LIVE.
References add_reg_note().
|
static |
Debugging info at top of bb.
References df_ignore_stack_reg(), df_print_note(), and free_EXPR_LIST_node().
|
static |
Transfer function.
References dump_file, and print_rtl().
|
static |
A subroutine of can_move_insns_across_p called through for_each_rtx. Return either MEMREF_NORMAL or MEMREF_VOLATILE if a memory is found.
Referenced by df_simulate_one_insn_forwards().
A subroutine of can_move_insns_across_p called through note_stores. DATA points to an integer in which we set either the bit for MEMREF_NORMAL or the bit for MEMREF_VOLATILE if we find a MEM of either kind.
Treat stores to SP as stores to memory, this will prevent problems when there are references to the stack frame.
Referenced by df_simulate_one_insn_forwards().
void simulate_backwards_to_point | ( | ) |
Scan BB backwards, using df_simulate functions to keep track of lifetimes, up to insn POINT. The result is stored in LIVE.
Scan and update life information until we reach the point we're interested in.
|
static |
Scratch var used by transfer functions. This is used to implement an optimization to reduce the amount of space used to compute the combined lr and live analysis.
|
static |
Scratch var used by transfer functions. This is used to do md analysis only for live registers.
|
static |
|
static |
All of the information associated with every instance of the problem.
|
static |
All of the information associated with every instance of the problem.
|
static |
|
static |
All of the information associated every instance of the problem.
|
static |
All of the information associated with every instance of the problem.
|
static |
All of the information associated with every instance of the problem.
|
static |
|
static |