Home | History | Annotate | Line # | Download | only in rtl-ssa
movement.h revision 1.1.1.1
      1  1.1  mrg // RTL SSA utilities relating to instruction movement               -*- C++ -*-
      2  1.1  mrg // Copyright (C) 2020-2022 Free Software Foundation, Inc.
      3  1.1  mrg //
      4  1.1  mrg // This file is part of GCC.
      5  1.1  mrg //
      6  1.1  mrg // GCC is free software; you can redistribute it and/or modify it under
      7  1.1  mrg // the terms of the GNU General Public License as published by the Free
      8  1.1  mrg // Software Foundation; either version 3, or (at your option) any later
      9  1.1  mrg // version.
     10  1.1  mrg //
     11  1.1  mrg // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
     12  1.1  mrg // WARRANTY; without even the implied warranty of MERCHANTABILITY or
     13  1.1  mrg // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     14  1.1  mrg // for more details.
     15  1.1  mrg //
     16  1.1  mrg // You should have received a copy of the GNU General Public License
     17  1.1  mrg // along with GCC; see the file COPYING3.  If not see
     18  1.1  mrg // <http://www.gnu.org/licenses/>.
     19  1.1  mrg 
     20  1.1  mrg namespace rtl_ssa {
     21  1.1  mrg 
     22  1.1  mrg // Restrict movement range RANGE so that the instruction is placed later
     23  1.1  mrg // than INSN.  (The movement range is the range of instructions after which
     24  1.1  mrg // an instruction can be placed.)
     25  1.1  mrg inline insn_range_info
     26  1.1  mrg move_later_than (insn_range_info range, insn_info *insn)
     27  1.1  mrg {
     28  1.1  mrg   return { later_insn (range.first, insn), range.last };
     29  1.1  mrg }
     30  1.1  mrg 
     31  1.1  mrg // Restrict movement range RANGE so that the instruction is placed no earlier
     32  1.1  mrg // than INSN.  (The movement range is the range of instructions after which
     33  1.1  mrg // an instruction can be placed.)
     34  1.1  mrg inline insn_range_info
     35  1.1  mrg move_no_earlier_than (insn_range_info range, insn_info *insn)
     36  1.1  mrg {
     37  1.1  mrg   insn_info *first = later_insn (range.first, insn->prev_nondebug_insn ());
     38  1.1  mrg   return { first, range.last };
     39  1.1  mrg }
     40  1.1  mrg 
     41  1.1  mrg // Restrict movement range RANGE so that the instruction is placed no later
     42  1.1  mrg // than INSN.  (The movement range is the range of instructions after which
     43  1.1  mrg // an instruction can be placed.)
     44  1.1  mrg inline insn_range_info
     45  1.1  mrg move_no_later_than (insn_range_info range, insn_info *insn)
     46  1.1  mrg {
     47  1.1  mrg   return { range.first, earlier_insn (range.last, insn) };
     48  1.1  mrg }
     49  1.1  mrg 
     50  1.1  mrg // Restrict movement range RANGE so that the instruction is placed earlier
     51  1.1  mrg // than INSN.  (The movement range is the range of instructions after which
     52  1.1  mrg // an instruction can be placed.)
     53  1.1  mrg inline insn_range_info
     54  1.1  mrg move_earlier_than (insn_range_info range, insn_info *insn)
     55  1.1  mrg {
     56  1.1  mrg   insn_info *last = earlier_insn (range.last, insn->prev_nondebug_insn ());
     57  1.1  mrg   return { range.first, last };
     58  1.1  mrg }
     59  1.1  mrg 
     60  1.1  mrg // Return true if it is possible to insert a new instruction after INSN.
     61  1.1  mrg inline bool
     62  1.1  mrg can_insert_after (insn_info *insn)
     63  1.1  mrg {
     64  1.1  mrg   return insn->is_bb_head () || (insn->is_real () && !insn->is_jump ());
     65  1.1  mrg }
     66  1.1  mrg 
     67  1.1  mrg // Try to restrict move range MOVE_RANGE so that it is possible to
     68  1.1  mrg // insert INSN after both of the end points.  Return true on success,
     69  1.1  mrg // otherwise leave MOVE_RANGE in an invalid state.
     70  1.1  mrg inline bool
     71  1.1  mrg canonicalize_move_range (insn_range_info &move_range, insn_info *insn)
     72  1.1  mrg {
     73  1.1  mrg   while (move_range.first != insn && !can_insert_after (move_range.first))
     74  1.1  mrg     move_range.first = move_range.first->next_nondebug_insn ();
     75  1.1  mrg   while (move_range.last != insn && !can_insert_after (move_range.last))
     76  1.1  mrg     move_range.last = move_range.last->prev_nondebug_insn ();
     77  1.1  mrg   return bool (move_range);
     78  1.1  mrg }
     79  1.1  mrg 
     80  1.1  mrg // Try to restrict movement range MOVE_RANGE of INSN so that it can set
     81  1.1  mrg // or clobber REGNO.  Assume that if:
     82  1.1  mrg //
     83  1.1  mrg // - an instruction I2 contains another access A to REGNO; and
     84  1.1  mrg // - IGNORE (I2) is true
     85  1.1  mrg //
     86  1.1  mrg // then either:
     87  1.1  mrg //
     88  1.1  mrg // - A will be removed; or
     89  1.1  mrg // - something will ensure that the new definition of REGNO does not
     90  1.1  mrg //   interfere with A, without this having to be enforced by I1's move range.
     91  1.1  mrg //
     92  1.1  mrg // Return true on success, otherwise leave MOVE_RANGE in an invalid state.
     93  1.1  mrg //
     94  1.1  mrg // This function only works correctly for instructions that remain within
     95  1.1  mrg // the same extended basic block.
     96  1.1  mrg template<typename IgnorePredicate>
     97  1.1  mrg bool
     98  1.1  mrg restrict_movement_for_dead_range (insn_range_info &move_range,
     99  1.1  mrg 				  unsigned int regno, insn_info *insn,
    100  1.1  mrg 				  IgnorePredicate ignore)
    101  1.1  mrg {
    102  1.1  mrg   // Find a definition at or neighboring INSN.
    103  1.1  mrg   resource_info resource = full_register (regno);
    104  1.1  mrg   def_lookup dl = crtl->ssa->find_def (resource, insn);
    105  1.1  mrg 
    106  1.1  mrg   def_info *prev = dl.last_def_of_prev_group ();
    107  1.1  mrg   ebb_info *ebb = insn->ebb ();
    108  1.1  mrg   if (!prev || prev->ebb () != ebb)
    109  1.1  mrg     {
    110  1.1  mrg       // REGNO is not defined or used in EBB before INSN, but it
    111  1.1  mrg       // might be live on entry.  To keep complexity under control,
    112  1.1  mrg       // handle only these cases:
    113  1.1  mrg       //
    114  1.1  mrg       // - If the register is not live on entry to EBB, the register is
    115  1.1  mrg       //   free from the start of EBB to the first definition in EBB.
    116  1.1  mrg       //
    117  1.1  mrg       // - Otherwise, if the register is live on entry to BB, refuse
    118  1.1  mrg       //   to allocate the register.  We could in principle try to move
    119  1.1  mrg       //   the instruction to later blocks in the EBB, but it's rarely
    120  1.1  mrg       //   worth the effort, and could lead to linear complexity.
    121  1.1  mrg       //
    122  1.1  mrg       // - Otherwise, don't allow INSN to move earlier than its current
    123  1.1  mrg       //   block.  Again, we could in principle look backwards to find where
    124  1.1  mrg       //   REGNO dies, but it's rarely worth the effort.
    125  1.1  mrg       bb_info *bb = insn->bb ();
    126  1.1  mrg       insn_info *limit;
    127  1.1  mrg       if (!bitmap_bit_p (DF_LR_IN (ebb->first_bb ()->cfg_bb ()), regno))
    128  1.1  mrg 	limit = ebb->phi_insn ();
    129  1.1  mrg       else if (bitmap_bit_p (DF_LR_IN (bb->cfg_bb ()), regno))
    130  1.1  mrg 	return false;
    131  1.1  mrg       else
    132  1.1  mrg 	limit = bb->head_insn ();
    133  1.1  mrg       move_range = move_later_than (move_range, limit);
    134  1.1  mrg     }
    135  1.1  mrg   else
    136  1.1  mrg     {
    137  1.1  mrg       // Stop the instruction moving beyond the previous relevant access
    138  1.1  mrg       // to REGNO.
    139  1.1  mrg       access_info *prev_access
    140  1.1  mrg 	= last_access_ignoring (prev, ignore_clobbers::YES, ignore);
    141  1.1  mrg       if (prev_access)
    142  1.1  mrg 	move_range = move_later_than (move_range, access_insn (prev_access));
    143  1.1  mrg     }
    144  1.1  mrg 
    145  1.1  mrg   // Stop the instruction moving beyond the next relevant definition of REGNO.
    146  1.1  mrg   def_info *next = dl.matching_set_or_first_def_of_next_group ();
    147  1.1  mrg   next = first_def_ignoring (next, ignore_clobbers::YES, ignore);
    148  1.1  mrg   if (next)
    149  1.1  mrg     move_range = move_earlier_than (move_range, next->insn ());
    150  1.1  mrg 
    151  1.1  mrg   return canonicalize_move_range (move_range, insn);
    152  1.1  mrg }
    153  1.1  mrg 
    154  1.1  mrg // Try to restrict movement range MOVE_RANGE so that it is possible for the
    155  1.1  mrg // instruction being moved ("instruction I1") to perform all the definitions
    156  1.1  mrg // in DEFS while still preserving dependencies between those definitions
    157  1.1  mrg // and surrounding instructions.  Assume that if:
    158  1.1  mrg //
    159  1.1  mrg // - DEFS contains a definition D of resource R;
    160  1.1  mrg // - an instruction I2 contains another access A to R; and
    161  1.1  mrg // - IGNORE (I2) is true
    162  1.1  mrg //
    163  1.1  mrg // then either:
    164  1.1  mrg //
    165  1.1  mrg // - A will be removed; or
    166  1.1  mrg // - something will ensure that D and A maintain their current order,
    167  1.1  mrg //   without this having to be enforced by I1's move range.
    168  1.1  mrg //
    169  1.1  mrg // Return true on success, otherwise leave MOVE_RANGE in an invalid state.
    170  1.1  mrg //
    171  1.1  mrg // This function only works correctly for instructions that remain within
    172  1.1  mrg // the same extended basic block.
    173  1.1  mrg template<typename IgnorePredicate>
    174  1.1  mrg bool
    175  1.1  mrg restrict_movement_for_defs_ignoring (insn_range_info &move_range,
    176  1.1  mrg 				     def_array defs, IgnorePredicate ignore)
    177  1.1  mrg {
    178  1.1  mrg   for (def_info *def : defs)
    179  1.1  mrg     {
    180  1.1  mrg       // If the definition is a clobber, we can move it with respect
    181  1.1  mrg       // to other clobbers.
    182  1.1  mrg       //
    183  1.1  mrg       // ??? We could also do this if a definition and all its uses
    184  1.1  mrg       // are being moved at once.
    185  1.1  mrg       bool is_clobber = is_a<clobber_info *> (def);
    186  1.1  mrg 
    187  1.1  mrg       // Search back for the first unfiltered use or definition of the
    188  1.1  mrg       // same resource.
    189  1.1  mrg       access_info *access;
    190  1.1  mrg       access = prev_access_ignoring (def, ignore_clobbers (is_clobber),
    191  1.1  mrg 				     ignore);
    192  1.1  mrg       if (access)
    193  1.1  mrg 	move_range = move_later_than (move_range, access_insn (access));
    194  1.1  mrg 
    195  1.1  mrg       // Search forward for the first unfiltered use of DEF,
    196  1.1  mrg       // or the first unfiltered definition that follows DEF.
    197  1.1  mrg       //
    198  1.1  mrg       // We don't need to consider uses of following definitions, since
    199  1.1  mrg       // if IGNORE (D->insn ()) is true for some definition D, the caller
    200  1.1  mrg       // is guarantees that either
    201  1.1  mrg       //
    202  1.1  mrg       // - D will be removed, and thus its uses will be removed; or
    203  1.1  mrg       // - D will occur after DEF, and thus D's uses will also occur
    204  1.1  mrg       //   after DEF.
    205  1.1  mrg       //
    206  1.1  mrg       // This is purely a simplification: we could also process D's uses,
    207  1.1  mrg       // but we don't need to.
    208  1.1  mrg       access = next_access_ignoring (def, ignore_clobbers (is_clobber),
    209  1.1  mrg 				     ignore);
    210  1.1  mrg       if (access)
    211  1.1  mrg 	move_range = move_earlier_than (move_range, access_insn (access));
    212  1.1  mrg 
    213  1.1  mrg       // If DEF sets a hard register, take any call clobbers
    214  1.1  mrg       // into account.
    215  1.1  mrg       unsigned int regno = def->regno ();
    216  1.1  mrg       if (!HARD_REGISTER_NUM_P (regno) || is_clobber)
    217  1.1  mrg 	continue;
    218  1.1  mrg 
    219  1.1  mrg       ebb_info *ebb = def->ebb ();
    220  1.1  mrg       for (ebb_call_clobbers_info *call_group : ebb->call_clobbers ())
    221  1.1  mrg 	{
    222  1.1  mrg 	  if (!call_group->clobbers (def->resource ()))
    223  1.1  mrg 	    continue;
    224  1.1  mrg 
    225  1.1  mrg 	  // Exit now if we've already failed, and if the splay accesses
    226  1.1  mrg 	  // below would be wasted work.
    227  1.1  mrg 	  if (!move_range)
    228  1.1  mrg 	    return false;
    229  1.1  mrg 
    230  1.1  mrg 	  insn_info *insn;
    231  1.1  mrg 	  insn = prev_call_clobbers_ignoring (*call_group, def->insn (),
    232  1.1  mrg 					      ignore);
    233  1.1  mrg 	  if (insn)
    234  1.1  mrg 	    move_range = move_later_than (move_range, insn);
    235  1.1  mrg 
    236  1.1  mrg 	  insn = next_call_clobbers_ignoring (*call_group, def->insn (),
    237  1.1  mrg 					      ignore);
    238  1.1  mrg 	  if (insn)
    239  1.1  mrg 	    move_range = move_earlier_than (move_range, insn);
    240  1.1  mrg 	}
    241  1.1  mrg     }
    242  1.1  mrg 
    243  1.1  mrg   // Make sure that we don't move stores between basic blocks, since we
    244  1.1  mrg   // don't have enough information to tell whether it's safe.
    245  1.1  mrg   if (def_info *def = memory_access (defs))
    246  1.1  mrg     {
    247  1.1  mrg       move_range = move_later_than (move_range, def->bb ()->head_insn ());
    248  1.1  mrg       move_range = move_earlier_than (move_range, def->bb ()->end_insn ());
    249  1.1  mrg     }
    250  1.1  mrg 
    251  1.1  mrg   return bool (move_range);
    252  1.1  mrg }
    253  1.1  mrg 
    254  1.1  mrg // Like restrict_movement_for_defs_ignoring, but for the uses in USES.
    255  1.1  mrg template<typename IgnorePredicate>
    256  1.1  mrg bool
    257  1.1  mrg restrict_movement_for_uses_ignoring (insn_range_info &move_range,
    258  1.1  mrg 				     use_array uses, IgnorePredicate ignore)
    259  1.1  mrg {
    260  1.1  mrg   for (const use_info *use : uses)
    261  1.1  mrg     {
    262  1.1  mrg       // Ignore uses of undefined values.
    263  1.1  mrg       set_info *set = use->def ();
    264  1.1  mrg       if (!set)
    265  1.1  mrg 	continue;
    266  1.1  mrg 
    267  1.1  mrg       // Ignore uses by debug instructions.  Debug instructions are
    268  1.1  mrg       // never supposed to move, and uses by debug instructions are
    269  1.1  mrg       // never supposed to be transferred elsewhere, so we know that
    270  1.1  mrg       // the caller must be changing the uses on the debug instruction
    271  1.1  mrg       // and checking whether all new uses are available at the debug
    272  1.1  mrg       // instruction's original location.
    273  1.1  mrg       if (use->is_in_debug_insn ())
    274  1.1  mrg 	continue;
    275  1.1  mrg 
    276  1.1  mrg       // If the used value is defined by an instruction I2 for which
    277  1.1  mrg       // IGNORE (I2) is true, the caller guarantees that I2 will occur
    278  1.1  mrg       // before change.insn ().  Otherwise, make sure that the use occurs
    279  1.1  mrg       // after the definition.
    280  1.1  mrg       insn_info *insn = set->insn ();
    281  1.1  mrg       if (!ignore (insn))
    282  1.1  mrg 	move_range = move_later_than (move_range, insn);
    283  1.1  mrg 
    284  1.1  mrg       // Search forward for the first unfiltered definition that follows SET.
    285  1.1  mrg       //
    286  1.1  mrg       // We don't need to consider the uses of these definitions, since
    287  1.1  mrg       // if IGNORE (D->insn ()) is true for some definition D, the caller
    288  1.1  mrg       // is guarantees that either
    289  1.1  mrg       //
    290  1.1  mrg       // - D will be removed, and thus its uses will be removed; or
    291  1.1  mrg       // - D will occur after USE, and thus D's uses will also occur
    292  1.1  mrg       //   after USE.
    293  1.1  mrg       //
    294  1.1  mrg       // This is purely a simplification: we could also process D's uses,
    295  1.1  mrg       // but we don't need to.
    296  1.1  mrg       def_info *def;
    297  1.1  mrg       def = first_def_ignoring (set->next_def (), ignore_clobbers::NO,
    298  1.1  mrg 				ignore);
    299  1.1  mrg       if (def)
    300  1.1  mrg 	move_range = move_earlier_than (move_range, def->insn ());
    301  1.1  mrg 
    302  1.1  mrg       // If USE uses a hard register, take any call clobbers into account too.
    303  1.1  mrg       // SET will necessarily occur after any previous call clobber, so we
    304  1.1  mrg       // only need to check for later clobbers.
    305  1.1  mrg       unsigned int regno = use->regno ();
    306  1.1  mrg       if (!HARD_REGISTER_NUM_P (regno))
    307  1.1  mrg 	continue;
    308  1.1  mrg 
    309  1.1  mrg       ebb_info *ebb = use->ebb ();
    310  1.1  mrg       for (ebb_call_clobbers_info *call_group : ebb->call_clobbers ())
    311  1.1  mrg 	{
    312  1.1  mrg 	  if (!call_group->clobbers (use->resource ()))
    313  1.1  mrg 	    continue;
    314  1.1  mrg 
    315  1.1  mrg 	  if (!move_range)
    316  1.1  mrg 	    return false;
    317  1.1  mrg 
    318  1.1  mrg 	  insn_info *insn = next_call_clobbers_ignoring (*call_group,
    319  1.1  mrg 							 use->insn (), ignore);
    320  1.1  mrg 	  if (insn)
    321  1.1  mrg 	    move_range = move_earlier_than (move_range, insn);
    322  1.1  mrg 	}
    323  1.1  mrg     }
    324  1.1  mrg 
    325  1.1  mrg   // Make sure that we don't move loads into an earlier basic block.
    326  1.1  mrg   //
    327  1.1  mrg   // ??? It would be good to relax this for loads that can be safely
    328  1.1  mrg   // speculated.
    329  1.1  mrg   if (use_info *use = memory_access (uses))
    330  1.1  mrg     move_range = move_later_than (move_range, use->bb ()->head_insn ());
    331  1.1  mrg 
    332  1.1  mrg   return bool (move_range);
    333  1.1  mrg }
    334  1.1  mrg 
    335  1.1  mrg }
    336