aix: default to DWARF 4.
[official-gcc.git] / gcc / rtl-ssa / changes.cc
blob2a3cc2b229220ac8d90a84543f6907dd1eab61f5
1 // RTL SSA routines for changing instructions -*- C++ -*-
2 // Copyright (C) 2020-2021 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.inl"
30 #include "target.h"
31 #include "predict.h"
32 #include "memmodel.h" // Needed by emit-rtl.h
33 #include "emit-rtl.h"
34 #include "cfghooks.h"
35 #include "cfgrtl.h"
37 using namespace rtl_ssa;
39 // See the comment above the declaration.
40 void
41 insn_change::print (pretty_printer *pp) const
43 if (m_is_deletion)
45 pp_string (pp, "deletion of ");
46 pp_insn (pp, m_insn);
48 else
50 pp_string (pp, "change to ");
51 pp_insn (pp, m_insn);
52 pp_newline_and_indent (pp, 2);
53 pp_string (pp, "~~~~~~~");
55 pp_newline_and_indent (pp, 0);
56 pp_string (pp, "new cost: ");
57 pp_decimal_int (pp, new_cost);
59 pp_newline_and_indent (pp, 0);
60 pp_string (pp, "new uses:");
61 pp_newline_and_indent (pp, 2);
62 pp_accesses (pp, new_uses);
63 pp_indentation (pp) -= 2;
65 pp_newline_and_indent (pp, 0);
66 pp_string (pp, "new defs:");
67 pp_newline_and_indent (pp, 2);
68 pp_accesses (pp, new_defs);
69 pp_indentation (pp) -= 2;
71 pp_newline_and_indent (pp, 0);
72 pp_string (pp, "first insert-after candidate: ");
73 move_range.first->print_identifier_and_location (pp);
75 pp_newline_and_indent (pp, 0);
76 pp_string (pp, "last insert-after candidate: ");
77 move_range.last->print_identifier_and_location (pp);
81 // Return a copy of access_array ACCESSES, allocating it on the
82 // temporary obstack.
83 access_array
84 function_info::temp_access_array (access_array accesses)
86 if (accesses.empty ())
87 return accesses;
89 gcc_assert (obstack_object_size (&m_temp_obstack) == 0);
90 obstack_grow (&m_temp_obstack, accesses.begin (), accesses.size_bytes ());
91 return { static_cast<access_info **> (obstack_finish (&m_temp_obstack)),
92 accesses.size () };
95 // See the comment above the declaration.
96 bool
97 function_info::verify_insn_changes (array_slice<insn_change *const> changes)
99 HARD_REG_SET defined_hard_regs, clobbered_hard_regs;
100 CLEAR_HARD_REG_SET (defined_hard_regs);
101 CLEAR_HARD_REG_SET (clobbered_hard_regs);
103 insn_info *min_insn = m_first_insn;
104 for (insn_change *change : changes)
105 if (!change->is_deletion ())
107 // Make sure that the changes can be kept in their current order
108 // while honoring all of the move ranges.
109 min_insn = later_insn (min_insn, change->move_range.first);
110 while (min_insn != change->insn () && !can_insert_after (min_insn))
111 min_insn = min_insn->next_nondebug_insn ();
112 if (*min_insn > *change->move_range.last)
114 if (dump_file && (dump_flags & TDF_DETAILS))
115 fprintf (dump_file, "no viable insn position assignment\n");
116 return false;
119 // If recog introduced new clobbers of a register as part of
120 // the matching process, make sure that they don't conflict
121 // with any other new definitions or uses of the register.
122 // (We have already checked that they don't conflict with
123 // unchanging definitions and uses.)
124 for (use_info *use : change->new_uses)
126 unsigned int regno = use->regno ();
127 if (HARD_REGISTER_NUM_P (regno)
128 && TEST_HARD_REG_BIT (clobbered_hard_regs, regno))
130 if (dump_file && (dump_flags & TDF_DETAILS))
131 fprintf (dump_file, "register %d would be clobbered"
132 " while it is still live\n", regno);
133 return false;
136 for (def_info *def : change->new_defs)
138 unsigned int regno = def->regno ();
139 if (HARD_REGISTER_NUM_P (regno))
141 if (def->m_is_temp)
143 // This is a clobber introduced by recog.
144 gcc_checking_assert (is_a<clobber_info *> (def));
145 if (TEST_HARD_REG_BIT (defined_hard_regs, regno))
147 if (dump_file && (dump_flags & TDF_DETAILS))
148 fprintf (dump_file, "conflicting definitions of"
149 " register %d\n", regno);
150 return false;
152 SET_HARD_REG_BIT (clobbered_hard_regs, regno);
154 else if (is_a<set_info *> (def))
156 // REGNO now has a defined value.
157 SET_HARD_REG_BIT (defined_hard_regs, regno);
158 CLEAR_HARD_REG_BIT (clobbered_hard_regs, regno);
163 return true;
166 // See the comment above the declaration.
167 bool
168 rtl_ssa::changes_are_worthwhile (array_slice<insn_change *const> changes,
169 bool strict_p)
171 unsigned int old_cost = 0;
172 unsigned int new_cost = 0;
173 for (insn_change *change : changes)
175 old_cost += change->old_cost ();
176 if (!change->is_deletion ())
178 basic_block cfg_bb = change->bb ()->cfg_bb ();
179 change->new_cost = insn_cost (change->rtl (),
180 optimize_bb_for_speed_p (cfg_bb));
181 new_cost += change->new_cost;
184 bool ok_p = (strict_p ? new_cost < old_cost : new_cost <= old_cost);
185 if (dump_file && (dump_flags & TDF_DETAILS))
187 fprintf (dump_file, "original cost");
188 char sep = '=';
189 for (const insn_change *change : changes)
191 fprintf (dump_file, " %c %d", sep, change->old_cost ());
192 sep = '+';
194 fprintf (dump_file, ", replacement cost");
195 sep = '=';
196 for (const insn_change *change : changes)
197 if (!change->is_deletion ())
199 fprintf (dump_file, " %c %d", sep, change->new_cost);
200 sep = '+';
202 fprintf (dump_file, "; %s\n",
203 ok_p ? "keeping replacement" : "rejecting replacement");
205 if (!ok_p)
206 return false;
208 return true;
211 // Update the REG_NOTES of INSN, whose pattern has just been changed.
212 static void
213 update_notes (rtx_insn *insn)
215 for (rtx *note_ptr = &REG_NOTES (insn); *note_ptr; )
217 rtx note = *note_ptr;
218 bool keep_p = true;
219 switch (REG_NOTE_KIND (note))
221 case REG_EQUAL:
222 case REG_EQUIV:
223 case REG_NOALIAS:
224 keep_p = (single_set (insn) != nullptr);
225 break;
227 case REG_UNUSED:
228 case REG_DEAD:
229 // These notes are stale. We'll recompute REG_UNUSED notes
230 // after the update.
231 keep_p = false;
232 break;
234 default:
235 break;
237 if (keep_p)
238 note_ptr = &XEXP (*note_ptr, 1);
239 else
241 *note_ptr = XEXP (*note_ptr, 1);
242 free_EXPR_LIST_node (note);
247 // Pick a location for CHANGE's instruction and return the instruction
248 // after which it should be placed.
249 static insn_info *
250 choose_insn_placement (insn_change &change)
252 gcc_checking_assert (change.move_range);
254 insn_info *insn = change.insn ();
255 insn_info *first = change.move_range.first;
256 insn_info *last = change.move_range.last;
258 // Quick(ish) exit if there is only one possible choice.
259 if (first == last)
260 return first;
261 if (first == insn->prev_nondebug_insn () && last == insn)
262 return insn;
264 // For now just use the closest valid choice to the original instruction.
265 // If the register usage has changed significantly, it might instead be
266 // better to try to take register pressure into account.
267 insn_info *closest = change.move_range.clamp_insn_to_range (insn);
268 while (closest != insn && !can_insert_after (closest))
269 closest = closest->next_nondebug_insn ();
270 return closest;
273 // Record any changes related to CHANGE that need to be queued for later.
274 void
275 function_info::possibly_queue_changes (insn_change &change)
277 insn_info *insn = change.insn ();
278 rtx_insn *rtl = insn->rtl ();
280 // If the instruction could previously throw, we eventually need to call
281 // purge_dead_edges to check whether things have changed.
282 if (find_reg_note (rtl, REG_EH_REGION, nullptr))
283 bitmap_set_bit (m_need_to_purge_dead_edges, insn->bb ()->index ());
285 auto needs_pending_update = [&]()
287 // If an instruction became a no-op without the pass explicitly
288 // deleting it, queue the deletion for later. Removing the
289 // instruction on the fly would require an update to all instructions
290 // that use the result of the move, which would be a potential source
291 // of quadraticness. Also, definitions shouldn't disappear under
292 // the pass's feet.
293 if (INSN_CODE (rtl) == NOOP_MOVE_INSN_CODE)
294 return true;
296 // If any jumps got turned into unconditional jumps or nops, we need
297 // to update the CFG accordingly.
298 if (JUMP_P (rtl)
299 && (returnjump_p (rtl) || any_uncondjump_p (rtl))
300 && !single_succ_p (insn->bb ()->cfg_bb ()))
301 return true;
303 // If a previously conditional trap now always fires, execution
304 // terminates at that point.
305 rtx pattern = PATTERN (rtl);
306 if (GET_CODE (pattern) == TRAP_IF
307 && XEXP (pattern, 0) == const1_rtx)
308 return true;
310 return false;
313 if (needs_pending_update ()
314 && bitmap_set_bit (m_queued_insn_update_uids, insn->uid ()))
316 gcc_assert (!change.is_deletion ());
317 m_queued_insn_updates.safe_push (insn);
321 // Remove the instruction described by CHANGE from the underlying RTL
322 // and from the insn_info list.
323 static void
324 delete_insn (insn_change &change)
326 insn_info *insn = change.insn ();
327 rtx_insn *rtl = change.rtl ();
328 if (dump_file && (dump_flags & TDF_DETAILS))
329 fprintf (dump_file, "deleting insn %d\n", insn->uid ());
330 set_insn_deleted (rtl);
333 // Move the RTL instruction associated with CHANGE so that it comes
334 // immediately after AFTER.
335 static void
336 move_insn (insn_change &change, insn_info *after)
338 rtx_insn *rtl = change.rtl ();
339 rtx_insn *after_rtl = after->rtl ();
340 if (dump_file && (dump_flags & TDF_DETAILS))
341 fprintf (dump_file, "moving insn %d after insn %d\n",
342 INSN_UID (rtl), INSN_UID (after_rtl));
344 // At the moment we don't support moving instructions between EBBs,
345 // but this would be worth adding if it's useful.
346 insn_info *insn = change.insn ();
347 gcc_assert (after->ebb () == insn->ebb ());
348 bb_info *bb = after->bb ();
349 basic_block cfg_bb = bb->cfg_bb ();
351 if (insn->bb () != bb)
352 // Force DF to mark the old block as dirty.
353 df_insn_delete (rtl);
354 ::remove_insn (rtl);
355 ::add_insn_after (rtl, after_rtl, cfg_bb);
358 // The instruction associated with CHANGE is being changed in-place.
359 // Update the DF information for its new pattern.
360 static void
361 update_insn_in_place (insn_change &change)
363 insn_info *insn = change.insn ();
364 if (dump_file && (dump_flags & TDF_DETAILS))
365 fprintf (dump_file, "updating insn %d in-place\n", insn->uid ());
366 df_insn_rescan (change.rtl ());
369 // Finalize the new list of definitions and uses in CHANGE, removing
370 // any uses and definitions that are no longer needed, and converting
371 // pending clobbers into actual definitions.
372 void
373 function_info::finalize_new_accesses (insn_change &change)
375 insn_info *insn = change.insn ();
377 // Get a list of all the things that the instruction now references.
378 vec_rtx_properties properties;
379 properties.add_insn (insn->rtl (), true);
381 // Build up the new list of definitions.
382 for (rtx_obj_reference ref : properties.refs ())
383 if (ref.is_write ())
385 def_info *def = find_access (change.new_defs, ref.regno);
386 gcc_assert (def);
387 if (def->m_is_temp)
389 // At present, the only temporary instruction definitions we
390 // create are clobbers, such as those added during recog.
391 gcc_assert (is_a<clobber_info *> (def));
392 def = allocate<clobber_info> (change.insn (), ref.regno);
394 else if (!def->m_has_been_superceded)
396 // This is a second or subsequent definition.
397 // See function_info::record_def for a discussion of when
398 // this can happen.
399 def->record_reference (ref, false);
400 continue;
402 else
404 def->m_has_been_superceded = false;
406 // Clobbers can move around, so remove them from their current
407 // position and them back in their final position.
409 // At the moment, we don't allow sets to move relative to other
410 // definitions of the same resource, so we can leave those where
411 // they are. It might be useful to relax this in future.
412 // The main complication is that removing a set would potentially
413 // fuse two adjoining clobber_groups, and adding the set back
414 // would require the group to be split again.
415 if (is_a<clobber_info *> (def))
416 remove_def (def);
417 else if (ref.is_reg ())
418 def->set_mode (ref.mode);
419 def->set_insn (insn);
421 def->record_reference (ref, true);
422 m_temp_defs.safe_push (def);
425 // Also keep any explicitly-recorded call clobbers, which are deliberately
426 // excluded from the vec_rtx_properties. Calls shouldn't move, so we can
427 // keep the definitions in their current position.
428 for (def_info *def : change.new_defs)
429 if (def->m_has_been_superceded && def->is_call_clobber ())
431 def->m_has_been_superceded = false;
432 def->set_insn (insn);
433 m_temp_defs.safe_push (def);
436 // Install the new list of definitions in CHANGE.
437 sort_accesses (m_temp_defs);
438 access_array accesses = temp_access_array (m_temp_defs);
439 change.new_defs = def_array (accesses);
440 m_temp_defs.truncate (0);
442 // Create temporary copies of use_infos that are already attached to
443 // other insns, which could happen if the uses come from unchanging
444 // insns or if they have been used by earlier changes. Doing this
445 // makes it easier to detect multiple reads below.
446 auto *unshared_uses_base = XOBNEWVEC (&m_temp_obstack, access_info *,
447 change.new_uses.size ());
448 unsigned int i = 0;
449 for (use_info *use : change.new_uses)
451 if (!use->m_has_been_superceded)
453 use = allocate_temp<use_info> (insn, use->resource (), use->def ());
454 use->m_has_been_superceded = true;
455 use->m_is_temp = true;
457 unshared_uses_base[i++] = use;
459 auto unshared_uses = use_array (unshared_uses_base, change.new_uses.size ());
461 // Add (possibly temporary) uses to m_temp_uses for each resource.
462 // If there are multiple references to the same resource, aggregate
463 // information in the modes and flags.
464 for (rtx_obj_reference ref : properties.refs ())
465 if (ref.is_read ())
467 unsigned int regno = ref.regno;
468 machine_mode mode = ref.is_reg () ? ref.mode : BLKmode;
469 use_info *use = find_access (unshared_uses, ref.regno);
470 gcc_assert (use);
471 if (use->m_has_been_superceded)
473 // This is the first reference to the resource.
474 bool is_temp = use->m_is_temp;
475 *use = use_info (insn, resource_info { mode, regno }, use->def ());
476 use->m_is_temp = is_temp;
477 use->record_reference (ref, true);
478 m_temp_uses.safe_push (use);
480 else
482 // Record the mode of the largest use. The choice is arbitrary if
483 // the instruction (unusually) references the same register in two
484 // different but equal-sized modes.
485 if (HARD_REGISTER_NUM_P (regno)
486 && partial_subreg_p (use->mode (), mode))
487 use->set_mode (mode);
488 use->record_reference (ref, false);
492 // Replace any temporary uses and definitions with real ones.
493 for (unsigned int i = 0; i < m_temp_uses.length (); ++i)
495 auto *use = as_a<use_info *> (m_temp_uses[i]);
496 if (use->m_is_temp)
498 m_temp_uses[i] = use = allocate<use_info> (*use);
499 use->m_is_temp = false;
500 set_info *def = use->def ();
501 // Handle cases in which the value was previously not used
502 // within the block.
503 if (def && def->m_is_temp)
505 phi_info *phi = as_a<phi_info *> (def);
506 gcc_assert (phi->is_degenerate ());
507 phi = create_degenerate_phi (phi->ebb (), phi->input_value (0));
508 use->set_def (phi);
513 // Install the new list of definitions in CHANGE.
514 sort_accesses (m_temp_uses);
515 change.new_uses = use_array (temp_access_array (m_temp_uses));
516 m_temp_uses.truncate (0);
518 // Record the new instruction-wide properties.
519 insn->set_properties (properties);
522 // Copy information from CHANGE to its underlying insn_info, given that
523 // the insn_info has already been placed appropriately.
524 void
525 function_info::apply_changes_to_insn (insn_change &change)
527 insn_info *insn = change.insn ();
528 if (change.is_deletion ())
530 insn->set_accesses (nullptr, 0, 0);
531 return;
534 // Copy the cost.
535 insn->set_cost (change.new_cost);
537 // Add all clobbers. Sets and call clobbers never move relative to
538 // other definitions, so are OK as-is.
539 for (def_info *def : change.new_defs)
540 if (is_a<clobber_info *> (def) && !def->is_call_clobber ())
541 add_def (def);
543 // Add all uses, now that their position is final.
544 for (use_info *use : change.new_uses)
545 add_use (use);
547 // Copy the uses and definitions.
548 unsigned int num_defs = change.new_defs.size ();
549 unsigned int num_uses = change.new_uses.size ();
550 if (num_defs + num_uses <= insn->num_defs () + insn->num_uses ())
551 insn->copy_accesses (change.new_defs, change.new_uses);
552 else
554 access_array_builder builder (&m_obstack);
555 builder.reserve (num_defs + num_uses);
557 for (def_info *def : change.new_defs)
558 builder.quick_push (def);
559 for (use_info *use : change.new_uses)
560 builder.quick_push (use);
562 insn->set_accesses (builder.finish ().begin (), num_defs, num_uses);
565 add_reg_unused_notes (insn);
568 // Add a temporary placeholder instruction after AFTER.
569 insn_info *
570 function_info::add_placeholder_after (insn_info *after)
572 insn_info *insn = allocate_temp<insn_info> (after->bb (), nullptr, -1);
573 add_insn_after (insn, after);
574 return insn;
577 // See the comment above the declaration.
578 void
579 function_info::change_insns (array_slice<insn_change *> changes)
581 auto watermark = temp_watermark ();
583 insn_info *min_insn = m_first_insn;
584 for (insn_change *change : changes)
586 // Tentatively mark all the old uses and definitions for deletion.
587 for (use_info *use : change->old_uses ())
589 use->m_has_been_superceded = true;
590 remove_use (use);
592 for (def_info *def : change->old_defs ())
593 def->m_has_been_superceded = true;
595 if (!change->is_deletion ())
597 // Remove any notes that are no longer relevant.
598 update_notes (change->rtl ());
600 // Make sure that the placement of this instruction would still
601 // leave room for previous instructions.
602 change->move_range = move_later_than (change->move_range, min_insn);
603 if (!canonicalize_move_range (change->move_range, change->insn ()))
604 // verify_insn_changes is supposed to make sure that this holds.
605 gcc_unreachable ();
606 min_insn = later_insn (min_insn, change->move_range.first);
610 // Walk backwards through the changes, allocating specific positions
611 // to each one. Update the underlying RTL and its associated DF
612 // information.
613 insn_info *following_insn = nullptr;
614 auto_vec<insn_info *, 16> placeholders;
615 placeholders.safe_grow_cleared (changes.size ());
616 for (unsigned int i = changes.size (); i-- > 0;)
618 insn_change &change = *changes[i];
619 insn_info *placeholder = nullptr;
620 possibly_queue_changes (change);
621 if (change.is_deletion ())
622 delete_insn (change);
623 else
625 // Make sure that this instruction comes before later ones.
626 if (following_insn)
628 change.move_range = move_earlier_than (change.move_range,
629 following_insn);
630 if (!canonicalize_move_range (change.move_range,
631 change.insn ()))
632 // verify_insn_changes is supposed to make sure that this
633 // holds.
634 gcc_unreachable ();
637 // Decide which instruction INSN should go after.
638 insn_info *after = choose_insn_placement (change);
640 // If INSN is moving, insert a placeholder insn_info at the
641 // new location. We can't move INSN itself yet because it
642 // might still be referenced by earlier move ranges.
643 insn_info *insn = change.insn ();
644 if (after == insn || after == insn->prev_nondebug_insn ())
646 update_insn_in_place (change);
647 following_insn = insn;
649 else
651 move_insn (change, after);
652 placeholder = add_placeholder_after (after);
653 following_insn = placeholder;
656 // Finalize the new list of accesses for the change. Don't install
657 // them yet, so that we still have access to the old lists below.
658 finalize_new_accesses (change);
660 placeholders[i] = placeholder;
663 // Remove all definitions that are no longer needed. After the above,
664 // such definitions should no longer have any registered users.
666 // In particular, this means that consumers must handle debug
667 // instructions before removing a set.
668 for (insn_change *change : changes)
669 for (def_info *def : change->old_defs ())
670 if (def->m_has_been_superceded)
672 auto *set = dyn_cast<set_info *> (def);
673 gcc_assert (!set || !set->has_any_uses ());
674 remove_def (def);
677 // Move the insn_infos to their new locations.
678 for (unsigned int i = 0; i < changes.size (); ++i)
680 insn_change &change = *changes[i];
681 insn_info *insn = change.insn ();
682 if (change.is_deletion ())
683 remove_insn (insn);
684 else if (insn_info *placeholder = placeholders[i])
686 // Check if earlier movements turned a move into a no-op.
687 if (placeholder->prev_nondebug_insn () == insn
688 || placeholder->next_nondebug_insn () == insn)
690 remove_insn (placeholder);
691 placeholders[i] = nullptr;
693 else
695 // Remove the placeholder first so that we have a wider range of
696 // program points when inserting INSN.
697 insn_info *after = placeholder->prev_any_insn ();
698 remove_insn (insn);
699 remove_insn (placeholder);
700 insn->set_bb (after->bb ());
701 add_insn_after (insn, after);
706 // Finally apply the changes to the underlying insn_infos.
707 for (insn_change *change : changes)
708 apply_changes_to_insn (*change);
711 // See the comment above the declaration.
712 void
713 function_info::change_insn (insn_change &change)
715 insn_change *changes[] = { &change };
716 return change_insns (changes);
719 // Try to adjust CHANGE so that its pattern can include clobber rtx CLOBBER.
720 // Return true on success.
722 // ADD_REGNO_CLOBBER is a specialization of function_info::add_regno_clobber
723 // for a specific caller-provided predicate.
724 static bool
725 add_clobber (insn_change &change, add_regno_clobber_fn add_regno_clobber,
726 rtx clobber)
728 rtx pat = PATTERN (change.rtl ());
729 gcc_assert (GET_CODE (clobber) == CLOBBER);
730 rtx dest = XEXP (clobber, 0);
731 if (GET_CODE (dest) == SCRATCH)
733 if (reload_completed)
735 if (dump_file && (dump_flags & TDF_DETAILS))
737 // ??? Maybe we could try to do some RA here?
738 fprintf (dump_file, "instruction requires a scratch"
739 " after reload:\n");
740 print_rtl_single (dump_file, pat);
742 return false;
744 return true;
747 gcc_assert (REG_P (dest));
748 for (unsigned int regno = REGNO (dest); regno != END_REGNO (dest); ++regno)
749 if (!add_regno_clobber (change, regno))
751 if (dump_file && (dump_flags & TDF_DETAILS))
753 fprintf (dump_file, "cannot clobber live register %d in:\n",
754 regno);
755 print_rtl_single (dump_file, pat);
757 return false;
759 return true;
762 // Try to recognize the new form of the insn associated with CHANGE,
763 // adding any clobbers that are necessary to make the instruction match
764 // an .md pattern. Return true on success.
766 // ADD_REGNO_CLOBBER is a specialization of function_info::add_regno_clobber
767 // for a specific caller-provided predicate.
768 static bool
769 recog_level2 (insn_change &change, add_regno_clobber_fn add_regno_clobber)
771 insn_change_watermark insn_watermark;
772 rtx_insn *rtl = change.rtl ();
773 rtx pat = PATTERN (rtl);
774 int num_clobbers = 0;
775 int icode = -1;
776 bool asm_p = asm_noperands (pat) >= 0;
777 if (asm_p)
779 if (!check_asm_operands (pat))
781 if (dump_file && (dump_flags & TDF_DETAILS))
783 fprintf (dump_file, "failed to match this asm instruction:\n");
784 print_rtl_single (dump_file, pat);
786 return false;
789 else if (noop_move_p (rtl))
791 INSN_CODE (rtl) = NOOP_MOVE_INSN_CODE;
792 if (dump_file && (dump_flags & TDF_DETAILS))
794 fprintf (dump_file, "instruction becomes a no-op:\n");
795 print_rtl_single (dump_file, pat);
797 insn_watermark.keep ();
798 return true;
800 else
802 icode = ::recog (pat, rtl, &num_clobbers);
803 if (icode < 0)
805 if (dump_file && (dump_flags & TDF_DETAILS))
807 fprintf (dump_file, "failed to match this instruction:\n");
808 print_rtl_single (dump_file, pat);
810 return false;
814 auto prev_new_defs = change.new_defs;
815 auto prev_move_range = change.move_range;
816 if (num_clobbers > 0)
818 // ??? It would be good to have a way of recycling the rtxes on failure,
819 // but any attempt to cache old PARALLELs would at best be a half
820 // measure, since add_clobbers would still generate fresh clobbers
821 // each time. It would be better to have a more general recycling
822 // mechanism that all rtx passes can use.
823 rtvec newvec;
824 int oldlen;
825 if (GET_CODE (pat) == PARALLEL)
827 oldlen = XVECLEN (pat, 0);
828 newvec = rtvec_alloc (num_clobbers + oldlen);
829 for (int i = 0; i < oldlen; ++i)
830 RTVEC_ELT (newvec, i) = XVECEXP (pat, 0, i);
832 else
834 oldlen = 1;
835 newvec = rtvec_alloc (num_clobbers + oldlen);
836 RTVEC_ELT (newvec, 0) = pat;
838 rtx newpat = gen_rtx_PARALLEL (VOIDmode, newvec);
839 add_clobbers (newpat, icode);
840 validate_change (rtl, &PATTERN (rtl), newpat, true);
841 for (int i = 0; i < num_clobbers; ++i)
842 if (!add_clobber (change, add_regno_clobber,
843 XVECEXP (newpat, 0, oldlen + i)))
845 change.new_defs = prev_new_defs;
846 change.move_range = prev_move_range;
847 return false;
850 pat = newpat;
853 INSN_CODE (rtl) = icode;
854 if (reload_completed)
856 extract_insn (rtl);
857 if (!constrain_operands (1, get_preferred_alternatives (rtl)))
859 if (dump_file && (dump_flags & TDF_DETAILS))
861 if (asm_p)
862 fprintf (dump_file, "asm does not match its constraints:\n");
863 else if (const char *name = get_insn_name (icode))
864 fprintf (dump_file, "instruction does not match the"
865 " constraints for %s:\n", name);
866 else
867 fprintf (dump_file, "instruction does not match its"
868 " constraints:\n");
869 print_rtl_single (dump_file, pat);
871 change.new_defs = prev_new_defs;
872 change.move_range = prev_move_range;
873 return false;
877 if (dump_file && (dump_flags & TDF_DETAILS))
879 const char *name;
880 if (!asm_p && (name = get_insn_name (icode)))
881 fprintf (dump_file, "successfully matched this instruction "
882 "to %s:\n", name);
883 else
884 fprintf (dump_file, "successfully matched this instruction:\n");
885 print_rtl_single (dump_file, pat);
888 insn_watermark.keep ();
889 return true;
892 // Try to recognize the new form of the insn associated with CHANGE,
893 // adding and removing clobbers as necessary to make the instruction
894 // match an .md pattern. Return true on success, otherwise leave
895 // CHANGE as it was on entry.
897 // ADD_REGNO_CLOBBER is a specialization of function_info::add_regno_clobber
898 // for a specific caller-provided predicate.
899 bool
900 rtl_ssa::recog_internal (insn_change &change,
901 add_regno_clobber_fn add_regno_clobber)
903 // Accept all changes to debug instructions.
904 insn_info *insn = change.insn ();
905 if (insn->is_debug_insn ())
906 return true;
908 rtx_insn *rtl = insn->rtl ();
909 rtx pat = PATTERN (rtl);
910 if (GET_CODE (pat) == PARALLEL && asm_noperands (pat) < 0)
912 // Try to remove trailing (clobber (scratch)) rtxes, since the new form
913 // of the instruction might not need those scratches. recog will add
914 // back any that are needed.
915 int len = XVECLEN (pat, 0);
916 int new_len = len;
917 while (new_len > 0
918 && GET_CODE (XVECEXP (pat, 0, new_len - 1)) == CLOBBER
919 && GET_CODE (XEXP (XVECEXP (pat, 0, new_len - 1), 0)) == SCRATCH)
920 new_len -= 1;
922 int old_num_changes = num_validated_changes ();
923 validate_change_xveclen (rtl, &PATTERN (rtl), new_len, true);
924 if (recog_level2 (change, add_regno_clobber))
925 return true;
926 cancel_changes (old_num_changes);
928 // Try to remove all trailing clobbers. For example, a pattern that
929 // used to clobber the flags might no longer need to do so.
930 int prev_len = new_len;
931 while (new_len > 0
932 && GET_CODE (XVECEXP (pat, 0, new_len - 1)) == CLOBBER)
933 new_len -= 1;
934 if (new_len != prev_len)
936 validate_change_xveclen (rtl, &PATTERN (rtl), new_len, true);
937 if (recog_level2 (change, add_regno_clobber))
938 return true;
939 cancel_changes (old_num_changes);
941 return false;
944 return recog_level2 (change, add_regno_clobber);
947 // See the comment above the declaration.
948 bool
949 function_info::perform_pending_updates ()
951 bool changed_cfg = false;
952 bool changed_jumps = false;
953 for (insn_info *insn : m_queued_insn_updates)
955 rtx_insn *rtl = insn->rtl ();
956 if (JUMP_P (rtl))
958 if (INSN_CODE (rtl) == NOOP_MOVE_INSN_CODE)
960 ::delete_insn (rtl);
961 bitmap_set_bit (m_need_to_purge_dead_edges,
962 insn->bb ()->index ());
964 else if (returnjump_p (rtl) || any_uncondjump_p (rtl))
966 mark_jump_label (PATTERN (rtl), rtl, 0);
967 update_cfg_for_uncondjump (rtl);
968 changed_cfg = true;
969 changed_jumps = true;
972 else if (INSN_CODE (rtl) == NOOP_MOVE_INSN_CODE)
973 ::delete_insn (rtl);
974 else
976 rtx pattern = PATTERN (rtl);
977 if (GET_CODE (pattern) == TRAP_IF
978 && XEXP (pattern, 0) == const1_rtx)
980 remove_edge (split_block (BLOCK_FOR_INSN (rtl), rtl));
981 emit_barrier_after_bb (BLOCK_FOR_INSN (rtl));
982 changed_cfg = true;
987 unsigned int index;
988 bitmap_iterator bi;
989 EXECUTE_IF_SET_IN_BITMAP (m_need_to_purge_dead_edges, 0, index, bi)
990 if (purge_dead_edges (BASIC_BLOCK_FOR_FN (m_fn, index)))
991 changed_cfg = true;
993 if (changed_jumps)
994 // This uses its own timevar internally, so we don't need to push
995 // one ourselves.
996 rebuild_jump_labels (get_insns ());
998 bitmap_clear (m_need_to_purge_dead_edges);
999 bitmap_clear (m_queued_insn_update_uids);
1000 m_queued_insn_updates.truncate (0);
1002 if (changed_cfg)
1004 free_dominance_info (CDI_DOMINATORS);
1005 free_dominance_info (CDI_POST_DOMINATORS);
1008 return changed_cfg;
1011 // Print a description of CHANGE to PP.
1012 void
1013 rtl_ssa::pp_insn_change (pretty_printer *pp, const insn_change &change)
1015 change.print (pp);
1018 // Print a description of CHANGE to FILE.
1019 void
1020 dump (FILE *file, const insn_change &change)
1022 dump_using (file, pp_insn_change, change);
1025 // Debug interface to the dump routine above.
1026 void debug (const insn_change &x) { dump (stderr, x); }