1 // RTL SSA routines for changing instructions -*- C++ -*-
2 // Copyright (C) 2020-2021 Free Software Foundation, Inc.
4 // This file is part of GCC.
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
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
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
24 #include "coretypes.h"
29 #include "rtl-ssa/internals.inl"
32 #include "memmodel.h" // Needed by emit-rtl.h
37 using namespace rtl_ssa
;
39 // See the comment above the declaration.
41 insn_change::print (pretty_printer
*pp
) const
45 pp_string (pp
, "deletion of ");
50 pp_string (pp
, "change to ");
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
84 function_info::temp_access_array (access_array accesses
)
86 if (accesses
.empty ())
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
)),
95 // See the comment above the declaration.
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");
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
);
136 for (def_info
*def
: change
->new_defs
)
138 unsigned int regno
= def
->regno ();
139 if (HARD_REGISTER_NUM_P (regno
))
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
);
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
);
166 // See the comment above the declaration.
168 rtl_ssa::changes_are_worthwhile (array_slice
<insn_change
*const> changes
,
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");
189 for (const insn_change
*change
: changes
)
191 fprintf (dump_file
, " %c %d", sep
, change
->old_cost ());
194 fprintf (dump_file
, ", replacement cost");
196 for (const insn_change
*change
: changes
)
197 if (!change
->is_deletion ())
199 fprintf (dump_file
, " %c %d", sep
, change
->new_cost
);
202 fprintf (dump_file
, "; %s\n",
203 ok_p
? "keeping replacement" : "rejecting replacement");
211 // Update the REG_NOTES of INSN, whose pattern has just been changed.
213 update_notes (rtx_insn
*insn
)
215 for (rtx
*note_ptr
= ®_NOTES (insn
); *note_ptr
; )
217 rtx note
= *note_ptr
;
219 switch (REG_NOTE_KIND (note
))
224 keep_p
= (single_set (insn
) != nullptr);
229 // These notes are stale. We'll recompute REG_UNUSED notes
238 note_ptr
= &XEXP (*note_ptr
, 1);
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.
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.
261 if (first
== insn
->prev_nondebug_insn () && last
== 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 ();
273 // Record any changes related to CHANGE that need to be queued for later.
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
293 if (INSN_CODE (rtl
) == NOOP_MOVE_INSN_CODE
)
296 // If any jumps got turned into unconditional jumps or nops, we need
297 // to update the CFG accordingly.
299 && (returnjump_p (rtl
) || any_uncondjump_p (rtl
))
300 && !single_succ_p (insn
->bb ()->cfg_bb ()))
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
)
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.
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.
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
);
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.
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.
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 ())
385 def_info
*def
= find_access (change
.new_defs
, ref
.regno
);
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
399 def
->record_reference (ref
, false);
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
))
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 ());
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 ())
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
);
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
);
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
]);
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
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));
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.
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);
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 ())
543 // Add all uses, now that their position is final.
544 for (use_info
*use
: change
.new_uses
)
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
);
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.
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
);
577 // See the comment above the declaration.
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;
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.
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
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
);
625 // Make sure that this instruction comes before later ones.
628 change
.move_range
= move_earlier_than (change
.move_range
,
630 if (!canonicalize_move_range (change
.move_range
,
632 // verify_insn_changes is supposed to make sure that this
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
;
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 ());
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 ())
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;
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 ();
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.
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.
725 add_clobber (insn_change
&change
, add_regno_clobber_fn add_regno_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"
740 print_rtl_single (dump_file
, pat
);
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",
755 print_rtl_single (dump_file
, pat
);
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.
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;
776 bool asm_p
= asm_noperands (pat
) >= 0;
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
);
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 ();
802 icode
= ::recog (pat
, rtl
, &num_clobbers
);
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
);
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.
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
);
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
;
853 INSN_CODE (rtl
) = icode
;
854 if (reload_completed
)
857 if (!constrain_operands (1, get_preferred_alternatives (rtl
)))
859 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
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
);
867 fprintf (dump_file
, "instruction does not match its"
869 print_rtl_single (dump_file
, pat
);
871 change
.new_defs
= prev_new_defs
;
872 change
.move_range
= prev_move_range
;
877 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
880 if (!asm_p
&& (name
= get_insn_name (icode
)))
881 fprintf (dump_file
, "successfully matched this instruction "
884 fprintf (dump_file
, "successfully matched this instruction:\n");
885 print_rtl_single (dump_file
, pat
);
888 insn_watermark
.keep ();
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.
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 ())
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);
918 && GET_CODE (XVECEXP (pat
, 0, new_len
- 1)) == CLOBBER
919 && GET_CODE (XEXP (XVECEXP (pat
, 0, new_len
- 1), 0)) == SCRATCH
)
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
))
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
;
932 && GET_CODE (XVECEXP (pat
, 0, new_len
- 1)) == CLOBBER
)
934 if (new_len
!= prev_len
)
936 validate_change_xveclen (rtl
, &PATTERN (rtl
), new_len
, true);
937 if (recog_level2 (change
, add_regno_clobber
))
939 cancel_changes (old_num_changes
);
944 return recog_level2 (change
, add_regno_clobber
);
947 // See the comment above the declaration.
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 ();
958 if (INSN_CODE (rtl
) == NOOP_MOVE_INSN_CODE
)
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
);
969 changed_jumps
= true;
972 else if (INSN_CODE (rtl
) == NOOP_MOVE_INSN_CODE
)
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
));
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
)))
994 // This uses its own timevar internally, so we don't need to push
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);
1004 free_dominance_info (CDI_DOMINATORS
);
1005 free_dominance_info (CDI_POST_DOMINATORS
);
1011 // Print a description of CHANGE to PP.
1013 rtl_ssa::pp_insn_change (pretty_printer
*pp
, const insn_change
&change
)
1018 // Print a description of CHANGE to FILE.
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
); }