]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/rtl-ssa/member-fns.inl
Update copyright years.
[thirdparty/gcc.git] / gcc / rtl-ssa / member-fns.inl
CommitLineData
73b75827 1// Implementation of public inline member functions for RTL SSA -*- C++ -*-
83ffe9cd 2// Copyright (C) 2020-2023 Free Software Foundation, Inc.
73b75827
RS
3//
4// This file is part of GCC.
5//
6// GCC is free software; you can redistribute it and/or modify it under
7// the terms of the GNU General Public License as published by the Free
8// Software Foundation; either version 3, or (at your option) any later
9// version.
10//
11// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12// WARRANTY; without even the implied warranty of MERCHANTABILITY or
13// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14// for more details.
15//
16// You should have received a copy of the GNU General Public License
17// along with GCC; see the file COPYING3. If not see
18// <http://www.gnu.org/licenses/>.
19
20// This file contains inline implementations of public member functions that
21// are too large to be written in the class definition. It also contains
22// some non-inline template definitions of public member functions.
23// See the comments above the function declarations for details.
24//
25// The file also contains the bare minimum of private and protected inline
26// member functions that are needed to make the public functions compile.
27namespace rtl_ssa {
28
29inline void
30access_array_builder::reserve (unsigned int num_accesses)
31{
32 obstack_make_room (m_obstack, num_accesses * sizeof (access_info *));
33}
34
35inline void
36access_array_builder::quick_push (access_info *access)
37{
38 obstack_ptr_grow_fast (m_obstack, access);
39}
40
41inline array_slice<access_info *>
42access_array_builder::finish ()
43{
44 auto num_accesses = obstack_object_size (m_obstack) / sizeof (access_info *);
45 if (num_accesses == 0)
46 return {};
47
48 auto **base = static_cast<access_info **> (obstack_finish (m_obstack));
49 keep ();
50 return { base, num_accesses };
51}
52
53inline bool
54access_info::is_set_with_nondebug_insn_uses () const
55{
56 return m_is_set_with_nondebug_insn_uses;
57}
58
59inline bool
60use_info::is_in_debug_insn () const
61{
62 return m_insn_or_phi.is_first () && m_is_in_debug_insn_or_phi;
63}
64
65inline bb_info *
66use_info::bb () const
67{
68 if (m_insn_or_phi.is_first ())
69 return m_insn_or_phi.known_first ()->bb ();
70 return m_insn_or_phi.known_second ()->bb ();
71}
72
73inline ebb_info *
74use_info::ebb () const
75{
76 return bb ()->ebb ();
77}
78
79inline use_info *
80use_info::prev_use () const
81{
82 return m_last_use_or_prev_use.second_or_null ();
83}
84
85inline use_info *
86use_info::next_use () const
87{
88 return m_last_nondebug_insn_use_or_next_use.second_or_null ();
89}
90
91inline bool
92use_info::is_first_use () const
93{
94 return m_last_use_or_prev_use.is_first ();
95}
96
97inline bool
98use_info::is_last_use () const
99{
100 return m_last_nondebug_insn_use_or_next_use.is_first ();
101}
102
103inline use_info *
104use_info::next_nondebug_insn_use () const
105{
106 if (m_is_last_nondebug_insn_use)
107 return nullptr;
108 return m_last_nondebug_insn_use_or_next_use.known_second ();
109}
110
111inline use_info *
112use_info::next_any_insn_use () const
113{
114 // This is used less often than next_nondebug_insn_use, so it doesn't
115 // seem worth having an m_is_last_nondebug_insn_use-style end marker.
116 if (use_info *use = next_use ())
117 if (use->is_in_any_insn ())
118 return use;
119 return nullptr;
120}
121
122inline use_info *
123use_info::prev_phi_use () const
124{
125 // This is used less often than next_nondebug_insn_use, so it doesn't
126 // seem worth having an m_is_last_nondebug_insn_use-style end marker.
127 if (use_info *use = prev_use ())
128 if (use->is_in_phi ())
129 return use;
130 return nullptr;
131}
132
133// Return the last use of any kind in the list. Only valid when is_first ()
134// is true.
135inline use_info *
136use_info::last_use () const
137{
138 return m_last_use_or_prev_use.known_first ();
139}
140
141// Return the last nondebug insn use in the list, or null if none. Only valid
142// when is_last_use () is true.
143inline use_info *
144use_info::last_nondebug_insn_use () const
145{
146 return m_last_nondebug_insn_use_or_next_use.known_first ();
147}
148
149inline def_info *
150def_info::prev_def () const
151{
152 return m_last_def_or_prev_def.second_or_null ();
153}
154
155inline def_info *
156def_info::next_def () const
157{
158 return m_splay_root_or_next_def.second_or_null ();
159}
160
161inline bool
162def_info::is_first_def () const
163{
164 return m_last_def_or_prev_def.is_first ();
165}
166
167inline bool
168def_info::is_last_def () const
169{
170 return m_splay_root_or_next_def.is_first ();
171}
172
173inline bb_info *
174def_info::bb () const
175{
176 return m_insn->bb ();
177}
178
179inline ebb_info *
180def_info::ebb () const
181{
182 return m_insn->ebb ();
183}
184
185inline clobber_group *
186clobber_info::group () const
187{
188 if (!m_group || !m_group->has_been_superceded ())
189 return m_group;
190 return const_cast<clobber_info *> (this)->recompute_group ();
191}
192
193inline use_info *
194set_info::last_use () const
195{
196 return m_first_use ? m_first_use->last_use () : nullptr;
197}
198
199inline use_info *
200set_info::first_nondebug_insn_use () const
201{
202 if (m_is_set_with_nondebug_insn_uses)
203 return m_first_use;
204 return nullptr;
205}
206
207inline use_info *
208set_info::last_nondebug_insn_use () const
209{
210 if (m_is_set_with_nondebug_insn_uses)
211 return m_first_use->last_use ()->last_nondebug_insn_use ();
212 return nullptr;
213}
214
215inline use_info *
216set_info::first_any_insn_use () const
217{
218 if (m_first_use->is_in_any_insn ())
219 return m_first_use;
220 return nullptr;
221}
222
223inline use_info *
224set_info::last_phi_use () const
225{
226 if (m_first_use)
227 {
228 use_info *last = m_first_use->last_use ();
229 if (last->is_in_phi ())
230 return last;
231 }
232 return nullptr;
233}
234
235inline bool
236set_info::has_nondebug_uses () const
237{
238 return has_nondebug_insn_uses () || has_phi_uses ();
239}
240
241inline bool
242set_info::has_nondebug_insn_uses () const
243{
244 return m_is_set_with_nondebug_insn_uses;
245}
246
247inline bool
248set_info::has_phi_uses () const
249{
250 return m_first_use && m_first_use->last_use ()->is_in_phi ();
251}
252
b61461ac
IL
253inline use_info *
254set_info::single_nondebug_use () const
255{
256 if (!has_phi_uses ())
257 return single_nondebug_insn_use ();
258 if (!has_nondebug_insn_uses ())
259 return single_phi_use ();
260 return nullptr;
261}
262
263inline use_info *
264set_info::single_nondebug_insn_use () const
265{
266 use_info *first = first_nondebug_insn_use ();
267 if (first && !first->next_nondebug_insn_use ())
268 return first;
269 return nullptr;
270}
271
272inline use_info *
273set_info::single_phi_use () const
274{
275 use_info *last = last_phi_use ();
276 if (last && !last->prev_phi_use ())
277 return last;
278 return nullptr;
279}
280
73b75827
RS
281inline bool
282set_info::is_local_to_ebb () const
283{
284 if (!m_first_use)
285 return true;
286
287 use_info *last = m_first_use->last_use ();
288 if (last->is_in_phi ())
289 return false;
290
291 last = last->last_nondebug_insn_use ();
292 return !last || last->ebb () == ebb ();
293}
294
295inline iterator_range<use_iterator>
296set_info::all_uses () const
297{
298 return { m_first_use, nullptr };
299}
300
301inline iterator_range<reverse_use_iterator>
302set_info::reverse_all_uses () const
303{
304 return { last_use (), nullptr };
305}
306
307inline iterator_range<nondebug_insn_use_iterator>
308set_info::nondebug_insn_uses () const
309{
310 return { first_nondebug_insn_use (), nullptr };
311}
312
313inline iterator_range<reverse_use_iterator>
314set_info::reverse_nondebug_insn_uses () const
315{
316 return { last_nondebug_insn_use (), nullptr };
317}
318
319inline iterator_range<any_insn_use_iterator>
320set_info::all_insn_uses () const
321{
322 return { first_any_insn_use (), nullptr };
323}
324
325inline iterator_range<phi_use_iterator>
326set_info::phi_uses () const
327{
328 return { last_phi_use (), nullptr };
329}
330
331inline use_array
332phi_info::inputs () const
333{
334 if (m_num_inputs == 1)
335 return use_array (&m_single_input, 1);
336 return use_array (m_inputs, m_num_inputs);
337}
338
339inline use_info *
340phi_info::input_use (unsigned int i) const
341{
342 if (m_num_inputs == 1)
343 return as_a<use_info *> (m_single_input);
344 return as_a<use_info *> (m_inputs[i]);
345}
346
347inline set_info *
348phi_info::input_value (unsigned int i) const
349{
350 return input_use (i)->def ();
351}
352
353inline def_info *
354def_node::first_def () const
355{
356 // This should get optimized into an AND with -2.
357 if (m_clobber_or_set.is_first ())
358 return m_clobber_or_set.known_first ();
359 return m_clobber_or_set.known_second ();
360}
361
362inline clobber_info *
363clobber_group::first_clobber () const
364{
365 return m_clobber_or_set.known_first ();
366}
367
368inline iterator_range<def_iterator>
369clobber_group::clobbers () const
370{
371 return { first_clobber (), m_last_clobber->next_def () };
372}
373
374inline def_info *
375def_mux::first_def () const
376{
377 if (is_first ())
378 return known_first ();
379 return known_second ()->first_def ();
380}
381
382inline def_info *
383def_mux::last_def () const
384{
385 if (is_first ())
386 return known_first ();
387
388 def_node *node = known_second ();
389 if (auto *clobber = ::dyn_cast<clobber_group *> (node))
390 return clobber->last_clobber ();
391
392 return node->first_def ();
393}
394
395inline set_info *
396def_mux::set () const
397{
398 if (is_first ())
399 return ::safe_dyn_cast<set_info *> (known_first ());
400 return ::dyn_cast<set_info *> (known_second ()->first_def ());
401}
402
403inline def_info *
4a3073f0 404def_lookup::last_def_of_prev_group () const
73b75827
RS
405{
406 if (!mux)
407 return nullptr;
408
409 if (comparison > 0)
410 return mux.last_def ();
411
412 return mux.first_def ()->prev_def ();
413}
414
415inline def_info *
4a3073f0 416def_lookup::first_def_of_next_group () const
73b75827
RS
417{
418 if (!mux)
419 return nullptr;
420
421 if (comparison < 0)
422 return mux.first_def ();
423
424 return mux.last_def ()->next_def ();
425}
426
427inline set_info *
428def_lookup::matching_set () const
429{
430 if (comparison == 0)
431 return mux.set ();
432 return nullptr;
433}
434
435inline def_info *
4a3073f0 436def_lookup::matching_set_or_last_def_of_prev_group () const
73b75827
RS
437{
438 if (set_info *set = matching_set ())
439 return set;
4a3073f0 440 return last_def_of_prev_group ();
73b75827
RS
441}
442
443inline def_info *
4a3073f0 444def_lookup::matching_set_or_first_def_of_next_group () const
73b75827
RS
445{
446 if (set_info *set = matching_set ())
447 return set;
4a3073f0 448 return first_def_of_next_group ();
73b75827
RS
449}
450
451inline insn_note::insn_note (insn_note_kind kind)
452 : m_next_note (nullptr),
453 m_kind (kind),
454 m_data8 (0),
455 m_data16 (0),
456 m_data32 (0)
457{
458}
459
460template<typename T>
461inline T
462insn_note::as_a ()
463{
464 using deref_type = decltype (*std::declval<T> ());
465 using derived = typename std::remove_reference<deref_type>::type;
466 gcc_checking_assert (m_kind == derived::kind);
467 return static_cast<T> (this);
468}
469
470template<typename T>
471inline T
472insn_note::dyn_cast ()
473{
474 using deref_type = decltype (*std::declval<T> ());
475 using derived = typename std::remove_reference<deref_type>::type;
476 if (m_kind == derived::kind)
477 return static_cast<T> (this);
478 return nullptr;
479}
480
481inline bool
482insn_info::operator< (const insn_info &other) const
483{
484 if (this == &other)
485 return false;
486
22d9c880 487 if (LIKELY (m_point != other.m_point))
73b75827
RS
488 return m_point < other.m_point;
489
490 return slow_compare_with (other) < 0;
491}
492
493inline bool
494insn_info::operator> (const insn_info &other) const
495{
496 return other < *this;
497}
498
499inline bool
500insn_info::operator<= (const insn_info &other) const
501{
502 return !(other < *this);
503}
504
505inline bool
506insn_info::operator>= (const insn_info &other) const
507{
508 return !(*this < other);
509}
510
511inline int
512insn_info::compare_with (const insn_info *other) const
513{
514 if (this == other)
515 return 0;
516
22d9c880 517 if (LIKELY (m_point != other->m_point))
73b75827
RS
518 // Assume that points remain in [0, INT_MAX].
519 return m_point - other->m_point;
520
521 return slow_compare_with (*other);
522}
523
524inline insn_info *
525insn_info::prev_nondebug_insn () const
526{
527 gcc_checking_assert (!is_debug_insn ());
528 return m_prev_insn_or_last_debug_insn.known_first ();
529}
530
531inline insn_info *
532insn_info::next_nondebug_insn () const
533{
534 gcc_checking_assert (!is_debug_insn ());
535 const insn_info *from = this;
536 if (insn_info *first_debug = m_next_nondebug_or_debug_insn.second_or_null ())
537 from = first_debug->last_debug_insn ();
538 return from->m_next_nondebug_or_debug_insn.known_first ();
539}
540
541inline insn_info *
542insn_info::prev_any_insn () const
543{
544 const insn_info *from = this;
545 if (insn_info *last_debug = m_prev_insn_or_last_debug_insn.second_or_null ())
546 // This instruction is the first in a subsequence of debug instructions.
547 // Move to the following nondebug instruction.
548 from = last_debug->m_next_nondebug_or_debug_insn.known_first ();
549 return from->m_prev_insn_or_last_debug_insn.known_first ();
550}
551
552inline insn_info *
553insn_info::next_any_insn () const
554{
555 // This should get optimized into an AND with -2.
556 if (m_next_nondebug_or_debug_insn.is_first ())
557 return m_next_nondebug_or_debug_insn.known_first ();
558 return m_next_nondebug_or_debug_insn.known_second ();
559}
560
561inline bool
562insn_info::is_phi () const
563{
564 return this == ebb ()->phi_insn ();
565}
566
567inline bool
568insn_info::is_bb_head () const
569{
570 return this == m_bb->head_insn ();
571}
572
573inline bool
574insn_info::is_bb_end () const
575{
576 return this == m_bb->end_insn ();
577}
578
579inline ebb_info *
580insn_info::ebb () const
581{
582 return m_bb->ebb ();
583}
584
585inline int
586insn_info::uid () const
587{
588 return m_cost_or_uid < 0 ? m_cost_or_uid : INSN_UID (m_rtl);
589}
590
591inline use_array
592insn_info::uses () const
593{
594 return use_array (m_accesses + m_num_defs, m_num_uses);
595}
596
597inline bool
598insn_info::has_call_clobbers () const
599{
600 return find_note<insn_call_clobbers_note> ();
601}
602
603inline def_array
604insn_info::defs () const
605{
606 return def_array (m_accesses, m_num_defs);
607}
608
609inline unsigned int
610insn_info::cost () const
611{
612 if (m_cost_or_uid < 0)
613 return 0;
614 if (m_cost_or_uid == UNKNOWN_COST)
615 calculate_cost ();
616 return m_cost_or_uid;
617}
618
619template<typename T>
620inline const T *
621insn_info::find_note () const
622{
623 // We could break if the note kind is > T::kind, but since the number
624 // of notes should be very small, the check is unlikely to pay for itself.
625 for (const insn_note *note = first_note (); note; note = note->next_note ())
626 if (note->kind () == T::kind)
627 return static_cast<const T *> (note);
628 return nullptr;
629}
630
631// Only valid for debug instructions that come after a nondebug instruction,
632// and so start a subsequence of debug instructions. Return the last debug
633// instruction in the subsequence.
634inline insn_info *
635insn_info::last_debug_insn () const
636{
637 return m_prev_insn_or_last_debug_insn.known_second ();
638}
639
640inline insn_range_info::insn_range_info (insn_info *first, insn_info *last)
641 : first (first), last (last)
642{
643}
644
645inline bool
646insn_range_info::operator== (const insn_range_info &other) const
647{
648 return first == other.first && last == other.last;
649}
650
651inline bool
652insn_range_info::operator!= (const insn_range_info &other) const
653{
654 return first != other.first || last != other.last;
655}
656
657inline insn_info *
658insn_range_info::singleton () const
659{
660 return first == last ? last : nullptr;
661}
662
663inline bool
664insn_range_info::includes (insn_info *insn) const
665{
666 return *insn >= *first && *insn <= *last;
667}
668
669inline insn_info *
670insn_range_info::clamp_insn_to_range (insn_info *insn) const
671{
672 if (*first > *insn)
673 return first;
674 if (*last < *insn)
675 return last;
676 return insn;
677}
678
679inline bool
680insn_range_info::is_subrange_of (const insn_range_info &other) const
681{
682 return *first >= *other.first && *last <= *other.last;
683}
684
685inline iterator_range<any_insn_iterator>
686bb_info::all_insns () const
687{
688 return { m_head_insn, m_end_insn->next_any_insn () };
689}
690
691inline iterator_range<reverse_any_insn_iterator>
692bb_info::reverse_all_insns () const
693{
694 return { m_end_insn, m_head_insn->prev_any_insn () };
695}
696
697inline iterator_range<nondebug_insn_iterator>
698bb_info::nondebug_insns () const
699{
700 return { m_head_insn, m_end_insn->next_nondebug_insn () };
701}
702
703inline iterator_range<reverse_nondebug_insn_iterator>
704bb_info::reverse_nondebug_insns () const
705{
706 return { m_end_insn, m_head_insn->prev_nondebug_insn () };
707}
708
709inline iterator_range<any_insn_iterator>
710bb_info::real_insns () const
711{
712 return { m_head_insn->next_any_insn (), m_end_insn };
713}
714
715inline iterator_range<reverse_any_insn_iterator>
716bb_info::reverse_real_insns () const
717{
718 return { m_end_insn->prev_any_insn (), m_head_insn };
719}
720
721inline iterator_range<nondebug_insn_iterator>
722bb_info::real_nondebug_insns () const
723{
724 return { m_head_insn->next_nondebug_insn (), m_end_insn };
725}
726
727inline iterator_range<reverse_nondebug_insn_iterator>
728bb_info::reverse_real_nondebug_insns () const
729{
730 return { m_end_insn->prev_nondebug_insn (), m_head_insn };
731}
732
733inline bool
734ebb_call_clobbers_info::clobbers (resource_info resource) const
735{
736 // Only register clobbers are tracked this way. Other clobbers are
737 // recorded explicitly.
738 return (resource.is_reg ()
739 && m_abi->clobbers_reg_p (resource.mode, resource.regno));
740}
741
742inline ebb_info *
743ebb_info::prev_ebb () const
744{
745 if (bb_info *prev_bb = m_first_bb->prev_bb ())
746 return prev_bb->ebb ();
747 return nullptr;
748}
749
750inline ebb_info *
751ebb_info::next_ebb () const
752{
753 if (bb_info *next_bb = m_last_bb->next_bb ())
754 return next_bb->ebb ();
755 return nullptr;
756}
757
758inline iterator_range<phi_iterator>
759ebb_info::phis () const
760{
761 return { m_first_phi, nullptr };
762}
763
764inline iterator_range<bb_iterator>
765ebb_info::bbs () const
766{
767 return { m_first_bb, m_last_bb->next_bb () };
768}
769
770inline iterator_range<reverse_bb_iterator>
771ebb_info::reverse_bbs () const
772{
773 return { m_last_bb, m_first_bb->prev_bb () };
774}
775
776inline iterator_range<any_insn_iterator>
777ebb_info::all_insns () const
778{
779 return { m_phi_insn, m_last_bb->end_insn ()->next_any_insn () };
780}
781
782inline iterator_range<reverse_any_insn_iterator>
783ebb_info::reverse_all_insns () const
784{
785 return { m_last_bb->end_insn (), m_phi_insn->prev_any_insn () };
786}
787
788inline iterator_range<nondebug_insn_iterator>
789ebb_info::nondebug_insns () const
790{
791 return { m_phi_insn, m_last_bb->end_insn ()->next_nondebug_insn () };
792}
793
794inline iterator_range<reverse_nondebug_insn_iterator>
795ebb_info::reverse_nondebug_insns () const
796{
797 return { m_last_bb->end_insn (), m_phi_insn->prev_nondebug_insn () };
798}
799
800inline insn_range_info
801ebb_info::insn_range () const
802{
803 return { m_phi_insn, m_last_bb->end_insn () };
804}
805
806inline void
807ebb_info::set_first_call_clobbers (ebb_call_clobbers_info *call_clobbers)
808{
809 m_first_call_clobbers = call_clobbers;
810}
811
812inline ebb_call_clobbers_info *
813ebb_info::first_call_clobbers () const
814{
815 return m_first_call_clobbers;
816}
817
818inline iterator_range<ebb_call_clobbers_iterator>
819ebb_info::call_clobbers () const
820{
821 return { m_first_call_clobbers, nullptr };
822}
823
824inline insn_change::insn_change (insn_info *insn)
825 : m_insn (insn),
826 new_defs (insn->defs ()),
827 new_uses (insn->uses ()),
828 move_range (insn),
829 new_cost (UNKNOWN_COST),
830 m_is_deletion (false)
831{
832}
833
834inline insn_change::insn_change (insn_info *insn, delete_action)
835 : m_insn (insn),
836 new_defs (),
837 new_uses (),
838 move_range (insn),
839 new_cost (0),
840 m_is_deletion (true)
841{
842}
843
844inline insn_is_changing_closure::
845insn_is_changing_closure (array_slice<insn_change *const> changes)
846 : m_changes (changes)
847{
848}
849
850inline bool
851insn_is_changing_closure::operator() (const insn_info *insn) const
852{
853 for (const insn_change *change : m_changes)
854 if (change->insn () == insn)
855 return true;
856 return false;
857}
858
859inline iterator_range<bb_iterator>
860function_info::bbs () const
861{
862 return { m_first_bb, nullptr };
863}
864
865inline iterator_range<reverse_bb_iterator>
866function_info::reverse_bbs () const
867{
868 return { m_last_bb, nullptr };
869}
870
871inline iterator_range<ebb_iterator>
872function_info::ebbs () const
873{
874 return { m_first_bb->ebb (), nullptr };
875}
876
877inline iterator_range<reverse_ebb_iterator>
878function_info::reverse_ebbs () const
879{
880 return { m_last_bb->ebb (), nullptr };
881}
882
883inline iterator_range<any_insn_iterator>
884function_info::all_insns () const
885{
886 return { m_first_insn, nullptr };
887}
888
889inline iterator_range<reverse_any_insn_iterator>
890function_info::reverse_all_insns () const
891{
892 return { m_last_insn, nullptr };
893}
894
895inline iterator_range<nondebug_insn_iterator>
896function_info::nondebug_insns () const
897{
898 return { m_first_insn, nullptr };
899}
900
901inline iterator_range<reverse_nondebug_insn_iterator>
902function_info::reverse_nondebug_insns () const
903{
904 return { m_last_insn, nullptr };
905}
906
907inline iterator_range<def_iterator>
908function_info::mem_defs () const
909{
910 return { m_defs[0], nullptr };
911}
912
913inline iterator_range<def_iterator>
7f6cdaa9 914function_info::reg_defs (unsigned int regno) const
73b75827
RS
915{
916 return { m_defs[regno + 1], nullptr };
917}
918
919inline set_info *
920function_info::single_dominating_def (unsigned int regno) const
921{
922 if (set_info *set = safe_dyn_cast<set_info *> (m_defs[regno + 1]))
923 if (is_single_dominating_def (set))
924 return set;
925 return nullptr;
926}
927
928template<typename IgnorePredicate>
929bool
930function_info::add_regno_clobber (obstack_watermark &watermark,
931 insn_change &change, unsigned int regno,
932 IgnorePredicate ignore)
933{
934 // Check whether CHANGE already clobbers REGNO.
935 if (find_access (change.new_defs, regno))
936 return true;
937
938 // Get the closest position to INSN at which the new instruction
939 // could be placed.
940 insn_info *insn = change.move_range.clamp_insn_to_range (change.insn ());
941 def_array new_defs = insert_temp_clobber (watermark, insn, regno,
942 change.new_defs);
943 if (!new_defs.is_valid ())
944 return false;
945
946 // Find a definition at or neighboring INSN.
947 insn_range_info move_range = change.move_range;
948 if (!restrict_movement_for_dead_range (move_range, regno, insn, ignore))
949 return false;
950
951 change.new_defs = new_defs;
952 change.move_range = move_range;
953 return true;
954}
955
956}