Line data Source code
1 : // Implementation of public inline member functions for RTL SSA -*- C++ -*-
2 : // Copyright (C) 2020-2026 Free Software Foundation, Inc.
3 : //
4 : // This file is part of GCC.
5 : //
6 : // GCC is free software; you can redistribute it and/or modify it under
7 : // the terms of the GNU General Public License as published by the Free
8 : // Software Foundation; either version 3, or (at your option) any later
9 : // version.
10 : //
11 : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 : // for more details.
15 : //
16 : // You should have received a copy of the GNU General Public License
17 : // along with GCC; see the file COPYING3. If not see
18 : // <http://www.gnu.org/licenses/>.
19 :
20 : // 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.
27 : namespace rtl_ssa {
28 :
29 : inline void
30 79032885 : access_array_builder::reserve (unsigned int num_accesses)
31 : {
32 79032885 : obstack_make_room (m_obstack, num_accesses * sizeof (access_info *));
33 79032885 : }
34 :
35 : inline void
36 154837602 : access_array_builder::quick_push (access_info *access)
37 : {
38 131243020 : obstack_ptr_grow_fast (m_obstack, access);
39 24756587 : }
40 :
41 : inline array_slice<access_info *>
42 76542123 : access_array_builder::finish ()
43 : {
44 76542123 : unsigned num_accesses
45 76542123 : = obstack_object_size (m_obstack) / sizeof (access_info *);
46 76542123 : if (num_accesses == 0)
47 13586675 : return {};
48 :
49 62955448 : auto **base = static_cast<access_info **> (obstack_finish (m_obstack));
50 62955448 : keep ();
51 62955448 : return { base, num_accesses };
52 : }
53 :
54 : inline bool
55 146202420 : access_info::is_set_with_nondebug_insn_uses () const
56 : {
57 146202420 : return m_is_set_with_nondebug_insn_uses;
58 : }
59 :
60 : inline bool
61 1251011717 : use_info::is_in_debug_insn () const
62 : {
63 1251011717 : return m_insn_or_phi.is_first () && m_is_in_debug_insn_or_phi;
64 : }
65 :
66 : inline bb_info *
67 248592922 : use_info::bb () const
68 : {
69 147511225 : if (m_insn_or_phi.is_first ())
70 248592922 : return m_insn_or_phi.known_first ()->bb ();
71 4521686 : return m_insn_or_phi.known_second ()->bb ();
72 : }
73 :
74 : inline ebb_info *
75 46228961 : use_info::ebb () const
76 : {
77 213757028 : return bb ()->ebb ();
78 : }
79 :
80 : inline use_info *
81 1663663700 : use_info::prev_use () const
82 : {
83 2719671213 : return m_last_use_or_prev_use.second_or_null ();
84 : }
85 :
86 : inline use_info *
87 5407978904 : use_info::next_use () const
88 : {
89 8226390393 : return m_last_nondebug_insn_use_or_next_use.second_or_null ();
90 : }
91 :
92 : inline bool
93 : use_info::is_first_use () const
94 : {
95 : return m_last_use_or_prev_use.is_first ();
96 : }
97 :
98 : inline bool
99 : use_info::is_last_use () const
100 : {
101 : return m_last_nondebug_insn_use_or_next_use.is_first ();
102 : }
103 :
104 : inline use_info *
105 160859178 : use_info::next_nondebug_insn_use () const
106 : {
107 160859178 : if (m_is_last_nondebug_insn_use)
108 : return nullptr;
109 30773806 : return m_last_nondebug_insn_use_or_next_use.known_second ();
110 : }
111 :
112 : inline use_info *
113 46828226 : use_info::next_any_insn_use () const
114 : {
115 : // This is used less often than next_nondebug_insn_use, so it doesn't
116 : // seem worth having an m_is_last_nondebug_insn_use-style end marker.
117 46828226 : if (use_info *use = next_use ())
118 43540028 : if (use->is_in_any_insn ())
119 42653279 : return use;
120 : return nullptr;
121 : }
122 :
123 : inline use_info *
124 : use_info::next_debug_insn_use () const
125 : {
126 : if (auto use = next_use ())
127 : if (use->is_in_debug_insn ())
128 : return use;
129 : return nullptr;
130 : }
131 :
132 : inline use_info *
133 37416655 : use_info::prev_phi_use () const
134 : {
135 : // This is used less often than next_nondebug_insn_use, so it doesn't
136 : // seem worth having an m_is_last_nondebug_insn_use-style end marker.
137 37416655 : if (use_info *use = prev_use ())
138 34580734 : if (use->is_in_phi ())
139 : return use;
140 : return nullptr;
141 : }
142 :
143 : // Return the last use of any kind in the list. Only valid when is_first ()
144 : // is true.
145 : inline use_info *
146 965828610 : use_info::last_use () const
147 : {
148 1400334518 : return m_last_use_or_prev_use.known_first ();
149 : }
150 :
151 : // Return the last nondebug insn use in the list, or null if none. Only valid
152 : // when is_last_use () is true.
153 : inline use_info *
154 530108806 : use_info::last_nondebug_insn_use () const
155 : {
156 1490809618 : return m_last_nondebug_insn_use_or_next_use.known_first ();
157 : }
158 :
159 : inline def_info *
160 140502305 : def_info::prev_def () const
161 : {
162 302041443 : return m_last_def_or_prev_def.second_or_null ();
163 : }
164 :
165 : inline def_info *
166 335564503 : def_info::next_def () const
167 : {
168 632512887 : return m_splay_root_or_next_def.second_or_null ();
169 : }
170 :
171 : inline bool
172 100229360 : def_info::is_first_def () const
173 : {
174 100229360 : return m_last_def_or_prev_def.is_first ();
175 : }
176 :
177 : inline bool
178 97578024 : def_info::is_last_def () const
179 : {
180 84729423 : return m_splay_root_or_next_def.is_first ();
181 : }
182 :
183 : inline bb_info *
184 762756607 : def_info::bb () const
185 : {
186 758208353 : return m_insn->bb ();
187 : }
188 :
189 : inline ebb_info *
190 1074930611 : def_info::ebb () const
191 : {
192 1083670830 : return m_insn->ebb ();
193 : }
194 :
195 : inline clobber_group *
196 94885395 : clobber_info::group () const
197 : {
198 94885395 : if (!m_group || !m_group->has_been_superceded ())
199 : return m_group;
200 1399 : return const_cast<clobber_info *> (this)->recompute_group ();
201 : }
202 :
203 : inline use_info *
204 109772185 : set_info::last_use () const
205 : {
206 109772185 : return m_first_use ? m_first_use->last_use () : nullptr;
207 : }
208 :
209 : inline use_info *
210 338084413 : set_info::first_nondebug_insn_use () const
211 : {
212 338084413 : if (m_is_set_with_nondebug_insn_uses)
213 277449252 : return m_first_use;
214 : return nullptr;
215 : }
216 :
217 : inline use_info *
218 87817095 : set_info::last_nondebug_insn_use () const
219 : {
220 87817095 : if (m_is_set_with_nondebug_insn_uses)
221 87817095 : return m_first_use->last_use ()->last_nondebug_insn_use ();
222 : return nullptr;
223 : }
224 :
225 : inline use_info *
226 : set_info::first_debug_insn_use () const
227 : {
228 : use_info *use;
229 : if (has_nondebug_insn_uses ())
230 : use = last_nondebug_insn_use ()->next_use ();
231 : else
232 : use = first_use ();
233 :
234 : if (use && use->is_in_debug_insn ())
235 : return use;
236 : return nullptr;
237 : }
238 :
239 : inline use_info *
240 4210718 : set_info::first_any_insn_use () const
241 : {
242 4174947 : if (m_first_use && m_first_use->is_in_any_insn ())
243 : return m_first_use;
244 : return nullptr;
245 : }
246 :
247 : inline use_info *
248 136771930 : set_info::last_phi_use () const
249 : {
250 136771930 : if (m_first_use)
251 : {
252 129340458 : use_info *last = m_first_use->last_use ();
253 129340458 : if (last->is_in_phi ())
254 2330652 : return last;
255 : }
256 : return nullptr;
257 : }
258 :
259 : inline bool
260 20064069 : set_info::has_nondebug_uses () const
261 : {
262 99797667 : return has_nondebug_insn_uses () || has_phi_uses ();
263 : }
264 :
265 : inline bool
266 21978132 : set_info::has_nondebug_insn_uses () const
267 : {
268 21978132 : return m_is_set_with_nondebug_insn_uses;
269 : }
270 :
271 : inline bool
272 39674897 : set_info::has_phi_uses () const
273 : {
274 39674897 : return m_first_use && m_first_use->last_use ()->is_in_phi ();
275 : }
276 :
277 : inline use_info *
278 33622961 : set_info::single_nondebug_use () const
279 : {
280 33622961 : if (!has_phi_uses ())
281 31708898 : return single_nondebug_insn_use ();
282 1914063 : if (!has_nondebug_insn_uses ())
283 0 : return single_phi_use ();
284 : return nullptr;
285 : }
286 :
287 : inline use_info *
288 106433562 : set_info::single_nondebug_insn_use () const
289 : {
290 106433562 : use_info *first = first_nondebug_insn_use ();
291 95225320 : if (first && !first->next_nondebug_insn_use ())
292 69437562 : return first;
293 : return nullptr;
294 : }
295 :
296 : inline use_info *
297 0 : set_info::single_phi_use () const
298 : {
299 0 : use_info *last = last_phi_use ();
300 0 : if (last && !last->prev_phi_use ())
301 0 : return last;
302 : return nullptr;
303 : }
304 :
305 : inline bool
306 : set_info::is_local_to_ebb () const
307 : {
308 : if (!m_first_use)
309 : return true;
310 :
311 : use_info *last = m_first_use->last_use ();
312 : if (last->is_in_phi ())
313 : return false;
314 :
315 : last = last->last_nondebug_insn_use ();
316 : return !last || last->ebb () == ebb ();
317 : }
318 :
319 : inline iterator_range<use_iterator>
320 0 : set_info::all_uses () const
321 : {
322 0 : return { m_first_use, nullptr };
323 : }
324 :
325 : inline iterator_range<reverse_use_iterator>
326 : set_info::reverse_all_uses () const
327 : {
328 : return { last_use (), nullptr };
329 : }
330 :
331 : inline iterator_range<nondebug_insn_use_iterator>
332 137749104 : set_info::nondebug_insn_uses () const
333 : {
334 336661161 : return { first_nondebug_insn_use (), nullptr };
335 : }
336 :
337 : inline iterator_range<debug_insn_use_iterator>
338 : set_info::debug_insn_uses () const
339 : {
340 : return { first_debug_insn_use (), nullptr };
341 : }
342 :
343 : inline iterator_range<reverse_use_iterator>
344 : set_info::reverse_nondebug_insn_uses () const
345 : {
346 : return { last_nondebug_insn_use (), nullptr };
347 : }
348 :
349 : inline iterator_range<any_insn_use_iterator>
350 4210718 : set_info::all_insn_uses () const
351 : {
352 46649639 : return { first_any_insn_use (), nullptr };
353 : }
354 :
355 : inline iterator_range<phi_use_iterator>
356 132944840 : set_info::phi_uses () const
357 : {
358 265889680 : return { last_phi_use (), nullptr };
359 : }
360 :
361 : inline use_array
362 163405734 : phi_info::inputs () const
363 : {
364 163405734 : if (m_num_inputs == 1)
365 128985243 : return use_array (&m_single_input, 1);
366 34420491 : return use_array (m_inputs, m_num_inputs);
367 : }
368 :
369 : inline use_info *
370 133047505 : phi_info::input_use (unsigned int i) const
371 : {
372 133047505 : if (m_num_inputs == 1)
373 44485057 : return as_a<use_info *> (m_single_input);
374 88562448 : return as_a<use_info *> (m_inputs[i]);
375 : }
376 :
377 : inline set_info *
378 44485057 : phi_info::input_value (unsigned int i) const
379 : {
380 44485057 : return input_use (i)->def ();
381 : }
382 :
383 : inline def_info *
384 57476077 : def_node::first_def () const
385 : {
386 : // This should get optimized into an AND with -2.
387 53773952 : if (m_clobber_or_set.is_first ())
388 : return m_clobber_or_set.known_first ();
389 41248404 : return m_clobber_or_set.known_second ();
390 : }
391 :
392 : inline clobber_info *
393 13627501 : clobber_group::first_clobber () const
394 : {
395 13627501 : return m_clobber_or_set.known_first ();
396 : }
397 :
398 : inline iterator_range<def_iterator>
399 0 : clobber_group::clobbers () const
400 : {
401 0 : return { first_clobber (), m_last_clobber->next_def () };
402 : }
403 :
404 : inline def_info *
405 3910748 : def_mux::first_def () const
406 : {
407 3827260 : if (is_first ())
408 : return known_first ();
409 3901048 : return known_second ()->first_def ();
410 : }
411 :
412 : inline def_info *
413 4801761 : def_mux::last_def () const
414 : {
415 4801761 : if (is_first ())
416 : return known_first ();
417 :
418 3506601 : def_node *node = known_second ();
419 3506601 : if (auto *clobber = ::dyn_cast<clobber_group *> (node))
420 3091769 : return clobber->last_clobber ();
421 :
422 414832 : return node->first_def ();
423 : }
424 :
425 : inline set_info *
426 1211077 : def_mux::set () const
427 : {
428 1211077 : if (is_first ())
429 4427 : return ::safe_dyn_cast<set_info *> (known_first ());
430 1346671 : return ::dyn_cast<set_info *> (known_second ()->first_def ());
431 : }
432 :
433 : inline def_info *
434 2148957 : def_lookup::last_def_of_prev_group () const
435 : {
436 2148957 : if (!mux)
437 : return nullptr;
438 :
439 2148235 : if (comparison > 0)
440 715311 : return mux.last_def ();
441 :
442 2860997 : return mux.first_def ()->prev_def ();
443 : }
444 :
445 : inline def_info *
446 2148913 : def_lookup::first_def_of_next_group () const
447 : {
448 2148913 : if (!mux)
449 : return nullptr;
450 :
451 2148191 : if (comparison < 0)
452 366257 : return mux.first_def ();
453 :
454 1781934 : return mux.last_def ()->next_def ();
455 : }
456 :
457 : inline set_info *
458 2305238 : def_lookup::matching_set () const
459 : {
460 2305238 : if (comparison == 0)
461 1211077 : return mux.set ();
462 : return nullptr;
463 : }
464 :
465 : inline def_info *
466 : def_lookup::matching_set_or_last_def_of_prev_group () const
467 : {
468 : if (set_info *set = matching_set ())
469 : return set;
470 : return last_def_of_prev_group ();
471 : }
472 :
473 : inline def_info *
474 1964368 : def_lookup::matching_set_or_first_def_of_next_group () const
475 : {
476 1964368 : if (set_info *set = matching_set ())
477 : return set;
478 1964324 : return first_def_of_next_group ();
479 : }
480 :
481 : inline use_info *
482 : use_lookup::prev_use () const
483 : {
484 : return !use || comparison > 0 ? use : use->prev_use ();
485 : }
486 :
487 : inline use_info *
488 : use_lookup::next_use () const
489 : {
490 : return !use || comparison < 0 ? use : use->next_nondebug_insn_use ();
491 : }
492 :
493 : inline use_info *
494 93901747 : use_lookup::matching_use () const
495 : {
496 93901747 : return comparison == 0 ? use : nullptr;
497 : }
498 :
499 : inline use_info *
500 : use_lookup::matching_or_prev_use () const
501 : {
502 : return comparison == 0 ? use : prev_use ();
503 : }
504 :
505 : inline use_info *
506 : use_lookup::matching_or_next_use () const
507 : {
508 : return comparison == 0 ? use : next_use ();
509 : }
510 :
511 25424254 : inline insn_note::insn_note (insn_note_kind kind)
512 25424254 : : m_next_note (nullptr),
513 25424254 : m_kind (kind),
514 25424254 : m_data8 (0),
515 25424254 : m_data16 (0),
516 : m_data32 (0)
517 : {
518 : }
519 :
520 : template<typename T>
521 : inline T
522 1702 : insn_note::as_a ()
523 : {
524 : using deref_type = decltype (*std::declval<T> ());
525 : using derived = typename std::remove_reference<deref_type>::type;
526 1702 : gcc_checking_assert (m_kind == derived::kind);
527 1702 : return static_cast<T> (this);
528 : }
529 :
530 : template<typename T>
531 : inline T
532 1304 : insn_note::dyn_cast ()
533 : {
534 : using deref_type = decltype (*std::declval<T> ());
535 : using derived = typename std::remove_reference<deref_type>::type;
536 1304 : if (m_kind == derived::kind)
537 : return static_cast<T> (this);
538 : return nullptr;
539 : }
540 :
541 : inline bool
542 1084758397 : insn_info::operator< (const insn_info &other) const
543 : {
544 1084758397 : if (this == &other)
545 : return false;
546 :
547 793882572 : if (LIKELY (m_point != other.m_point))
548 793882243 : return m_point < other.m_point;
549 :
550 329 : return slow_compare_with (other) < 0;
551 : }
552 :
553 : inline bool
554 117231981 : insn_info::operator> (const insn_info &other) const
555 : {
556 116733374 : return other < *this;
557 : }
558 :
559 : inline bool
560 314812132 : insn_info::operator<= (const insn_info &other) const
561 : {
562 314812132 : return !(other < *this);
563 : }
564 :
565 : inline bool
566 49953151 : insn_info::operator>= (const insn_info &other) const
567 : {
568 49953151 : return !(*this < other);
569 : }
570 :
571 : inline int
572 979364860 : insn_info::compare_with (const insn_info *other) const
573 : {
574 979364860 : if (this == other)
575 : return 0;
576 :
577 953294527 : if (LIKELY (m_point != other->m_point))
578 : // Assume that points remain in [0, INT_MAX].
579 953294005 : return m_point - other->m_point;
580 :
581 522 : return slow_compare_with (*other);
582 : }
583 :
584 : inline insn_info *
585 280951787 : insn_info::prev_nondebug_insn () const
586 : {
587 280951787 : gcc_checking_assert (!is_debug_insn ());
588 280951787 : return m_prev_sametype_or_last_debug_insn.known_first ();
589 : }
590 :
591 : inline insn_info *
592 351994565 : insn_info::next_nondebug_insn () const
593 : {
594 351994565 : gcc_checking_assert (!is_debug_insn ());
595 351994565 : const insn_info *from = this;
596 351994565 : if (insn_info *first_debug = m_next_nondebug_or_debug_insn.second_or_null ())
597 27985382 : from = first_debug->last_debug_insn ();
598 351994565 : return from->m_next_nondebug_or_debug_insn.known_first ();
599 : }
600 :
601 : inline insn_info *
602 2240341 : insn_info::prev_any_insn () const
603 : {
604 2240341 : if (auto *last_debug = m_prev_sametype_or_last_debug_insn.second_or_null ())
605 : // This instruction is the first in a subsequence of debug instructions.
606 : // Move to the following nondebug instruction and get the previous one
607 : // from there.
608 0 : return (last_debug->m_next_nondebug_or_debug_insn.known_first ()
609 0 : ->m_prev_sametype_or_last_debug_insn.known_first ());
610 2240341 : auto *prev = m_prev_sametype_or_last_debug_insn.known_first ();
611 2240341 : if (prev)
612 : {
613 4480682 : auto *next = prev->next_any_insn ();
614 2240341 : if (next != this)
615 : // This instruction is a non-debug instruction and there are some
616 : // debug instructions between it and PREV. NEXT is the first of
617 : // the debug instructions; get the last.
618 114608 : return next->m_prev_sametype_or_last_debug_insn.known_second ();
619 : }
620 : return prev;
621 : }
622 :
623 : inline insn_info *
624 1421043457 : insn_info::next_any_insn () const
625 : {
626 : // This should get optimized into an AND with -2.
627 1421043457 : if (m_next_nondebug_or_debug_insn.is_first ())
628 : return m_next_nondebug_or_debug_insn.known_first ();
629 390931875 : return m_next_nondebug_or_debug_insn.known_second ();
630 : }
631 :
632 : inline bool
633 0 : insn_info::is_phi () const
634 : {
635 0 : return this == ebb ()->phi_insn ();
636 : }
637 :
638 : inline bool
639 16437140 : insn_info::is_bb_head () const
640 : {
641 16437140 : return this == m_bb->head_insn ();
642 : }
643 :
644 : inline bool
645 : insn_info::is_bb_end () const
646 : {
647 : return this == m_bb->end_insn ();
648 : }
649 :
650 : inline ebb_info *
651 1089457864 : insn_info::ebb () const
652 : {
653 1057651061 : return m_bb->ebb ();
654 : }
655 :
656 : inline int
657 8428 : insn_info::uid () const
658 : {
659 8428 : return m_cost_or_uid < 0 ? m_cost_or_uid : INSN_UID (m_rtl);
660 : }
661 :
662 : inline use_array
663 504479116 : insn_info::uses () const
664 : {
665 409797754 : return use_array (m_accesses + m_num_defs, m_num_uses);
666 : }
667 :
668 : inline bool
669 : insn_info::has_call_clobbers () const
670 : {
671 : return find_note<insn_call_clobbers_note> ();
672 : }
673 :
674 : inline def_array
675 329629501 : insn_info::defs () const
676 : {
677 291555548 : return def_array (m_accesses, m_num_defs);
678 : }
679 :
680 : inline unsigned int
681 27939981 : insn_info::cost () const
682 : {
683 27939981 : if (m_cost_or_uid < 0)
684 : return 0;
685 27939981 : if (m_cost_or_uid == UNKNOWN_COST)
686 14366310 : calculate_cost ();
687 27939981 : return m_cost_or_uid;
688 : }
689 :
690 : template<typename T>
691 : inline const T *
692 2188753 : insn_info::find_note () const
693 : {
694 : // We could break if the note kind is > T::kind, but since the number
695 : // of notes should be very small, the check is unlikely to pay for itself.
696 2188753 : for (const insn_note *note = first_note (); note; note = note->next_note ())
697 0 : if (note->kind () == T::kind)
698 : return static_cast<const T *> (note);
699 : return nullptr;
700 : }
701 :
702 : // Only valid for debug instructions that come after a nondebug instruction,
703 : // and so start a subsequence of debug instructions. Return the last debug
704 : // instruction in the subsequence.
705 : inline insn_info *
706 28003743 : insn_info::last_debug_insn () const
707 : {
708 28003743 : return m_prev_sametype_or_last_debug_insn.known_second ();
709 : }
710 :
711 274330104 : inline insn_range_info::insn_range_info (insn_info *first, insn_info *last)
712 : : first (first), last (last)
713 : {
714 : }
715 :
716 : inline bool
717 : insn_range_info::operator== (const insn_range_info &other) const
718 : {
719 : return first == other.first && last == other.last;
720 : }
721 :
722 : inline bool
723 : insn_range_info::operator!= (const insn_range_info &other) const
724 : {
725 : return first != other.first || last != other.last;
726 : }
727 :
728 : inline insn_info *
729 : insn_range_info::singleton () const
730 : {
731 : return first == last ? last : nullptr;
732 : }
733 :
734 : inline bool
735 : insn_range_info::includes (insn_info *insn) const
736 : {
737 : return *insn >= *first && *insn <= *last;
738 : }
739 :
740 : inline insn_info *
741 2462975 : insn_range_info::clamp_insn_to_range (insn_info *insn) const
742 : {
743 2462975 : if (*first > *insn)
744 0 : return first;
745 2462975 : if (*last < *insn)
746 23661 : return last;
747 : return insn;
748 : }
749 :
750 : inline bool
751 : insn_range_info::is_subrange_of (const insn_range_info &other) const
752 : {
753 : return *first >= *other.first && *last <= *other.last;
754 : }
755 :
756 : inline iterator_range<any_insn_iterator>
757 : bb_info::all_insns () const
758 : {
759 : return { m_head_insn, m_end_insn->next_any_insn () };
760 : }
761 :
762 : inline iterator_range<reverse_any_insn_iterator>
763 : bb_info::reverse_all_insns () const
764 : {
765 : return { m_end_insn, m_head_insn->prev_any_insn () };
766 : }
767 :
768 : inline iterator_range<nondebug_insn_iterator>
769 : bb_info::nondebug_insns () const
770 : {
771 : return { m_head_insn, m_end_insn->next_nondebug_insn () };
772 : }
773 :
774 : inline iterator_range<reverse_nondebug_insn_iterator>
775 : bb_info::reverse_nondebug_insns () const
776 : {
777 : return { m_end_insn, m_head_insn->prev_nondebug_insn () };
778 : }
779 :
780 : inline iterator_range<any_insn_iterator>
781 0 : bb_info::real_insns () const
782 : {
783 0 : return { m_head_insn->next_any_insn (), m_end_insn };
784 : }
785 :
786 : inline iterator_range<reverse_any_insn_iterator>
787 : bb_info::reverse_real_insns () const
788 : {
789 : return { m_end_insn->prev_any_insn (), m_head_insn };
790 : }
791 :
792 : inline iterator_range<nondebug_insn_iterator>
793 : bb_info::real_nondebug_insns () const
794 : {
795 : return { m_head_insn->next_nondebug_insn (), m_end_insn };
796 : }
797 :
798 : inline iterator_range<reverse_nondebug_insn_iterator>
799 : bb_info::reverse_real_nondebug_insns () const
800 : {
801 : return { m_end_insn->prev_nondebug_insn (), m_head_insn };
802 : }
803 :
804 : inline bool
805 52494834 : ebb_call_clobbers_info::clobbers (resource_info resource) const
806 : {
807 : // Only register clobbers are tracked this way. Other clobbers are
808 : // recorded explicitly.
809 52494834 : return (resource.is_reg ()
810 52494834 : && m_abi->clobbers_reg_p (resource.mode, resource.regno));
811 : }
812 :
813 : inline ebb_info *
814 : ebb_info::prev_ebb () const
815 : {
816 : if (bb_info *prev_bb = m_first_bb->prev_bb ())
817 : return prev_bb->ebb ();
818 : return nullptr;
819 : }
820 :
821 : inline ebb_info *
822 91711228 : ebb_info::next_ebb () const
823 : {
824 91711228 : if (bb_info *next_bb = m_last_bb->next_bb ())
825 79805756 : return next_bb->ebb ();
826 : return nullptr;
827 : }
828 :
829 : inline iterator_range<phi_iterator>
830 82790135 : ebb_info::phis () const
831 : {
832 82790135 : return { m_first_phi, nullptr };
833 : }
834 :
835 : inline iterator_range<bb_iterator>
836 33952304 : ebb_info::bbs () const
837 : {
838 33952304 : return { m_first_bb, m_last_bb->next_bb () };
839 : }
840 :
841 : inline iterator_range<reverse_bb_iterator>
842 : ebb_info::reverse_bbs () const
843 : {
844 : return { m_last_bb, m_first_bb->prev_bb () };
845 : }
846 :
847 : inline iterator_range<any_insn_iterator>
848 : ebb_info::all_insns () const
849 : {
850 : return { m_phi_insn, m_last_bb->end_insn ()->next_any_insn () };
851 : }
852 :
853 : inline iterator_range<reverse_any_insn_iterator>
854 : ebb_info::reverse_all_insns () const
855 : {
856 : return { m_last_bb->end_insn (), m_phi_insn->prev_any_insn () };
857 : }
858 :
859 : inline iterator_range<nondebug_insn_iterator>
860 : ebb_info::nondebug_insns () const
861 : {
862 : return { m_phi_insn, m_last_bb->end_insn ()->next_nondebug_insn () };
863 : }
864 :
865 : inline iterator_range<reverse_nondebug_insn_iterator>
866 : ebb_info::reverse_nondebug_insns () const
867 : {
868 : return { m_last_bb->end_insn (), m_phi_insn->prev_nondebug_insn () };
869 : }
870 :
871 : inline insn_range_info
872 4274291 : ebb_info::insn_range () const
873 : {
874 4274291 : return { m_phi_insn, m_last_bb->end_insn () };
875 : }
876 :
877 : inline void
878 14808837 : ebb_info::set_first_call_clobbers (ebb_call_clobbers_info *call_clobbers)
879 : {
880 14808837 : m_first_call_clobbers = call_clobbers;
881 14808837 : }
882 :
883 : inline ebb_call_clobbers_info *
884 40231332 : ebb_info::first_call_clobbers () const
885 : {
886 40231332 : return m_first_call_clobbers;
887 : }
888 :
889 : inline iterator_range<ebb_call_clobbers_iterator>
890 79476728 : ebb_info::call_clobbers () const
891 : {
892 79476728 : return { m_first_call_clobbers, nullptr };
893 : }
894 :
895 71438406 : inline insn_change::insn_change (insn_info *insn)
896 71438406 : : m_insn (insn),
897 71438406 : new_defs (insn->defs ()),
898 71438406 : new_uses (insn->uses ()),
899 71438406 : move_range (insn),
900 71438406 : new_cost (UNKNOWN_COST),
901 71438406 : m_is_deletion (false)
902 : {
903 : }
904 :
905 24973484 : inline insn_change::insn_change (insn_info *insn, delete_action)
906 24973484 : : m_insn (insn),
907 24973484 : new_defs (),
908 24973484 : new_uses (),
909 24973484 : move_range (insn),
910 24973484 : new_cost (0),
911 24973484 : m_is_deletion (true)
912 : {
913 : }
914 :
915 : inline iterator_range<bb_iterator>
916 : function_info::bbs () const
917 : {
918 : return { m_first_bb, nullptr };
919 : }
920 :
921 : inline iterator_range<reverse_bb_iterator>
922 : function_info::reverse_bbs () const
923 : {
924 : return { m_last_bb, nullptr };
925 : }
926 :
927 : inline iterator_range<ebb_iterator>
928 11905472 : function_info::ebbs () const
929 : {
930 11905472 : return { m_first_bb->ebb (), nullptr };
931 : }
932 :
933 : inline iterator_range<reverse_ebb_iterator>
934 : function_info::reverse_ebbs () const
935 : {
936 : return { m_last_bb->ebb (), nullptr };
937 : }
938 :
939 : inline iterator_range<any_insn_iterator>
940 : function_info::all_insns () const
941 : {
942 : return { m_first_insn, nullptr };
943 : }
944 :
945 : inline iterator_range<reverse_any_insn_iterator>
946 : function_info::reverse_all_insns () const
947 : {
948 : return { m_last_insn, nullptr };
949 : }
950 :
951 : inline iterator_range<nondebug_insn_iterator>
952 3861770 : function_info::nondebug_insns () const
953 : {
954 3861770 : return { m_first_insn, nullptr };
955 : }
956 :
957 : inline iterator_range<reverse_nondebug_insn_iterator>
958 : function_info::reverse_nondebug_insns () const
959 : {
960 : return { m_last_insn, nullptr };
961 : }
962 :
963 : inline iterator_range<def_iterator>
964 : function_info::mem_defs () const
965 : {
966 : return { m_defs[0], nullptr };
967 : }
968 :
969 : inline iterator_range<def_iterator>
970 : function_info::reg_defs (unsigned int regno) const
971 : {
972 : return { m_defs[regno + 1], nullptr };
973 : }
974 :
975 : inline bool
976 100229360 : function_info::is_single_dominating_def (const set_info *set) const
977 : {
978 100229360 : return (set->is_first_def ()
979 83291101 : && set->is_last_def ()
980 159589703 : && (!HARD_REGISTER_NUM_P (set->regno ())
981 4893436 : || !TEST_HARD_REG_BIT (m_clobbered_by_calls, set->regno ())));
982 : }
983 :
984 : inline set_info *
985 60779937 : function_info::single_dominating_def (unsigned int regno) const
986 : {
987 60779937 : if (set_info *set = safe_dyn_cast<set_info *> (m_defs[regno + 1]))
988 58278087 : if (is_single_dominating_def (set))
989 34570067 : return set;
990 : return nullptr;
991 : }
992 :
993 : template<typename IgnorePredicates>
994 : bool
995 2510186 : function_info::add_regno_clobber (obstack_watermark &watermark,
996 : insn_change &change, unsigned int regno,
997 : IgnorePredicates ignore)
998 : {
999 : // Check whether CHANGE already clobbers REGNO.
1000 2510186 : if (find_access (change.new_defs, regno))
1001 : return true;
1002 :
1003 : // Get the closest position to INSN at which the new instruction
1004 : // could be placed.
1005 1964368 : insn_info *insn = change.move_range.clamp_insn_to_range (change.insn ());
1006 1964368 : def_array new_defs = insert_temp_clobber (watermark, insn, regno,
1007 : change.new_defs);
1008 2939 : if (!new_defs.is_valid ())
1009 : return false;
1010 :
1011 : // Find a definition at or neighboring INSN.
1012 1964368 : insn_range_info move_range = change.move_range;
1013 1964368 : if (!restrict_movement_for_dead_range (move_range, regno, insn, ignore))
1014 : return false;
1015 :
1016 1961429 : change.new_defs = new_defs;
1017 1961429 : change.move_range = move_range;
1018 1961429 : return true;
1019 : }
1020 :
1021 : template<typename T, typename... Ts>
1022 : inline T *
1023 0 : function_info::change_alloc (obstack_watermark &wm, Ts... args)
1024 : {
1025 : static_assert (std::is_trivially_destructible<T>::value,
1026 : "destructor won't be called");
1027 : static_assert (alignof (T) <= obstack_alignment,
1028 : "too much alignment required");
1029 0 : void *addr = XOBNEW (wm, T);
1030 0 : return new (addr) T (std::forward<Ts> (args)...);
1031 : }
1032 :
1033 : inline
1034 7669218 : ignore_changing_insns::
1035 7669218 : ignore_changing_insns (array_slice<insn_change *const> changes)
1036 7669218 : : m_changes (changes)
1037 : {
1038 : }
1039 :
1040 : inline bool
1041 38001756 : ignore_changing_insns::should_ignore_insn (const insn_info *insn)
1042 : {
1043 101447549 : for (const insn_change *change : m_changes)
1044 72057735 : if (change->insn () == insn)
1045 : return true;
1046 : return false;
1047 : }
1048 :
1049 : }
|