GCC Middle and Back End API Reference
mode-switching.c File Reference

Data Structures

struct  seginfo
struct  bb_info


static struct seginfonew_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 seginfonew_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_passmake_pass_mode_switching ()


static sbitmapantic
static sbitmaptransp
static sbitmapcomp

Function Documentation

static void add_seginfo ( struct bb_info ,
struct seginfo  
static void add_seginfo ( )
   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 basic_block create_pre_exit ( )
   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 bool gate_mode_switching ( )
rtl_opt_pass* make_pass_mode_switching ( )
static void make_preds_opaque ( basic_block  ,
static void make_preds_opaque ( )
   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.  
static struct seginfo* new_seginfo ( int  ,
rtx  ,
int  ,
static struct seginfo* new_seginfo ( )
   This function will allocate a new BBINFO structure, initialized
   with the MODE, INSN, and basic block BB parameters.  
static int optimize_mode_switching ( )
   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
         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 void reg_becomes_live ( rtx  ,
const_rtx  ,
void *   
static void reg_becomes_live ( )
   Record in LIVE that register REG became live.
   This is called via note_stores.  
static void reg_dies ( rtx  ,
static void reg_dies ( )
   Record in LIVE that register REG died.  
static unsigned int rest_of_handle_mode_switching ( )

Referenced by gate_mode_switching().

Variable Documentation

sbitmap* antic
   These bitmaps are used for the LCM algorithm.  
sbitmap* comp
sbitmap* transp