ada: Rename Is_Constr_Subt_For_UN_Aliased flag
[official-gcc.git] / gcc / rtl-ssa / changes.cc
blob443d0575df5b6e7e3fa385afae46e2927b425458
1 // RTL SSA routines for changing instructions -*- C++ -*-
2 // Copyright (C) 2020-2023 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.
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.
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/>.
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 #include "sreal.h"
39 using namespace rtl_ssa;
41 // See the comment above the declaration.
42 void
43 insn_change::print (pretty_printer *pp) const
45 if (m_is_deletion)
47 pp_string (pp, "deletion of ");
48 pp_insn (pp, m_insn);
50 else
52 pp_string (pp, "change to ");
53 pp_insn (pp, m_insn);
54 pp_newline_and_indent (pp, 2);
55 pp_string (pp, "~~~~~~~");
57 pp_newline_and_indent (pp, 0);
58 pp_string (pp, "new cost: ");
59 pp_decimal_int (pp, new_cost);
61 pp_newline_and_indent (pp, 0);
62 pp_string (pp, "new uses:");
63 pp_newline_and_indent (pp, 2);
64 pp_accesses (pp, new_uses);
65 pp_indentation (pp) -= 2;
67 pp_newline_and_indent (pp, 0);
68 pp_string (pp, "new defs:");
69 pp_newline_and_indent (pp, 2);
70 pp_accesses (pp, new_defs);
71 pp_indentation (pp) -= 2;
73 pp_newline_and_indent (pp, 0);
74 pp_string (pp, "first insert-after candidate: ");
75 move_range.first->print_identifier_and_location (pp);
77 pp_newline_and_indent (pp, 0);
78 pp_string (pp, "last insert-after candidate: ");
79 move_range.last->print_identifier_and_location (pp);
83 // Return a copy of access_array ACCESSES, allocating it on the
84 // temporary obstack.
85 access_array
86 function_info::temp_access_array (access_array accesses)
88 if (accesses.empty ())
89 return accesses;
91 gcc_assert (obstack_object_size (&m_temp_obstack) == 0);
92 obstack_grow (&m_temp_obstack, accesses.begin (), accesses.size_bytes ());
93 return { static_cast<access_info **> (obstack_finish (&m_temp_obstack)),
94 accesses.size () };
97 // See the comment above the declaration.
98 bool
99 function_info::verify_insn_changes (array_slice<insn_change *const> changes)
101 HARD_REG_SET defined_hard_regs, clobbered_hard_regs;
102 CLEAR_HARD_REG_SET (defined_hard_regs);
103 CLEAR_HARD_REG_SET (clobbered_hard_regs);
105 insn_info *min_insn = m_first_insn;
106 for (insn_change *change : changes)
107 if (!change->is_deletion ())
109 // Make sure that the changes can be kept in their current order
110 // while honoring all of the move ranges.
111 min_insn = later_insn (min_insn, change->move_range.first);
112 while (min_insn != change->insn () && !can_insert_after (min_insn))
113 min_insn = min_insn->next_nondebug_insn ();
114 if (*min_insn > *change->move_range.last)
116 if (dump_file && (dump_flags & TDF_DETAILS))
117 fprintf (dump_file, "no viable insn position assignment\n");
118 return false;
121 // If recog introduced new clobbers of a register as part of
122 // the matching process, make sure that they don't conflict
123 // with any other new definitions or uses of the register.
124 // (We have already checked that they don't conflict with
125 // unchanging definitions and uses.)
126 for (use_info *use : change->new_uses)
128 unsigned int regno = use->regno ();
129 if (HARD_REGISTER_NUM_P (regno)
130 && TEST_HARD_REG_BIT (clobbered_hard_regs, regno))
132 if (dump_file && (dump_flags & TDF_DETAILS))
133 fprintf (dump_file, "register %d would be clobbered"
134 " while it is still live\n", regno);
135 return false;
138 for (def_info *def : change->new_defs)
140 unsigned int regno = def->regno ();
141 if (HARD_REGISTER_NUM_P (regno))
143 if (def->m_is_temp)
145 // This is a clobber introduced by recog.
146 gcc_checking_assert (is_a<clobber_info *> (def));
147 if (TEST_HARD_REG_BIT (defined_hard_regs, regno))
149 if (dump_file && (dump_flags & TDF_DETAILS))
150 fprintf (dump_file, "conflicting definitions of"
151 " register %d\n", regno);
152 return false;
154 SET_HARD_REG_BIT (clobbered_hard_regs, regno);
156 else if (is_a<set_info *> (def))
158 // REGNO now has a defined value.
159 SET_HARD_REG_BIT (defined_hard_regs, regno);
160 CLEAR_HARD_REG_BIT (clobbered_hard_regs, regno);
165 return true;
168 // See the comment above the declaration.
169 bool
170 rtl_ssa::changes_are_worthwhile (array_slice<insn_change *const> changes,
171 bool strict_p)
173 unsigned int old_cost = 0;
174 unsigned int new_cost = 0;
175 sreal weighted_old_cost = 0;
176 sreal weighted_new_cost = 0;
177 auto entry_count = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count;
178 for (insn_change *change : changes)
180 old_cost += change->old_cost ();
181 basic_block cfg_bb = change->bb ()->cfg_bb ();
182 bool for_speed = optimize_bb_for_speed_p (cfg_bb);
183 if (for_speed)
184 weighted_old_cost += (cfg_bb->count.to_sreal_scale (entry_count)
185 * change->old_cost ());
186 if (!change->is_deletion ())
188 change->new_cost = insn_cost (change->rtl (), for_speed);
189 new_cost += change->new_cost;
190 if (for_speed)
191 weighted_new_cost += (cfg_bb->count.to_sreal_scale (entry_count)
192 * change->new_cost);
195 bool ok_p;
196 if (weighted_new_cost != weighted_old_cost)
197 ok_p = weighted_new_cost < weighted_old_cost;
198 else if (strict_p)
199 ok_p = new_cost < old_cost;
200 else
201 ok_p = new_cost <= old_cost;
202 if (dump_file && (dump_flags & TDF_DETAILS))
204 fprintf (dump_file, "original cost");
205 char sep = '=';
206 for (const insn_change *change : changes)
208 fprintf (dump_file, " %c %d", sep, change->old_cost ());
209 sep = '+';
211 if (weighted_old_cost != 0)
212 fprintf (dump_file, " (weighted: %f)", weighted_old_cost.to_double ());
213 fprintf (dump_file, ", replacement cost");
214 sep = '=';
215 for (const insn_change *change : changes)
216 if (!change->is_deletion ())
218 fprintf (dump_file, " %c %d", sep, change->new_cost);
219 sep = '+';
221 if (weighted_new_cost != 0)
222 fprintf (dump_file, " (weighted: %f)", weighted_new_cost.to_double ());
223 fprintf (dump_file, "; %s\n",
224 ok_p ? "keeping replacement" : "rejecting replacement");
226 if (!ok_p)
227 return false;
229 return true;
232 // SET has been deleted. Clean up all remaining uses. Such uses are
233 // either dead phis or now-redundant live-out uses.
234 void
235 function_info::process_uses_of_deleted_def (set_info *set)
237 if (!set->has_any_uses ())
238 return;
240 auto *use = *set->all_uses ().begin ();
243 auto *next_use = use->next_use ();
244 if (use->is_in_phi ())
246 // This call will not recurse.
247 process_uses_of_deleted_def (use->phi ());
248 delete_phi (use->phi ());
250 else
252 gcc_assert (use->is_live_out_use ());
253 remove_use (use);
255 use = next_use;
257 while (use);
258 gcc_assert (!set->has_any_uses ());
261 // Update the REG_NOTES of INSN, whose pattern has just been changed.
262 static void
263 update_notes (rtx_insn *insn)
265 for (rtx *note_ptr = &REG_NOTES (insn); *note_ptr; )
267 rtx note = *note_ptr;
268 bool keep_p = true;
269 switch (REG_NOTE_KIND (note))
271 case REG_EQUAL:
272 case REG_EQUIV:
273 case REG_NOALIAS:
274 keep_p = (single_set (insn) != nullptr);
275 break;
277 case REG_UNUSED:
278 case REG_DEAD:
279 // These notes are stale. We'll recompute REG_UNUSED notes
280 // after the update.
281 keep_p = false;
282 break;
284 default:
285 break;
287 if (keep_p)
288 note_ptr = &XEXP (*note_ptr, 1);
289 else
291 *note_ptr = XEXP (*note_ptr, 1);
292 free_EXPR_LIST_node (note);
297 // Pick a location for CHANGE's instruction and return the instruction
298 // after which it should be placed.
299 static insn_info *
300 choose_insn_placement (insn_change &change)
302 gcc_checking_assert (change.move_range);
304 insn_info *insn = change.insn ();
305 insn_info *first = change.move_range.first;
306 insn_info *last = change.move_range.last;
308 // Quick(ish) exit if there is only one possible choice.
309 if (first == last)
310 return first;
311 if (first == insn->prev_nondebug_insn () && last == insn)
312 return insn;
314 // For now just use the closest valid choice to the original instruction.
315 // If the register usage has changed significantly, it might instead be
316 // better to try to take register pressure into account.
317 insn_info *closest = change.move_range.clamp_insn_to_range (insn);
318 while (closest != insn && !can_insert_after (closest))
319 closest = closest->next_nondebug_insn ();
320 return closest;
323 // Record any changes related to CHANGE that need to be queued for later.
324 void
325 function_info::possibly_queue_changes (insn_change &change)
327 insn_info *insn = change.insn ();
328 rtx_insn *rtl = insn->rtl ();
330 // If the instruction could previously throw, we eventually need to call
331 // purge_dead_edges to check whether things have changed.
332 if (find_reg_note (rtl, REG_EH_REGION, nullptr))
333 bitmap_set_bit (m_need_to_purge_dead_edges, insn->bb ()->index ());
335 auto needs_pending_update = [&]()
337 // If an instruction became a no-op without the pass explicitly
338 // deleting it, queue the deletion for later. Removing the
339 // instruction on the fly would require an update to all instructions
340 // that use the result of the move, which would be a potential source
341 // of quadraticness. Also, definitions shouldn't disappear under
342 // the pass's feet.
343 if (INSN_CODE (rtl) == NOOP_MOVE_INSN_CODE)
344 return true;
346 // If any jumps got turned into unconditional jumps or nops, we need
347 // to update the CFG accordingly.
348 if (JUMP_P (rtl)
349 && (returnjump_p (rtl) || any_uncondjump_p (rtl))
350 && !single_succ_p (insn->bb ()->cfg_bb ()))
351 return true;
353 // If a previously conditional trap now always fires, execution
354 // terminates at that point.
355 rtx pattern = PATTERN (rtl);
356 if (GET_CODE (pattern) == TRAP_IF
357 && XEXP (pattern, 0) == const1_rtx)
358 return true;
360 return false;
363 if (needs_pending_update ()
364 && bitmap_set_bit (m_queued_insn_update_uids, insn->uid ()))
366 gcc_assert (!change.is_deletion ());
367 m_queued_insn_updates.safe_push (insn);
371 // Remove the instruction described by CHANGE from the underlying RTL
372 // and from the insn_info list.
373 static void
374 delete_insn (insn_change &change)
376 insn_info *insn = change.insn ();
377 rtx_insn *rtl = change.rtl ();
378 if (dump_file && (dump_flags & TDF_DETAILS))
379 fprintf (dump_file, "deleting insn %d\n", insn->uid ());
380 set_insn_deleted (rtl);
383 // Move the RTL instruction associated with CHANGE so that it comes
384 // immediately after AFTER.
385 static void
386 move_insn (insn_change &change, insn_info *after)
388 rtx_insn *rtl = change.rtl ();
389 rtx_insn *after_rtl = after->rtl ();
390 if (dump_file && (dump_flags & TDF_DETAILS))
391 fprintf (dump_file, "moving insn %d after insn %d\n",
392 INSN_UID (rtl), INSN_UID (after_rtl));
394 // At the moment we don't support moving instructions between EBBs,
395 // but this would be worth adding if it's useful.
396 insn_info *insn = change.insn ();
398 bb_info *bb = after->bb ();
399 basic_block cfg_bb = bb->cfg_bb ();
401 if (!insn->is_temporary ())
403 gcc_assert (after->ebb () == insn->ebb ());
405 if (insn->bb () != bb)
406 // Force DF to mark the old block as dirty.
407 df_insn_delete (rtl);
408 ::remove_insn (rtl);
411 ::add_insn_after (rtl, after_rtl, cfg_bb);
414 // The instruction associated with CHANGE is being changed in-place.
415 // Update the DF information for its new pattern.
416 static void
417 update_insn_in_place (insn_change &change)
419 insn_info *insn = change.insn ();
420 if (dump_file && (dump_flags & TDF_DETAILS))
421 fprintf (dump_file, "updating insn %d in-place\n", insn->uid ());
422 df_insn_rescan (change.rtl ());
425 // Finalize the new list of definitions and uses in CHANGE, removing
426 // any uses and definitions that are no longer needed, and converting
427 // pending clobbers into actual definitions.
429 // POS gives the final position of INSN, which hasn't yet been moved into
430 // place.
431 void
432 function_info::finalize_new_accesses (insn_change &change, insn_info *pos)
434 insn_info *insn = change.insn ();
436 // Get a list of all the things that the instruction now references.
437 vec_rtx_properties properties;
438 properties.add_insn (insn->rtl (), true);
440 // Build up the new list of definitions.
441 for (rtx_obj_reference ref : properties.refs ())
442 if (ref.is_write ())
444 def_info *def = find_access (change.new_defs, ref.regno);
445 gcc_assert (def);
447 if (def->m_is_temp && is_a<set_info *> (def) && def->last_def ())
449 // For temporary sets being added with this change, we keep track of
450 // the corresponding permanent def using the last_def link.
452 // So if we have one of these, follow it to get the permanent def.
453 def = def->last_def ();
454 gcc_assert (!def->m_is_temp && !def->m_has_been_superceded);
457 if (def->m_is_temp)
459 if (is_a<clobber_info *> (def))
460 def = allocate<clobber_info> (change.insn (), ref.regno);
461 else if (is_a<set_info *> (def))
463 // Install the permanent set in the last_def link of the
464 // temporary def. This allows us to find the permanent def
465 // later in case we see a second write to the same resource.
466 def_info *perm_def = allocate<set_info> (change.insn (),
467 def->resource ());
468 def->set_last_def (perm_def);
469 def = perm_def;
471 else
472 gcc_unreachable ();
474 else if (!def->m_has_been_superceded)
476 // This is a second or subsequent definition.
477 // See function_info::record_def for a discussion of when
478 // this can happen.
479 def->record_reference (ref, false);
480 continue;
482 else
484 def->m_has_been_superceded = false;
486 // Clobbers can move around, so remove them from their current
487 // position and them back in their final position.
489 // At the moment, we don't allow sets to move relative to other
490 // definitions of the same resource, so we can leave those where
491 // they are. It might be useful to relax this in future.
492 // The main complication is that removing a set would potentially
493 // fuse two adjoining clobber_groups, and adding the set back
494 // would require the group to be split again.
495 if (is_a<clobber_info *> (def))
496 remove_def (def);
497 else if (ref.is_reg ())
498 def->set_mode (ref.mode);
499 def->set_insn (insn);
501 def->record_reference (ref, true);
502 m_temp_defs.safe_push (def);
505 // Also keep any explicitly-recorded call clobbers, which are deliberately
506 // excluded from the vec_rtx_properties. Calls shouldn't move, so we can
507 // keep the definitions in their current position.
509 // If the change describes a set of memory, but the pattern doesn't
510 // reference memory, keep the set anyway. This can happen if the
511 // old pattern was a parallel that contained a memory clobber, and if
512 // the new pattern was recognized without that clobber. Keeping the
513 // set avoids a linear-complexity update to the set's users.
515 // ??? We could queue an update so that these bogus clobbers are
516 // removed later.
517 for (def_info *def : change.new_defs)
518 if (def->m_has_been_superceded
519 && (def->is_call_clobber () || def->is_mem ()))
521 def->m_has_been_superceded = false;
522 def->set_insn (insn);
523 m_temp_defs.safe_push (def);
526 // Install the new list of definitions in CHANGE.
527 sort_accesses (m_temp_defs);
528 access_array accesses = temp_access_array (m_temp_defs);
529 change.new_defs = def_array (accesses);
530 m_temp_defs.truncate (0);
532 // Create temporary copies of use_infos that are already attached to
533 // other insns, which could happen if the uses come from unchanging
534 // insns or if they have been used by earlier changes. Doing this
535 // makes it easier to detect multiple reads below.
536 auto *unshared_uses_base = XOBNEWVEC (&m_temp_obstack, access_info *,
537 change.new_uses.size ());
538 unsigned int i = 0;
539 for (use_info *use : change.new_uses)
541 if (!use->m_has_been_superceded)
543 use = allocate_temp<use_info> (insn, use->resource (), use->def ());
544 use->m_has_been_superceded = true;
545 use->m_is_temp = true;
547 unshared_uses_base[i++] = use;
549 auto unshared_uses = use_array (unshared_uses_base, change.new_uses.size ());
551 // Add (possibly temporary) uses to m_temp_uses for each resource.
552 // If there are multiple references to the same resource, aggregate
553 // information in the modes and flags.
554 use_info *mem_use = nullptr;
555 for (rtx_obj_reference ref : properties.refs ())
556 if (ref.is_read ())
558 unsigned int regno = ref.regno;
559 machine_mode mode = ref.is_reg () ? ref.mode : BLKmode;
560 use_info *use = find_access (unshared_uses, ref.regno);
561 if (!use)
563 // For now, we only support inferring uses of mem.
564 gcc_assert (regno == MEM_REGNO);
566 if (mem_use)
568 mem_use->record_reference (ref, false);
569 continue;
572 resource_info resource { mode, regno };
573 auto def = find_def (resource, pos).prev_def (pos);
574 auto set = safe_dyn_cast <set_info *> (def);
575 gcc_assert (set);
576 mem_use = allocate<use_info> (insn, resource, set);
577 mem_use->record_reference (ref, true);
578 m_temp_uses.safe_push (mem_use);
579 continue;
582 if (use->m_has_been_superceded)
584 // This is the first reference to the resource.
585 bool is_temp = use->m_is_temp;
586 *use = use_info (insn, resource_info { mode, regno }, use->def ());
587 use->m_is_temp = is_temp;
588 use->record_reference (ref, true);
589 m_temp_uses.safe_push (use);
591 else
593 // Record the mode of the largest use. The choice is arbitrary if
594 // the instruction (unusually) references the same register in two
595 // different but equal-sized modes.
596 if (HARD_REGISTER_NUM_P (regno)
597 && partial_subreg_p (use->mode (), mode))
598 use->set_mode (mode);
599 use->record_reference (ref, false);
603 // Replace any temporary uses and definitions with real ones.
604 for (unsigned int i = 0; i < m_temp_uses.length (); ++i)
606 auto *use = as_a<use_info *> (m_temp_uses[i]);
607 if (use->m_is_temp)
609 m_temp_uses[i] = use = allocate<use_info> (*use);
610 use->m_is_temp = false;
611 set_info *def = use->def ();
612 // Handle cases in which the value was previously not used
613 // within the block.
614 if (def && def->m_is_temp)
616 phi_info *phi = as_a<phi_info *> (def);
617 gcc_assert (phi->is_degenerate ());
618 phi = create_degenerate_phi (phi->ebb (), phi->input_value (0));
619 use->set_def (phi);
624 // Install the new list of uses in CHANGE.
625 sort_accesses (m_temp_uses);
626 change.new_uses = use_array (temp_access_array (m_temp_uses));
627 m_temp_uses.truncate (0);
629 // Record the new instruction-wide properties.
630 insn->set_properties (properties);
633 // Copy information from CHANGE to its underlying insn_info, given that
634 // the insn_info has already been placed appropriately.
635 void
636 function_info::apply_changes_to_insn (insn_change &change)
638 insn_info *insn = change.insn ();
639 if (change.is_deletion ())
641 insn->set_accesses (nullptr, 0, 0);
642 return;
645 // Copy the cost.
646 insn->set_cost (change.new_cost);
648 // Add all clobbers. Sets and call clobbers never move relative to
649 // other definitions, so are OK as-is.
650 for (def_info *def : change.new_defs)
651 if (is_a<clobber_info *> (def) && !def->is_call_clobber ())
652 add_def (def);
654 // Add all uses, now that their position is final.
655 for (use_info *use : change.new_uses)
656 add_use (use);
658 // Copy the uses and definitions.
659 unsigned int num_defs = change.new_defs.size ();
660 unsigned int num_uses = change.new_uses.size ();
661 if (num_defs + num_uses <= insn->num_defs () + insn->num_uses ())
662 insn->copy_accesses (change.new_defs, change.new_uses);
663 else
665 access_array_builder builder (&m_obstack);
666 builder.reserve (num_defs + num_uses);
668 for (def_info *def : change.new_defs)
669 builder.quick_push (def);
670 for (use_info *use : change.new_uses)
671 builder.quick_push (use);
673 insn->set_accesses (builder.finish ().begin (), num_defs, num_uses);
676 insn->m_is_temp = false;
679 // Add a temporary placeholder instruction after AFTER.
680 insn_info *
681 function_info::add_placeholder_after (insn_info *after)
683 insn_info *insn = allocate_temp<insn_info> (after->bb (), nullptr, -1);
684 add_insn_after (insn, after);
685 return insn;
688 // See the comment above the declaration.
689 void
690 function_info::change_insns (array_slice<insn_change *> changes)
692 auto watermark = temp_watermark ();
694 insn_info *min_insn = m_first_insn;
695 for (insn_change *change : changes)
697 // Tentatively mark all the old uses and definitions for deletion.
698 for (use_info *use : change->old_uses ())
700 use->m_has_been_superceded = true;
701 remove_use (use);
703 for (def_info *def : change->old_defs ())
704 def->m_has_been_superceded = true;
706 if (!change->is_deletion ())
708 // Remove any notes that are no longer relevant.
709 if (!change->insn ()->m_is_temp)
710 update_notes (change->rtl ());
712 // Make sure that the placement of this instruction would still
713 // leave room for previous instructions.
714 change->move_range = move_later_than (change->move_range, min_insn);
715 if (!canonicalize_move_range (change->move_range, change->insn ()))
716 // verify_insn_changes is supposed to make sure that this holds.
717 gcc_unreachable ();
718 min_insn = later_insn (min_insn, change->move_range.first);
720 if (change->insn ()->m_is_temp)
722 change->m_insn = allocate<insn_info> (change->insn ()->bb (),
723 change->rtl (),
724 change->insn_uid ());
726 // Set the flag again so subsequent logic is aware.
727 // It will be cleared later on.
728 change->m_insn->m_is_temp = true;
733 // Walk backwards through the changes, allocating specific positions
734 // to each one. Update the underlying RTL and its associated DF
735 // information.
736 insn_info *following_insn = nullptr;
737 auto_vec<insn_info *, 16> placeholders;
738 placeholders.safe_grow_cleared (changes.size ());
739 for (unsigned int i = changes.size (); i-- > 0;)
741 insn_change &change = *changes[i];
742 insn_info *placeholder = nullptr;
743 possibly_queue_changes (change);
744 if (change.is_deletion ())
745 delete_insn (change);
746 else
748 // Make sure that this instruction comes before later ones.
749 if (following_insn)
751 change.move_range = move_earlier_than (change.move_range,
752 following_insn);
753 if (!canonicalize_move_range (change.move_range,
754 change.insn ()))
755 // verify_insn_changes is supposed to make sure that this
756 // holds.
757 gcc_unreachable ();
760 // Decide which instruction INSN should go after.
761 insn_info *after = choose_insn_placement (change);
763 // If INSN is moving, insert a placeholder insn_info at the
764 // new location. We can't move INSN itself yet because it
765 // might still be referenced by earlier move ranges.
766 insn_info *insn = change.insn ();
767 if (after == insn || after == insn->prev_nondebug_insn ())
769 update_insn_in_place (change);
770 following_insn = insn;
772 else
774 move_insn (change, after);
775 placeholder = add_placeholder_after (after);
776 following_insn = placeholder;
779 // Finalize the new list of accesses for the change. Don't install
780 // them yet, so that we still have access to the old lists below.
781 finalize_new_accesses (change,
782 placeholder ? placeholder : insn);
784 placeholders[i] = placeholder;
787 // Remove all definitions that are no longer needed. After the above,
788 // the only uses of such definitions should be dead phis and now-redundant
789 // live-out uses.
791 // In particular, this means that consumers must handle debug
792 // instructions before removing a set.
793 for (insn_change *change : changes)
794 for (def_info *def : change->old_defs ())
795 if (def->m_has_been_superceded)
797 auto *set = dyn_cast<set_info *> (def);
798 if (set && set->has_any_uses ())
799 process_uses_of_deleted_def (set);
800 remove_def (def);
803 // Move the insn_infos to their new locations.
804 for (unsigned int i = 0; i < changes.size (); ++i)
806 insn_change &change = *changes[i];
807 insn_info *insn = change.insn ();
808 if (change.is_deletion ())
810 if (rtx_insn *rtl = insn->rtl ())
811 ::remove_insn (rtl); // Remove the underlying RTL insn.
812 remove_insn (insn);
814 else if (insn_info *placeholder = placeholders[i])
816 // Check if earlier movements turned a move into a no-op.
817 if (placeholder->prev_nondebug_insn () == insn
818 || placeholder->next_nondebug_insn () == insn)
820 remove_insn (placeholder);
821 placeholders[i] = nullptr;
823 else
825 // Remove the placeholder first so that we have a wider range of
826 // program points when inserting INSN.
827 insn_info *after = placeholder->prev_any_insn ();
828 if (!insn->is_temporary ())
829 remove_insn (insn);
830 remove_insn (placeholder);
831 insn->set_bb (after->bb ());
832 add_insn_after (insn, after);
837 // Apply the changes to the underlying insn_infos.
838 for (insn_change *change : changes)
839 apply_changes_to_insn (*change);
841 // Now that the insns and accesses are up to date, add any REG_UNUSED notes.
842 for (insn_change *change : changes)
843 if (!change->is_deletion ())
844 add_reg_unused_notes (change->insn ());
847 // See the comment above the declaration.
848 void
849 function_info::change_insn (insn_change &change)
851 insn_change *changes[] = { &change };
852 return change_insns (changes);
855 // Try to adjust CHANGE so that its pattern can include clobber rtx CLOBBER.
856 // Return true on success.
858 // ADD_REGNO_CLOBBER is a specialization of function_info::add_regno_clobber
859 // for a specific caller-provided predicate.
860 static bool
861 add_clobber (insn_change &change, add_regno_clobber_fn add_regno_clobber,
862 rtx clobber)
864 rtx pat = PATTERN (change.rtl ());
865 gcc_assert (GET_CODE (clobber) == CLOBBER);
866 rtx dest = XEXP (clobber, 0);
867 if (GET_CODE (dest) == SCRATCH)
869 if (reload_completed)
871 if (dump_file && (dump_flags & TDF_DETAILS))
873 // ??? Maybe we could try to do some RA here?
874 fprintf (dump_file, "instruction requires a scratch"
875 " after reload:\n");
876 print_rtl_single (dump_file, pat);
878 return false;
880 return true;
883 gcc_assert (REG_P (dest));
884 for (unsigned int regno = REGNO (dest); regno != END_REGNO (dest); ++regno)
885 if (!add_regno_clobber (change, regno))
887 if (dump_file && (dump_flags & TDF_DETAILS))
889 fprintf (dump_file, "cannot clobber live register %d in:\n",
890 regno);
891 print_rtl_single (dump_file, pat);
893 return false;
895 return true;
898 // Try to recognize the new form of the insn associated with CHANGE,
899 // adding any clobbers that are necessary to make the instruction match
900 // an .md pattern. Return true on success.
902 // ADD_REGNO_CLOBBER is a specialization of function_info::add_regno_clobber
903 // for a specific caller-provided predicate.
904 static bool
905 recog_level2 (insn_change &change, add_regno_clobber_fn add_regno_clobber)
907 insn_change_watermark insn_watermark;
908 rtx_insn *rtl = change.rtl ();
909 rtx pat = PATTERN (rtl);
910 int num_clobbers = 0;
911 int icode = -1;
912 bool asm_p = asm_noperands (pat) >= 0;
913 if (asm_p)
915 if (!check_asm_operands (pat))
917 if (dump_file && (dump_flags & TDF_DETAILS))
919 fprintf (dump_file, "failed to match this asm instruction:\n");
920 print_rtl_single (dump_file, pat);
922 return false;
925 else if (noop_move_p (rtl))
927 INSN_CODE (rtl) = NOOP_MOVE_INSN_CODE;
928 if (dump_file && (dump_flags & TDF_DETAILS))
930 fprintf (dump_file, "instruction becomes a no-op:\n");
931 print_rtl_single (dump_file, pat);
933 insn_watermark.keep ();
934 return true;
936 else
938 icode = ::recog (pat, rtl, &num_clobbers);
939 if (icode < 0)
941 if (dump_file && (dump_flags & TDF_DETAILS))
943 fprintf (dump_file, "failed to match this instruction:\n");
944 print_rtl_single (dump_file, pat);
946 return false;
950 auto prev_new_defs = change.new_defs;
951 auto prev_move_range = change.move_range;
952 if (num_clobbers > 0)
954 // ??? It would be good to have a way of recycling the rtxes on failure,
955 // but any attempt to cache old PARALLELs would at best be a half
956 // measure, since add_clobbers would still generate fresh clobbers
957 // each time. It would be better to have a more general recycling
958 // mechanism that all rtx passes can use.
959 rtvec newvec;
960 int oldlen;
961 if (GET_CODE (pat) == PARALLEL)
963 oldlen = XVECLEN (pat, 0);
964 newvec = rtvec_alloc (num_clobbers + oldlen);
965 for (int i = 0; i < oldlen; ++i)
966 RTVEC_ELT (newvec, i) = XVECEXP (pat, 0, i);
968 else
970 oldlen = 1;
971 newvec = rtvec_alloc (num_clobbers + oldlen);
972 RTVEC_ELT (newvec, 0) = pat;
974 rtx newpat = gen_rtx_PARALLEL (VOIDmode, newvec);
975 add_clobbers (newpat, icode);
976 validate_change (rtl, &PATTERN (rtl), newpat, true);
977 for (int i = 0; i < num_clobbers; ++i)
978 if (!add_clobber (change, add_regno_clobber,
979 XVECEXP (newpat, 0, oldlen + i)))
981 change.new_defs = prev_new_defs;
982 change.move_range = prev_move_range;
983 return false;
986 pat = newpat;
989 // check_asm_operands checks the constraints after RA, so we don't
990 // need to do it again.
991 INSN_CODE (rtl) = icode;
992 if (reload_completed && !asm_p)
994 extract_insn (rtl);
995 if (!constrain_operands (1, get_preferred_alternatives (rtl)))
997 if (dump_file && (dump_flags & TDF_DETAILS))
999 if (asm_p)
1000 fprintf (dump_file, "asm does not match its constraints:\n");
1001 else if (const char *name = get_insn_name (icode))
1002 fprintf (dump_file, "instruction does not match the"
1003 " constraints for %s:\n", name);
1004 else
1005 fprintf (dump_file, "instruction does not match its"
1006 " constraints:\n");
1007 print_rtl_single (dump_file, pat);
1009 change.new_defs = prev_new_defs;
1010 change.move_range = prev_move_range;
1011 return false;
1015 if (dump_file && (dump_flags & TDF_DETAILS))
1017 const char *name;
1018 if (!asm_p && (name = get_insn_name (icode)))
1019 fprintf (dump_file, "successfully matched this instruction "
1020 "to %s:\n", name);
1021 else
1022 fprintf (dump_file, "successfully matched this instruction:\n");
1023 print_rtl_single (dump_file, pat);
1026 insn_watermark.keep ();
1027 return true;
1030 // Try to recognize the new form of the insn associated with CHANGE,
1031 // adding and removing clobbers as necessary to make the instruction
1032 // match an .md pattern. Return true on success, otherwise leave
1033 // CHANGE as it was on entry.
1035 // ADD_REGNO_CLOBBER is a specialization of function_info::add_regno_clobber
1036 // for a specific caller-provided predicate.
1037 bool
1038 rtl_ssa::recog_internal (insn_change &change,
1039 add_regno_clobber_fn add_regno_clobber)
1041 // Accept all changes to debug instructions.
1042 insn_info *insn = change.insn ();
1043 if (insn->is_debug_insn ())
1044 return true;
1046 rtx_insn *rtl = insn->rtl ();
1047 rtx pat = PATTERN (rtl);
1048 if (GET_CODE (pat) == PARALLEL && asm_noperands (pat) < 0)
1050 // Try to remove trailing (clobber (scratch)) rtxes, since the new form
1051 // of the instruction might not need those scratches. recog will add
1052 // back any that are needed.
1053 int len = XVECLEN (pat, 0);
1054 int new_len = len;
1055 while (new_len > 0
1056 && GET_CODE (XVECEXP (pat, 0, new_len - 1)) == CLOBBER
1057 && GET_CODE (XEXP (XVECEXP (pat, 0, new_len - 1), 0)) == SCRATCH)
1058 new_len -= 1;
1060 int old_num_changes = num_validated_changes ();
1061 validate_change_xveclen (rtl, &PATTERN (rtl), new_len, true);
1062 if (recog_level2 (change, add_regno_clobber))
1063 return true;
1064 cancel_changes (old_num_changes);
1066 // Try to remove all trailing clobbers. For example, a pattern that
1067 // used to clobber the flags might no longer need to do so.
1068 int prev_len = new_len;
1069 while (new_len > 0
1070 && GET_CODE (XVECEXP (pat, 0, new_len - 1)) == CLOBBER)
1071 new_len -= 1;
1072 if (new_len != prev_len)
1074 validate_change_xveclen (rtl, &PATTERN (rtl), new_len, true);
1075 if (recog_level2 (change, add_regno_clobber))
1076 return true;
1077 cancel_changes (old_num_changes);
1079 return false;
1082 return recog_level2 (change, add_regno_clobber);
1085 // See the comment above the declaration.
1086 bool
1087 function_info::perform_pending_updates ()
1089 bool changed_cfg = false;
1090 bool changed_jumps = false;
1091 for (insn_info *insn : m_queued_insn_updates)
1093 rtx_insn *rtl = insn->rtl ();
1094 if (NOTE_P (rtl))
1095 // The insn was later optimized away, typically to a NOTE_INSN_DELETED.
1097 else if (JUMP_P (rtl))
1099 if (INSN_CODE (rtl) == NOOP_MOVE_INSN_CODE)
1101 ::delete_insn (rtl);
1102 bitmap_set_bit (m_need_to_purge_dead_edges,
1103 insn->bb ()->index ());
1105 else if (returnjump_p (rtl) || any_uncondjump_p (rtl))
1107 mark_jump_label (PATTERN (rtl), rtl, 0);
1108 update_cfg_for_uncondjump (rtl);
1109 changed_cfg = true;
1110 changed_jumps = true;
1113 else if (INSN_CODE (rtl) == NOOP_MOVE_INSN_CODE)
1114 ::delete_insn (rtl);
1115 else
1117 rtx pattern = PATTERN (rtl);
1118 if (GET_CODE (pattern) == TRAP_IF
1119 && XEXP (pattern, 0) == const1_rtx)
1121 remove_edge (split_block (BLOCK_FOR_INSN (rtl), rtl));
1122 emit_barrier_after_bb (BLOCK_FOR_INSN (rtl));
1123 changed_cfg = true;
1128 unsigned int index;
1129 bitmap_iterator bi;
1130 EXECUTE_IF_SET_IN_BITMAP (m_need_to_purge_dead_edges, 0, index, bi)
1131 if (purge_dead_edges (BASIC_BLOCK_FOR_FN (m_fn, index)))
1132 changed_cfg = true;
1134 if (changed_jumps)
1135 // This uses its own timevar internally, so we don't need to push
1136 // one ourselves.
1137 rebuild_jump_labels (get_insns ());
1139 bitmap_clear (m_need_to_purge_dead_edges);
1140 bitmap_clear (m_queued_insn_update_uids);
1141 m_queued_insn_updates.truncate (0);
1143 if (changed_cfg)
1145 free_dominance_info (CDI_DOMINATORS);
1146 free_dominance_info (CDI_POST_DOMINATORS);
1149 return changed_cfg;
1152 insn_info *
1153 function_info::create_insn (obstack_watermark &watermark,
1154 rtx_code insn_code,
1155 rtx pat)
1157 rtx_insn *rti = nullptr;
1159 // TODO: extend, move in to emit-rtl.cc.
1160 switch (insn_code)
1162 case INSN:
1163 rti = make_insn_raw (pat);
1164 break;
1165 default:
1166 gcc_unreachable ();
1169 auto insn = change_alloc<insn_info> (watermark, nullptr, rti, INSN_UID (rti));
1170 insn->m_is_temp = true;
1171 return insn;
1174 // Print a description of CHANGE to PP.
1175 void
1176 rtl_ssa::pp_insn_change (pretty_printer *pp, const insn_change &change)
1178 change.print (pp);
1181 // Print a description of CHANGE to FILE.
1182 void
1183 dump (FILE *file, const insn_change &change)
1185 dump_using (file, pp_insn_change, change);
1188 // Debug interface to the dump routine above.
1189 void debug (const insn_change &x) { dump (stderr, x); }