GCC Middle and Back End API Reference
|
Data Structures | |
struct | seginfo |
struct | bb_info |
Functions | |
static struct seginfo * | new_seginfo (int, rtx, int, HARD_REG_SET) |
static void | add_seginfo (struct bb_info *, struct seginfo *) |
static void | reg_dies (rtx, HARD_REG_SET *) |
static void | reg_becomes_live (rtx, const_rtx, void *) |
static void | make_preds_opaque (basic_block, int) |
static struct seginfo * | new_seginfo () |
static void | add_seginfo () |
static void | make_preds_opaque () |
static void | reg_dies () |
static void | reg_becomes_live () |
static basic_block | create_pre_exit () |
static int | optimize_mode_switching () |
static bool | gate_mode_switching () |
static unsigned int | rest_of_handle_mode_switching () |
rtl_opt_pass * | make_pass_mode_switching () |
Variables | |
static sbitmap * | antic |
static sbitmap * | transp |
static sbitmap * | comp |
|
static |
Add a seginfo element to the end of a list. HEAD is a pointer to the list beginning. INFO is the structure to be linked in.
References seginfo::next, and bb_info::seginfo.
|
static |
Make sure if MODE_ENTRY is defined the MODE_EXIT is defined and vice versa.
Split the fallthrough edge to the exit block, so that we can note that there NORMAL_MODE is required. Return the new block if it's inserted before the exit block. Otherwise return null.
The only non-call predecessor at this stage is a block with a fallthrough edge; there can be at most one, but there could be none at all, e.g. when exit is called.
If this function returns a value at the end, we have to insert the final mode switch before the return value copy to its hard register.
When using SJLJ exceptions, the call to the unregister function is inserted between the clobber of the return value and the copy. We do not want to split the block before this or any other call; if we have not found the copy yet, the copy must have been deleted.
Skip USEs of multiple return registers. __builtin_apply pattern is also handled here.
Skip barrier insns.
Fall through.
If the return register is not (in its entirety) likely spilled, the return copy might be partially or completely optimized away.
This might be (clobber (reg [<result>])) when not optimizing. Then check if the previous insn is the clobber for the return register.
When control reaches end of non-void function, there are no return copy insns at all. This avoids an ice on that invalid function.
If the return register is not likely spilled, - as is the case for floating point on SH4 - then it might be set by an arithmetic operation that needs a different mode than the exit block.
__builtin_return emits a sequence of loads to all return registers. One of them might require another mode than MODE_EXIT, even if it is unrelated to the return value, so we want to put the final mode switch after it.
For the SH4, floating point loads depend on fpscr, thus we might need to put the final mode switch after the return value copy. That is still OK, because a floating point return value does not conflict with address reloads.
??? Exception handling can lead to the return value copy being already separated from the return value use, as in unwind-dw2.c . Similarly, conditionally returning without a value, and conditionally using builtin_return can lead to an isolated use.
If we didn't see a full return value copy, verify that there is a plausible reason for this. If some, but not all of the return register is likely spilled, we can expect that there is a copy for the likely spilled part.
For multi-hard-register floating point values, sometimes the likely-spilled part is ordinarily copied first, then the other part is set with an arithmetic operation. This doesn't actually cause reload failures, so let it pass.
Instructions preceding LAST_INSN in the same block might require a different mode than MODE_EXIT, so if we might have such instructions, keep them in a separate block from pre_exit.
References edge_def::dest, emit_note_before(), seginfo::mode, split_block(), split_edge(), edge_def::src, and targetm.
|
static |
References rest_of_handle_mode_switching().
rtl_opt_pass* make_pass_mode_switching | ( | ) |
|
static |
|
static |
Make all predecessors of basic block B opaque, recursively, till we hit some that are already non-transparent, or an edge where aux is set; that denotes that a mode set is to be done on that edge. J is the bit number in the bitmaps that corresponds to the entity that we are currently handling mode-switching for.
|
staticread |
|
staticread |
This function will allocate a new BBINFO structure, initialized with the MODE, INSN, and basic block BB parameters.
|
static |
Find all insns that need a particular mode setting, and insert the necessary mode switches. Return true if we did work.
Create the list of segments within each basic block. If NORMAL_MODE is defined, allow for two extra blocks split from the entry and exit block.
Split the edge from the entry block, so that we can note that there NORMAL_MODE is supplied.
Create the bitmap vectors.
Determine what the first use (if any) need for a mode of entity E is. This will be the mode that is anticipatable for this block. Also compute the initial transparency settings.
Pretend the mode is clobbered across abnormal edges.
Update LIVE_NOW.
Check for blocks without ANY mode requirements. N.B. because of MODE_AFTER, last_mode might still be different from no_mode.
By always making this nontransparent, we save an extra check in make_preds_opaque. We also need this to avoid confusing pre_edge_lcm when antic is cleared but transp and comp are set.
Insert a fake computing definition of MODE into entry blocks which compute no mode. This represents the mode on entry.
Set the anticipatable and computing arrays.
Calculate the optimal locations for the placement mode switches to modes with priority I.
Insert all mode sets that have been inserted by lcm.
Wherever we have moved a mode setting upwards in the flow graph, the blocks between the new setting site and the now redundant computation ceases to be transparent for any lower-priority mode of the same entity. First set the aux field of each insertion site edge non-transparent, then propagate the new non-transparency from the redundant computation upwards till we hit an insertion site or an already non-transparent block.
Do not bother to insert empty sequence.
We should not get an abnormal edge here.
Cancel the 'deleted' mode set.
Now output the remaining mode sets in all the segments.
Insert MODE_SET only if it is nonempty.
Finished. Free up all the things we've allocated.
|
static |
Record in LIVE that register REG became live. This is called via note_stores.
|
static |
|
static |
Record in LIVE that register REG died.
|
static |
Referenced by gate_mode_switching().
|
static |
These bitmaps are used for the LCM algorithm.
|
static |
|
static |