Home | History | Annotate | Line # | Download | only in rtl-ssa
      1 // RTL SSA routines for changing instructions                       -*- C++ -*-
      2 // Copyright (C) 2020-2022 Free Software Foundation, Inc.
      3 //
      4 // This file is part of GCC.
      5 //
      6 // GCC is free software; you can redistribute it and/or modify it under
      7 // the terms of the GNU General Public License as published by the Free
      8 // Software Foundation; either version 3, or (at your option) any later
      9 // version.
     10 //
     11 // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
     12 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
     13 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     14 // for more details.
     15 //
     16 // You should have received a copy of the GNU General Public License
     17 // along with GCC; see the file COPYING3.  If not see
     18 // <http://www.gnu.org/licenses/>.
     19 
     20 #define INCLUDE_ALGORITHM
     21 #define INCLUDE_FUNCTIONAL
     22 #include "config.h"
     23 #include "system.h"
     24 #include "coretypes.h"
     25 #include "backend.h"
     26 #include "rtl.h"
     27 #include "df.h"
     28 #include "rtl-ssa.h"
     29 #include "rtl-ssa/internals.h"
     30 #include "rtl-ssa/internals.inl"
     31 #include "target.h"
     32 #include "predict.h"
     33 #include "memmodel.h" // Needed by emit-rtl.h
     34 #include "emit-rtl.h"
     35 #include "cfghooks.h"
     36 #include "cfgrtl.h"
     37 
     38 using namespace rtl_ssa;
     39 
     40 // See the comment above the declaration.
     41 void
     42 insn_change::print (pretty_printer *pp) const
     43 {
     44   if (m_is_deletion)
     45     {
     46       pp_string (pp, "deletion of ");
     47       pp_insn (pp, m_insn);
     48     }
     49   else
     50     {
     51       pp_string (pp, "change to ");
     52       pp_insn (pp, m_insn);
     53       pp_newline_and_indent (pp, 2);
     54       pp_string (pp, "~~~~~~~");
     55 
     56       pp_newline_and_indent (pp, 0);
     57       pp_string (pp, "new cost: ");
     58       pp_decimal_int (pp, new_cost);
     59 
     60       pp_newline_and_indent (pp, 0);
     61       pp_string (pp, "new uses:");
     62       pp_newline_and_indent (pp, 2);
     63       pp_accesses (pp, new_uses);
     64       pp_indentation (pp) -= 2;
     65 
     66       pp_newline_and_indent (pp, 0);
     67       pp_string (pp, "new defs:");
     68       pp_newline_and_indent (pp, 2);
     69       pp_accesses (pp, new_defs);
     70       pp_indentation (pp) -= 2;
     71 
     72       pp_newline_and_indent (pp, 0);
     73       pp_string (pp, "first insert-after candidate: ");
     74       move_range.first->print_identifier_and_location (pp);
     75 
     76       pp_newline_and_indent (pp, 0);
     77       pp_string (pp, "last insert-after candidate: ");
     78       move_range.last->print_identifier_and_location (pp);
     79     }
     80 }
     81 
     82 // Return a copy of access_array ACCESSES, allocating it on the
     83 // temporary obstack.
     84 access_array
     85 function_info::temp_access_array (access_array accesses)
     86 {
     87   if (accesses.empty ())
     88     return accesses;
     89 
     90   gcc_assert (obstack_object_size (&m_temp_obstack) == 0);
     91   obstack_grow (&m_temp_obstack, accesses.begin (), accesses.size_bytes ());
     92   return { static_cast<access_info **> (obstack_finish (&m_temp_obstack)),
     93 	   accesses.size () };
     94 }
     95 
     96 // See the comment above the declaration.
     97 bool
     98 function_info::verify_insn_changes (array_slice<insn_change *const> changes)
     99 {
    100   HARD_REG_SET defined_hard_regs, clobbered_hard_regs;
    101   CLEAR_HARD_REG_SET (defined_hard_regs);
    102   CLEAR_HARD_REG_SET (clobbered_hard_regs);
    103 
    104   insn_info *min_insn = m_first_insn;
    105   for (insn_change *change : changes)
    106     if (!change->is_deletion ())
    107       {
    108 	// Make sure that the changes can be kept in their current order
    109 	// while honoring all of the move ranges.
    110 	min_insn = later_insn (min_insn, change->move_range.first);
    111 	while (min_insn != change->insn () && !can_insert_after (min_insn))
    112 	  min_insn = min_insn->next_nondebug_insn ();
    113 	if (*min_insn > *change->move_range.last)
    114 	  {
    115 	    if (dump_file && (dump_flags & TDF_DETAILS))
    116 	      fprintf (dump_file, "no viable insn position assignment\n");
    117 	    return false;
    118 	  }
    119 
    120 	// If recog introduced new clobbers of a register as part of
    121 	// the matching process, make sure that they don't conflict
    122 	// with any other new definitions or uses of the register.
    123 	// (We have already checked that they don't conflict with
    124 	// unchanging definitions and uses.)
    125 	for (use_info *use : change->new_uses)
    126 	  {
    127 	    unsigned int regno = use->regno ();
    128 	    if (HARD_REGISTER_NUM_P (regno)
    129 		&& TEST_HARD_REG_BIT (clobbered_hard_regs, regno))
    130 	      {
    131 		if (dump_file && (dump_flags & TDF_DETAILS))
    132 		  fprintf (dump_file, "register %d would be clobbered"
    133 			   " while it is still live\n", regno);
    134 		return false;
    135 	      }
    136 	  }
    137 	for (def_info *def : change->new_defs)
    138 	  {
    139 	    unsigned int regno = def->regno ();
    140 	    if (HARD_REGISTER_NUM_P (regno))
    141 	      {
    142 		if (def->m_is_temp)
    143 		  {
    144 		    // This is a clobber introduced by recog.
    145 		    gcc_checking_assert (is_a<clobber_info *> (def));
    146 		    if (TEST_HARD_REG_BIT (defined_hard_regs, regno))
    147 		      {
    148 			if (dump_file && (dump_flags & TDF_DETAILS))
    149 			  fprintf (dump_file, "conflicting definitions of"
    150 				   " register %d\n", regno);
    151 			return false;
    152 		      }
    153 		    SET_HARD_REG_BIT (clobbered_hard_regs, regno);
    154 		  }
    155 		else if (is_a<set_info *> (def))
    156 		  {
    157 		    // REGNO now has a defined value.
    158 		    SET_HARD_REG_BIT (defined_hard_regs, regno);
    159 		    CLEAR_HARD_REG_BIT (clobbered_hard_regs, regno);
    160 		  }
    161 	      }
    162 	  }
    163       }
    164   return true;
    165 }
    166 
    167 // See the comment above the declaration.
    168 bool
    169 rtl_ssa::changes_are_worthwhile (array_slice<insn_change *const> changes,
    170 				 bool strict_p)
    171 {
    172   unsigned int old_cost = 0;
    173   unsigned int new_cost = 0;
    174   for (insn_change *change : changes)
    175     {
    176       old_cost += change->old_cost ();
    177       if (!change->is_deletion ())
    178 	{
    179 	  basic_block cfg_bb = change->bb ()->cfg_bb ();
    180 	  change->new_cost = insn_cost (change->rtl (),
    181 					optimize_bb_for_speed_p (cfg_bb));
    182 	  new_cost += change->new_cost;
    183 	}
    184     }
    185   bool ok_p = (strict_p ? new_cost < old_cost : new_cost <= old_cost);
    186   if (dump_file && (dump_flags & TDF_DETAILS))
    187     {
    188       fprintf (dump_file, "original cost");
    189       char sep = '=';
    190       for (const insn_change *change : changes)
    191 	{
    192 	  fprintf (dump_file, " %c %d", sep, change->old_cost ());
    193 	  sep = '+';
    194 	}
    195       fprintf (dump_file, ", replacement cost");
    196       sep = '=';
    197       for (const insn_change *change : changes)
    198 	if (!change->is_deletion ())
    199 	  {
    200 	    fprintf (dump_file, " %c %d", sep, change->new_cost);
    201 	    sep = '+';
    202 	  }
    203       fprintf (dump_file, "; %s\n",
    204 	       ok_p ? "keeping replacement" : "rejecting replacement");
    205     }
    206   if (!ok_p)
    207     return false;
    208 
    209   return true;
    210 }
    211 
    212 // Update the REG_NOTES of INSN, whose pattern has just been changed.
    213 static void
    214 update_notes (rtx_insn *insn)
    215 {
    216   for (rtx *note_ptr = &REG_NOTES (insn); *note_ptr; )
    217     {
    218       rtx note = *note_ptr;
    219       bool keep_p = true;
    220       switch (REG_NOTE_KIND (note))
    221 	{
    222 	case REG_EQUAL:
    223 	case REG_EQUIV:
    224 	case REG_NOALIAS:
    225 	  keep_p = (single_set (insn) != nullptr);
    226 	  break;
    227 
    228 	case REG_UNUSED:
    229 	case REG_DEAD:
    230 	  // These notes are stale.  We'll recompute REG_UNUSED notes
    231 	  // after the update.
    232 	  keep_p = false;
    233 	  break;
    234 
    235 	default:
    236 	  break;
    237 	}
    238       if (keep_p)
    239 	note_ptr = &XEXP (*note_ptr, 1);
    240       else
    241 	{
    242 	  *note_ptr = XEXP (*note_ptr, 1);
    243 	  free_EXPR_LIST_node (note);
    244 	}
    245     }
    246 }
    247 
    248 // Pick a location for CHANGE's instruction and return the instruction
    249 // after which it should be placed.
    250 static insn_info *
    251 choose_insn_placement (insn_change &change)
    252 {
    253   gcc_checking_assert (change.move_range);
    254 
    255   insn_info *insn = change.insn ();
    256   insn_info *first = change.move_range.first;
    257   insn_info *last = change.move_range.last;
    258 
    259   // Quick(ish) exit if there is only one possible choice.
    260   if (first == last)
    261     return first;
    262   if (first == insn->prev_nondebug_insn () && last == insn)
    263     return insn;
    264 
    265   // For now just use the closest valid choice to the original instruction.
    266   // If the register usage has changed significantly, it might instead be
    267   // better to try to take register pressure into account.
    268   insn_info *closest = change.move_range.clamp_insn_to_range (insn);
    269   while (closest != insn && !can_insert_after (closest))
    270     closest = closest->next_nondebug_insn ();
    271   return closest;
    272 }
    273 
    274 // Record any changes related to CHANGE that need to be queued for later.
    275 void
    276 function_info::possibly_queue_changes (insn_change &change)
    277 {
    278   insn_info *insn = change.insn ();
    279   rtx_insn *rtl = insn->rtl ();
    280 
    281   // If the instruction could previously throw, we eventually need to call
    282   // purge_dead_edges to check whether things have changed.
    283   if (find_reg_note (rtl, REG_EH_REGION, nullptr))
    284     bitmap_set_bit (m_need_to_purge_dead_edges, insn->bb ()->index ());
    285 
    286   auto needs_pending_update = [&]()
    287     {
    288       // If an instruction became a no-op without the pass explicitly
    289       // deleting it, queue the deletion for later.  Removing the
    290       // instruction on the fly would require an update to all instructions
    291       // that use the result of the move, which would be a potential source
    292       // of quadraticness.  Also, definitions shouldn't disappear under
    293       // the pass's feet.
    294       if (INSN_CODE (rtl) == NOOP_MOVE_INSN_CODE)
    295 	return true;
    296 
    297       // If any jumps got turned into unconditional jumps or nops, we need
    298       // to update the CFG accordingly.
    299       if (JUMP_P (rtl)
    300 	  && (returnjump_p (rtl) || any_uncondjump_p (rtl))
    301 	  && !single_succ_p (insn->bb ()->cfg_bb ()))
    302 	return true;
    303 
    304       // If a previously conditional trap now always fires, execution
    305       // terminates at that point.
    306       rtx pattern = PATTERN (rtl);
    307       if (GET_CODE (pattern) == TRAP_IF
    308 	  && XEXP (pattern, 0) == const1_rtx)
    309 	return true;
    310 
    311       return false;
    312     };
    313 
    314   if (needs_pending_update ()
    315       && bitmap_set_bit (m_queued_insn_update_uids, insn->uid ()))
    316     {
    317       gcc_assert (!change.is_deletion ());
    318       m_queued_insn_updates.safe_push (insn);
    319     }
    320 }
    321 
    322 // Remove the instruction described by CHANGE from the underlying RTL
    323 // and from the insn_info list.
    324 static void
    325 delete_insn (insn_change &change)
    326 {
    327   insn_info *insn = change.insn ();
    328   rtx_insn *rtl = change.rtl ();
    329   if (dump_file && (dump_flags & TDF_DETAILS))
    330     fprintf (dump_file, "deleting insn %d\n", insn->uid ());
    331   set_insn_deleted (rtl);
    332 }
    333 
    334 // Move the RTL instruction associated with CHANGE so that it comes
    335 // immediately after AFTER.
    336 static void
    337 move_insn (insn_change &change, insn_info *after)
    338 {
    339   rtx_insn *rtl = change.rtl ();
    340   rtx_insn *after_rtl = after->rtl ();
    341   if (dump_file && (dump_flags & TDF_DETAILS))
    342     fprintf (dump_file, "moving insn %d after insn %d\n",
    343 	     INSN_UID (rtl), INSN_UID (after_rtl));
    344 
    345   // At the moment we don't support moving instructions between EBBs,
    346   // but this would be worth adding if it's useful.
    347   insn_info *insn = change.insn ();
    348   gcc_assert (after->ebb () == insn->ebb ());
    349   bb_info *bb = after->bb ();
    350   basic_block cfg_bb = bb->cfg_bb ();
    351 
    352   if (insn->bb () != bb)
    353     // Force DF to mark the old block as dirty.
    354     df_insn_delete (rtl);
    355   ::remove_insn (rtl);
    356   ::add_insn_after (rtl, after_rtl, cfg_bb);
    357 }
    358 
    359 // The instruction associated with CHANGE is being changed in-place.
    360 // Update the DF information for its new pattern.
    361 static void
    362 update_insn_in_place (insn_change &change)
    363 {
    364   insn_info *insn = change.insn ();
    365   if (dump_file && (dump_flags & TDF_DETAILS))
    366     fprintf (dump_file, "updating insn %d in-place\n", insn->uid ());
    367   df_insn_rescan (change.rtl ());
    368 }
    369 
    370 // Finalize the new list of definitions and uses in CHANGE, removing
    371 // any uses and definitions that are no longer needed, and converting
    372 // pending clobbers into actual definitions.
    373 void
    374 function_info::finalize_new_accesses (insn_change &change)
    375 {
    376   insn_info *insn = change.insn ();
    377 
    378   // Get a list of all the things that the instruction now references.
    379   vec_rtx_properties properties;
    380   properties.add_insn (insn->rtl (), true);
    381 
    382   // Build up the new list of definitions.
    383   for (rtx_obj_reference ref : properties.refs ())
    384     if (ref.is_write ())
    385       {
    386 	def_info *def = find_access (change.new_defs, ref.regno);
    387 	gcc_assert (def);
    388 	if (def->m_is_temp)
    389 	  {
    390 	    // At present, the only temporary instruction definitions we
    391 	    // create are clobbers, such as those added during recog.
    392 	    gcc_assert (is_a<clobber_info *> (def));
    393 	    def = allocate<clobber_info> (change.insn (), ref.regno);
    394 	  }
    395 	else if (!def->m_has_been_superceded)
    396 	  {
    397 	    // This is a second or subsequent definition.
    398 	    // See function_info::record_def for a discussion of when
    399 	    // this can happen.
    400 	    def->record_reference (ref, false);
    401 	    continue;
    402 	  }
    403 	else
    404 	  {
    405 	    def->m_has_been_superceded = false;
    406 
    407 	    // Clobbers can move around, so remove them from their current
    408 	    // position and them back in their final position.
    409 	    //
    410 	    // At the moment, we don't allow sets to move relative to other
    411 	    // definitions of the same resource, so we can leave those where
    412 	    // they are.  It might be useful to relax this in future.
    413 	    // The main complication is that removing a set would potentially
    414 	    // fuse two adjoining clobber_groups, and adding the set back
    415 	    // would require the group to be split again.
    416 	    if (is_a<clobber_info *> (def))
    417 	      remove_def (def);
    418 	    else if (ref.is_reg ())
    419 	      def->set_mode (ref.mode);
    420 	    def->set_insn (insn);
    421 	  }
    422 	def->record_reference (ref, true);
    423 	m_temp_defs.safe_push (def);
    424       }
    425 
    426   // Also keep any explicitly-recorded call clobbers, which are deliberately
    427   // excluded from the vec_rtx_properties.  Calls shouldn't move, so we can
    428   // keep the definitions in their current position.
    429   for (def_info *def : change.new_defs)
    430     if (def->m_has_been_superceded && def->is_call_clobber ())
    431       {
    432 	def->m_has_been_superceded = false;
    433 	def->set_insn (insn);
    434 	m_temp_defs.safe_push (def);
    435       }
    436 
    437   // Install the new list of definitions in CHANGE.
    438   sort_accesses (m_temp_defs);
    439   access_array accesses = temp_access_array (m_temp_defs);
    440   change.new_defs = def_array (accesses);
    441   m_temp_defs.truncate (0);
    442 
    443   // Create temporary copies of use_infos that are already attached to
    444   // other insns, which could happen if the uses come from unchanging
    445   // insns or if they have been used by earlier changes.  Doing this
    446   // makes it easier to detect multiple reads below.
    447   auto *unshared_uses_base = XOBNEWVEC (&m_temp_obstack, access_info *,
    448 					change.new_uses.size ());
    449   unsigned int i = 0;
    450   for (use_info *use : change.new_uses)
    451     {
    452       if (!use->m_has_been_superceded)
    453 	{
    454 	  use = allocate_temp<use_info> (insn, use->resource (), use->def ());
    455 	  use->m_has_been_superceded = true;
    456 	  use->m_is_temp = true;
    457 	}
    458       unshared_uses_base[i++] = use;
    459     }
    460   auto unshared_uses = use_array (unshared_uses_base, change.new_uses.size ());
    461 
    462   // Add (possibly temporary) uses to m_temp_uses for each resource.
    463   // If there are multiple references to the same resource, aggregate
    464   // information in the modes and flags.
    465   for (rtx_obj_reference ref : properties.refs ())
    466     if (ref.is_read ())
    467       {
    468 	unsigned int regno = ref.regno;
    469 	machine_mode mode = ref.is_reg () ? ref.mode : BLKmode;
    470 	use_info *use = find_access (unshared_uses, ref.regno);
    471 	gcc_assert (use);
    472 	if (use->m_has_been_superceded)
    473 	  {
    474 	    // This is the first reference to the resource.
    475 	    bool is_temp = use->m_is_temp;
    476 	    *use = use_info (insn, resource_info { mode, regno }, use->def ());
    477 	    use->m_is_temp = is_temp;
    478 	    use->record_reference (ref, true);
    479 	    m_temp_uses.safe_push (use);
    480 	  }
    481 	else
    482 	  {
    483 	    // Record the mode of the largest use.  The choice is arbitrary if
    484 	    // the instruction (unusually) references the same register in two
    485 	    // different but equal-sized modes.
    486 	    if (HARD_REGISTER_NUM_P (regno)
    487 		&& partial_subreg_p (use->mode (), mode))
    488 	      use->set_mode (mode);
    489 	    use->record_reference (ref, false);
    490 	  }
    491       }
    492 
    493   // Replace any temporary uses and definitions with real ones.
    494   for (unsigned int i = 0; i < m_temp_uses.length (); ++i)
    495     {
    496       auto *use = as_a<use_info *> (m_temp_uses[i]);
    497       if (use->m_is_temp)
    498 	{
    499 	  m_temp_uses[i] = use = allocate<use_info> (*use);
    500 	  use->m_is_temp = false;
    501 	  set_info *def = use->def ();
    502 	  // Handle cases in which the value was previously not used
    503 	  // within the block.
    504 	  if (def && def->m_is_temp)
    505 	    {
    506 	      phi_info *phi = as_a<phi_info *> (def);
    507 	      gcc_assert (phi->is_degenerate ());
    508 	      phi = create_degenerate_phi (phi->ebb (), phi->input_value (0));
    509 	      use->set_def (phi);
    510 	    }
    511 	}
    512     }
    513 
    514   // Install the new list of definitions in CHANGE.
    515   sort_accesses (m_temp_uses);
    516   change.new_uses = use_array (temp_access_array (m_temp_uses));
    517   m_temp_uses.truncate (0);
    518 
    519   // Record the new instruction-wide properties.
    520   insn->set_properties (properties);
    521 }
    522 
    523 // Copy information from CHANGE to its underlying insn_info, given that
    524 // the insn_info has already been placed appropriately.
    525 void
    526 function_info::apply_changes_to_insn (insn_change &change)
    527 {
    528   insn_info *insn = change.insn ();
    529   if (change.is_deletion ())
    530     {
    531       insn->set_accesses (nullptr, 0, 0);
    532       return;
    533     }
    534 
    535   // Copy the cost.
    536   insn->set_cost (change.new_cost);
    537 
    538   // Add all clobbers.  Sets and call clobbers never move relative to
    539   // other definitions, so are OK as-is.
    540   for (def_info *def : change.new_defs)
    541     if (is_a<clobber_info *> (def) && !def->is_call_clobber ())
    542       add_def (def);
    543 
    544   // Add all uses, now that their position is final.
    545   for (use_info *use : change.new_uses)
    546     add_use (use);
    547 
    548   // Copy the uses and definitions.
    549   unsigned int num_defs = change.new_defs.size ();
    550   unsigned int num_uses = change.new_uses.size ();
    551   if (num_defs + num_uses <= insn->num_defs () + insn->num_uses ())
    552     insn->copy_accesses (change.new_defs, change.new_uses);
    553   else
    554     {
    555       access_array_builder builder (&m_obstack);
    556       builder.reserve (num_defs + num_uses);
    557 
    558       for (def_info *def : change.new_defs)
    559 	builder.quick_push (def);
    560       for (use_info *use : change.new_uses)
    561 	builder.quick_push (use);
    562 
    563       insn->set_accesses (builder.finish ().begin (), num_defs, num_uses);
    564     }
    565 
    566   add_reg_unused_notes (insn);
    567 }
    568 
    569 // Add a temporary placeholder instruction after AFTER.
    570 insn_info *
    571 function_info::add_placeholder_after (insn_info *after)
    572 {
    573   insn_info *insn = allocate_temp<insn_info> (after->bb (), nullptr, -1);
    574   add_insn_after (insn, after);
    575   return insn;
    576 }
    577 
    578 // See the comment above the declaration.
    579 void
    580 function_info::change_insns (array_slice<insn_change *> changes)
    581 {
    582   auto watermark = temp_watermark ();
    583 
    584   insn_info *min_insn = m_first_insn;
    585   for (insn_change *change : changes)
    586     {
    587       // Tentatively mark all the old uses and definitions for deletion.
    588       for (use_info *use : change->old_uses ())
    589 	{
    590 	  use->m_has_been_superceded = true;
    591 	  remove_use (use);
    592 	}
    593       for (def_info *def : change->old_defs ())
    594 	def->m_has_been_superceded = true;
    595 
    596       if (!change->is_deletion ())
    597 	{
    598 	  // Remove any notes that are no longer relevant.
    599 	  update_notes (change->rtl ());
    600 
    601 	  // Make sure that the placement of this instruction would still
    602 	  // leave room for previous instructions.
    603 	  change->move_range = move_later_than (change->move_range, min_insn);
    604 	  if (!canonicalize_move_range (change->move_range, change->insn ()))
    605 	    // verify_insn_changes is supposed to make sure that this holds.
    606 	    gcc_unreachable ();
    607 	  min_insn = later_insn (min_insn, change->move_range.first);
    608 	}
    609     }
    610 
    611   // Walk backwards through the changes, allocating specific positions
    612   // to each one.  Update the underlying RTL and its associated DF
    613   // information.
    614   insn_info *following_insn = nullptr;
    615   auto_vec<insn_info *, 16> placeholders;
    616   placeholders.safe_grow_cleared (changes.size ());
    617   for (unsigned int i = changes.size (); i-- > 0;)
    618     {
    619       insn_change &change = *changes[i];
    620       insn_info *placeholder = nullptr;
    621       possibly_queue_changes (change);
    622       if (change.is_deletion ())
    623 	delete_insn (change);
    624       else
    625 	{
    626 	  // Make sure that this instruction comes before later ones.
    627 	  if (following_insn)
    628 	    {
    629 	      change.move_range = move_earlier_than (change.move_range,
    630 						     following_insn);
    631 	      if (!canonicalize_move_range (change.move_range,
    632 					    change.insn ()))
    633 		// verify_insn_changes is supposed to make sure that this
    634 		// holds.
    635 		gcc_unreachable ();
    636 	    }
    637 
    638 	  // Decide which instruction INSN should go after.
    639 	  insn_info *after = choose_insn_placement (change);
    640 
    641 	  // If INSN is moving, insert a placeholder insn_info at the
    642 	  // new location.  We can't move INSN itself yet because it
    643 	  // might still be referenced by earlier move ranges.
    644 	  insn_info *insn = change.insn ();
    645 	  if (after == insn || after == insn->prev_nondebug_insn ())
    646 	    {
    647 	      update_insn_in_place (change);
    648 	      following_insn = insn;
    649 	    }
    650 	  else
    651 	    {
    652 	      move_insn (change, after);
    653 	      placeholder = add_placeholder_after (after);
    654 	      following_insn = placeholder;
    655 	    }
    656 
    657 	  // Finalize the new list of accesses for the change.  Don't install
    658 	  // them yet, so that we still have access to the old lists below.
    659 	  finalize_new_accesses (change);
    660 	}
    661       placeholders[i] = placeholder;
    662     }
    663 
    664   // Remove all definitions that are no longer needed.  After the above,
    665   // such definitions should no longer have any registered users.
    666   //
    667   // In particular, this means that consumers must handle debug
    668   // instructions before removing a set.
    669   for (insn_change *change : changes)
    670     for (def_info *def : change->old_defs ())
    671       if (def->m_has_been_superceded)
    672 	{
    673 	  auto *set = dyn_cast<set_info *> (def);
    674 	  gcc_assert (!set || !set->has_any_uses ());
    675 	  remove_def (def);
    676 	}
    677 
    678   // Move the insn_infos to their new locations.
    679   for (unsigned int i = 0; i < changes.size (); ++i)
    680     {
    681       insn_change &change = *changes[i];
    682       insn_info *insn = change.insn ();
    683       if (change.is_deletion ())
    684 	remove_insn (insn);
    685       else if (insn_info *placeholder = placeholders[i])
    686 	{
    687 	  // Check if earlier movements turned a move into a no-op.
    688 	  if (placeholder->prev_nondebug_insn () == insn
    689 	      || placeholder->next_nondebug_insn () == insn)
    690 	    {
    691 	      remove_insn (placeholder);
    692 	      placeholders[i] = nullptr;
    693 	    }
    694 	  else
    695 	    {
    696 	      // Remove the placeholder first so that we have a wider range of
    697 	      // program points when inserting INSN.
    698 	      insn_info *after = placeholder->prev_any_insn ();
    699 	      remove_insn (insn);
    700 	      remove_insn (placeholder);
    701 	      insn->set_bb (after->bb ());
    702 	      add_insn_after (insn, after);
    703 	    }
    704 	}
    705     }
    706 
    707   // Finally apply the changes to the underlying insn_infos.
    708   for (insn_change *change : changes)
    709     apply_changes_to_insn (*change);
    710 }
    711 
    712 // See the comment above the declaration.
    713 void
    714 function_info::change_insn (insn_change &change)
    715 {
    716   insn_change *changes[] = { &change };
    717   return change_insns (changes);
    718 }
    719 
    720 // Try to adjust CHANGE so that its pattern can include clobber rtx CLOBBER.
    721 // Return true on success.
    722 //
    723 // ADD_REGNO_CLOBBER is a specialization of function_info::add_regno_clobber
    724 // for a specific caller-provided predicate.
    725 static bool
    726 add_clobber (insn_change &change, add_regno_clobber_fn add_regno_clobber,
    727 	     rtx clobber)
    728 {
    729   rtx pat = PATTERN (change.rtl ());
    730   gcc_assert (GET_CODE (clobber) == CLOBBER);
    731   rtx dest = XEXP (clobber, 0);
    732   if (GET_CODE (dest) == SCRATCH)
    733     {
    734       if (reload_completed)
    735 	{
    736 	  if (dump_file && (dump_flags & TDF_DETAILS))
    737 	    {
    738 	      // ??? Maybe we could try to do some RA here?
    739 	      fprintf (dump_file, "instruction requires a scratch"
    740 		       " after reload:\n");
    741 	      print_rtl_single (dump_file, pat);
    742 	    }
    743 	  return false;
    744 	}
    745       return true;
    746     }
    747 
    748   gcc_assert (REG_P (dest));
    749   for (unsigned int regno = REGNO (dest); regno != END_REGNO (dest); ++regno)
    750     if (!add_regno_clobber (change, regno))
    751       {
    752 	if (dump_file && (dump_flags & TDF_DETAILS))
    753 	  {
    754 	    fprintf (dump_file, "cannot clobber live register %d in:\n",
    755 		     regno);
    756 	    print_rtl_single (dump_file, pat);
    757 	  }
    758 	return false;
    759       }
    760   return true;
    761 }
    762 
    763 // Try to recognize the new form of the insn associated with CHANGE,
    764 // adding any clobbers that are necessary to make the instruction match
    765 // an .md pattern.  Return true on success.
    766 //
    767 // ADD_REGNO_CLOBBER is a specialization of function_info::add_regno_clobber
    768 // for a specific caller-provided predicate.
    769 static bool
    770 recog_level2 (insn_change &change, add_regno_clobber_fn add_regno_clobber)
    771 {
    772   insn_change_watermark insn_watermark;
    773   rtx_insn *rtl = change.rtl ();
    774   rtx pat = PATTERN (rtl);
    775   int num_clobbers = 0;
    776   int icode = -1;
    777   bool asm_p = asm_noperands (pat) >= 0;
    778   if (asm_p)
    779     {
    780       if (!check_asm_operands (pat))
    781 	{
    782 	  if (dump_file && (dump_flags & TDF_DETAILS))
    783 	    {
    784 	      fprintf (dump_file, "failed to match this asm instruction:\n");
    785 	      print_rtl_single (dump_file, pat);
    786 	    }
    787 	  return false;
    788 	}
    789     }
    790   else if (noop_move_p (rtl))
    791     {
    792       INSN_CODE (rtl) = NOOP_MOVE_INSN_CODE;
    793       if (dump_file && (dump_flags & TDF_DETAILS))
    794 	{
    795 	  fprintf (dump_file, "instruction becomes a no-op:\n");
    796 	  print_rtl_single (dump_file, pat);
    797 	}
    798       insn_watermark.keep ();
    799       return true;
    800     }
    801   else
    802     {
    803       icode = ::recog (pat, rtl, &num_clobbers);
    804       if (icode < 0)
    805 	{
    806 	  if (dump_file && (dump_flags & TDF_DETAILS))
    807 	    {
    808 	      fprintf (dump_file, "failed to match this instruction:\n");
    809 	      print_rtl_single (dump_file, pat);
    810 	    }
    811 	  return false;
    812 	}
    813     }
    814 
    815   auto prev_new_defs = change.new_defs;
    816   auto prev_move_range = change.move_range;
    817   if (num_clobbers > 0)
    818     {
    819       // ??? It would be good to have a way of recycling the rtxes on failure,
    820       // but any attempt to cache old PARALLELs would at best be a half
    821       // measure, since add_clobbers would still generate fresh clobbers
    822       // each time.  It would be better to have a more general recycling
    823       // mechanism that all rtx passes can use.
    824       rtvec newvec;
    825       int oldlen;
    826       if (GET_CODE (pat) == PARALLEL)
    827 	{
    828 	  oldlen = XVECLEN (pat, 0);
    829 	  newvec = rtvec_alloc (num_clobbers + oldlen);
    830 	  for (int i = 0; i < oldlen; ++i)
    831 	    RTVEC_ELT (newvec, i) = XVECEXP (pat, 0, i);
    832 	}
    833       else
    834 	{
    835 	  oldlen = 1;
    836 	  newvec = rtvec_alloc (num_clobbers + oldlen);
    837 	  RTVEC_ELT (newvec, 0) = pat;
    838 	}
    839       rtx newpat = gen_rtx_PARALLEL (VOIDmode, newvec);
    840       add_clobbers (newpat, icode);
    841       validate_change (rtl, &PATTERN (rtl), newpat, true);
    842       for (int i = 0; i < num_clobbers; ++i)
    843 	if (!add_clobber (change, add_regno_clobber,
    844 			  XVECEXP (newpat, 0, oldlen + i)))
    845 	  {
    846 	    change.new_defs = prev_new_defs;
    847 	    change.move_range = prev_move_range;
    848 	    return false;
    849 	  }
    850 
    851       pat = newpat;
    852     }
    853 
    854   INSN_CODE (rtl) = icode;
    855   if (reload_completed)
    856     {
    857       extract_insn (rtl);
    858       if (!constrain_operands (1, get_preferred_alternatives (rtl)))
    859 	{
    860 	  if (dump_file && (dump_flags & TDF_DETAILS))
    861 	    {
    862 	      if (asm_p)
    863 		fprintf (dump_file, "asm does not match its constraints:\n");
    864 	      else if (const char *name = get_insn_name (icode))
    865 		fprintf (dump_file, "instruction does not match the"
    866 			 " constraints for %s:\n", name);
    867 	      else
    868 		fprintf (dump_file, "instruction does not match its"
    869 			 " constraints:\n");
    870 	      print_rtl_single (dump_file, pat);
    871 	    }
    872 	  change.new_defs = prev_new_defs;
    873 	  change.move_range = prev_move_range;
    874 	  return false;
    875 	}
    876     }
    877 
    878   if (dump_file && (dump_flags & TDF_DETAILS))
    879     {
    880       const char *name;
    881       if (!asm_p && (name = get_insn_name (icode)))
    882 	fprintf (dump_file, "successfully matched this instruction "
    883 		 "to %s:\n", name);
    884       else
    885 	fprintf (dump_file, "successfully matched this instruction:\n");
    886       print_rtl_single (dump_file, pat);
    887     }
    888 
    889   insn_watermark.keep ();
    890   return true;
    891 }
    892 
    893 // Try to recognize the new form of the insn associated with CHANGE,
    894 // adding and removing clobbers as necessary to make the instruction
    895 // match an .md pattern.  Return true on success, otherwise leave
    896 // CHANGE as it was on entry.
    897 //
    898 // ADD_REGNO_CLOBBER is a specialization of function_info::add_regno_clobber
    899 // for a specific caller-provided predicate.
    900 bool
    901 rtl_ssa::recog_internal (insn_change &change,
    902 			 add_regno_clobber_fn add_regno_clobber)
    903 {
    904   // Accept all changes to debug instructions.
    905   insn_info *insn = change.insn ();
    906   if (insn->is_debug_insn ())
    907     return true;
    908 
    909   rtx_insn *rtl = insn->rtl ();
    910   rtx pat = PATTERN (rtl);
    911   if (GET_CODE (pat) == PARALLEL && asm_noperands (pat) < 0)
    912     {
    913       // Try to remove trailing (clobber (scratch)) rtxes, since the new form
    914       // of the instruction might not need those scratches.  recog will add
    915       // back any that are needed.
    916       int len = XVECLEN (pat, 0);
    917       int new_len = len;
    918       while (new_len > 0
    919 	     && GET_CODE (XVECEXP (pat, 0, new_len - 1)) == CLOBBER
    920 	     && GET_CODE (XEXP (XVECEXP (pat, 0, new_len - 1), 0)) == SCRATCH)
    921 	new_len -= 1;
    922 
    923       int old_num_changes = num_validated_changes ();
    924       validate_change_xveclen (rtl, &PATTERN (rtl), new_len, true);
    925       if (recog_level2 (change, add_regno_clobber))
    926 	return true;
    927       cancel_changes (old_num_changes);
    928 
    929       // Try to remove all trailing clobbers.  For example, a pattern that
    930       // used to clobber the flags might no longer need to do so.
    931       int prev_len = new_len;
    932       while (new_len > 0
    933 	     && GET_CODE (XVECEXP (pat, 0, new_len - 1)) == CLOBBER)
    934 	new_len -= 1;
    935       if (new_len != prev_len)
    936 	{
    937 	  validate_change_xveclen (rtl, &PATTERN (rtl), new_len, true);
    938 	  if (recog_level2 (change, add_regno_clobber))
    939 	    return true;
    940 	  cancel_changes (old_num_changes);
    941 	}
    942       return false;
    943     }
    944 
    945   return recog_level2 (change, add_regno_clobber);
    946 }
    947 
    948 // See the comment above the declaration.
    949 bool
    950 function_info::perform_pending_updates ()
    951 {
    952   bool changed_cfg = false;
    953   bool changed_jumps = false;
    954   for (insn_info *insn : m_queued_insn_updates)
    955     {
    956       rtx_insn *rtl = insn->rtl ();
    957       if (JUMP_P (rtl))
    958 	{
    959 	  if (INSN_CODE (rtl) == NOOP_MOVE_INSN_CODE)
    960 	    {
    961 	      ::delete_insn (rtl);
    962 	      bitmap_set_bit (m_need_to_purge_dead_edges,
    963 			      insn->bb ()->index ());
    964 	    }
    965 	  else if (returnjump_p (rtl) || any_uncondjump_p (rtl))
    966 	    {
    967 	      mark_jump_label (PATTERN (rtl), rtl, 0);
    968 	      update_cfg_for_uncondjump (rtl);
    969 	      changed_cfg = true;
    970 	      changed_jumps = true;
    971 	    }
    972 	}
    973       else if (INSN_CODE (rtl) == NOOP_MOVE_INSN_CODE)
    974 	::delete_insn (rtl);
    975       else
    976 	{
    977 	  rtx pattern = PATTERN (rtl);
    978 	  if (GET_CODE (pattern) == TRAP_IF
    979 	      && XEXP (pattern, 0) == const1_rtx)
    980 	    {
    981 	      remove_edge (split_block (BLOCK_FOR_INSN (rtl), rtl));
    982 	      emit_barrier_after_bb (BLOCK_FOR_INSN (rtl));
    983 	      changed_cfg = true;
    984 	    }
    985 	}
    986     }
    987 
    988   unsigned int index;
    989   bitmap_iterator bi;
    990   EXECUTE_IF_SET_IN_BITMAP (m_need_to_purge_dead_edges, 0, index, bi)
    991     if (purge_dead_edges (BASIC_BLOCK_FOR_FN (m_fn, index)))
    992       changed_cfg = true;
    993 
    994   if (changed_jumps)
    995     // This uses its own timevar internally, so we don't need to push
    996     // one ourselves.
    997     rebuild_jump_labels (get_insns ());
    998 
    999   bitmap_clear (m_need_to_purge_dead_edges);
   1000   bitmap_clear (m_queued_insn_update_uids);
   1001   m_queued_insn_updates.truncate (0);
   1002 
   1003   if (changed_cfg)
   1004     {
   1005       free_dominance_info (CDI_DOMINATORS);
   1006       free_dominance_info (CDI_POST_DOMINATORS);
   1007     }
   1008 
   1009   return changed_cfg;
   1010 }
   1011 
   1012 // Print a description of CHANGE to PP.
   1013 void
   1014 rtl_ssa::pp_insn_change (pretty_printer *pp, const insn_change &change)
   1015 {
   1016   change.print (pp);
   1017 }
   1018 
   1019 // Print a description of CHANGE to FILE.
   1020 void
   1021 dump (FILE *file, const insn_change &change)
   1022 {
   1023   dump_using (file, pp_insn_change, change);
   1024 }
   1025 
   1026 // Debug interface to the dump routine above.
   1027 void debug (const insn_change &x) { dump (stderr, x); }
   1028