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 79377845 : access_array_builder::reserve (unsigned int num_accesses)
31 : {
32 79377845 : obstack_make_room (m_obstack, num_accesses * sizeof (access_info *));
33 79377845 : }
34 :
35 : inline void
36 155491696 : access_array_builder::quick_push (access_info *access)
37 : {
38 131753536 : obstack_ptr_grow_fast (m_obstack, access);
39 24944371 : }
40 :
41 : inline array_slice<access_info *>
42 76864825 : access_array_builder::finish ()
43 : {
44 76864825 : unsigned num_accesses
45 76864825 : = obstack_object_size (m_obstack) / sizeof (access_info *);
46 76864825 : if (num_accesses == 0)
47 13649735 : return {};
48 :
49 63215090 : auto **base = static_cast<access_info **> (obstack_finish (m_obstack));
50 63215090 : keep ();
51 63215090 : return { base, num_accesses };
52 : }
53 :
54 : inline bool
55 146626420 : access_info::is_set_with_nondebug_insn_uses () const
56 : {
57 146626420 : return m_is_set_with_nondebug_insn_uses;
58 : }
59 :
60 : inline bool
61 1262280991 : use_info::is_in_debug_insn () const
62 : {
63 1262280991 : return m_insn_or_phi.is_first () && m_is_in_debug_insn_or_phi;
64 : }
65 :
66 : inline bb_info *
67 248898264 : use_info::bb () const
68 : {
69 147591901 : if (m_insn_or_phi.is_first ())
70 248898264 : return m_insn_or_phi.known_first ()->bb ();
71 4542663 : return m_insn_or_phi.known_second ()->bb ();
72 : }
73 :
74 : inline ebb_info *
75 46165845 : use_info::ebb () const
76 : {
77 214201096 : return bb ()->ebb ();
78 : }
79 :
80 : inline use_info *
81 1664607303 : use_info::prev_use () const
82 : {
83 2721475936 : return m_last_use_or_prev_use.second_or_null ();
84 : }
85 :
86 : inline use_info *
87 5409190347 : use_info::next_use () const
88 : {
89 8243906116 : 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 161106762 : use_info::next_nondebug_insn_use () const
106 : {
107 161106762 : if (m_is_last_nondebug_insn_use)
108 : return nullptr;
109 30681820 : return m_last_nondebug_insn_use_or_next_use.known_second ();
110 : }
111 :
112 : inline use_info *
113 46677896 : 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 46677896 : if (use_info *use = next_use ())
118 43385022 : if (use->is_in_any_insn ())
119 42458381 : 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 37763328 : 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 37763328 : if (use_info *use = prev_use ())
138 34885660 : 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 965983577 : use_info::last_use () const
147 : {
148 1401749577 : 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 528418442 : use_info::last_nondebug_insn_use () const
155 : {
156 1490098651 : return m_last_nondebug_insn_use_or_next_use.known_first ();
157 : }
158 :
159 : inline def_info *
160 141005264 : def_info::prev_def () const
161 : {
162 303089787 : return m_last_def_or_prev_def.second_or_null ();
163 : }
164 :
165 : inline def_info *
166 335526026 : def_info::next_def () const
167 : {
168 633324514 : return m_splay_root_or_next_def.second_or_null ();
169 : }
170 :
171 : inline bool
172 100258389 : def_info::is_first_def () const
173 : {
174 100258389 : return m_last_def_or_prev_def.is_first ();
175 : }
176 :
177 : inline bool
178 97652114 : def_info::is_last_def () const
179 : {
180 84842667 : return m_splay_root_or_next_def.is_first ();
181 : }
182 :
183 : inline bb_info *
184 763801205 : def_info::bb () const
185 : {
186 759309702 : return m_insn->bb ();
187 : }
188 :
189 : inline ebb_info *
190 1073268351 : def_info::ebb () const
191 : {
192 1082013622 : return m_insn->ebb ();
193 : }
194 :
195 : inline clobber_group *
196 95088646 : clobber_info::group () const
197 : {
198 95088646 : if (!m_group || !m_group->has_been_superceded ())
199 : return m_group;
200 1600 : return const_cast<clobber_info *> (this)->recompute_group ();
201 : }
202 :
203 : inline use_info *
204 110040791 : set_info::last_use () const
205 : {
206 110040791 : return m_first_use ? m_first_use->last_use () : nullptr;
207 : }
208 :
209 : inline use_info *
210 336475380 : set_info::first_nondebug_insn_use () const
211 : {
212 336475380 : if (m_is_set_with_nondebug_insn_uses)
213 276211496 : return m_first_use;
214 : return nullptr;
215 : }
216 :
217 : inline use_info *
218 86834453 : set_info::last_nondebug_insn_use () const
219 : {
220 86834453 : if (m_is_set_with_nondebug_insn_uses)
221 86834453 : 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 4255552 : set_info::first_any_insn_use () const
241 : {
242 4219515 : 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 137249046 : set_info::last_phi_use () const
249 : {
250 137249046 : if (m_first_use)
251 : {
252 129832245 : use_info *last = m_first_use->last_use ();
253 129832245 : if (last->is_in_phi ())
254 2329272 : return last;
255 : }
256 : return nullptr;
257 : }
258 :
259 : inline bool
260 6525203 : set_info::has_nondebug_uses () const
261 : {
262 19540777 : return has_nondebug_insn_uses () || has_phi_uses ();
263 : }
264 :
265 : inline bool
266 8466340 : set_info::has_nondebug_insn_uses () const
267 : {
268 8466340 : return m_is_set_with_nondebug_insn_uses;
269 : }
270 :
271 : inline bool
272 33782346 : set_info::has_phi_uses () const
273 : {
274 33782346 : return m_first_use && m_first_use->last_use ()->is_in_phi ();
275 : }
276 :
277 : inline use_info *
278 33639784 : set_info::single_nondebug_use () const
279 : {
280 33639784 : if (!has_phi_uses ())
281 31698647 : return single_nondebug_insn_use ();
282 1941137 : if (!has_nondebug_insn_uses ())
283 0 : return single_phi_use ();
284 : return nullptr;
285 : }
286 :
287 : inline use_info *
288 106485242 : set_info::single_nondebug_insn_use () const
289 : {
290 106485242 : use_info *first = first_nondebug_insn_use ();
291 95337403 : if (first && !first->next_nondebug_insn_use ())
292 69609983 : 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 16067355 : set_info::all_uses () const
321 : {
322 16067355 : 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 138026043 : set_info::nondebug_insn_uses () const
333 : {
334 337304274 : 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 4255552 : set_info::all_insn_uses () const
351 : {
352 46530643 : return { first_any_insn_use (), nullptr };
353 : }
354 :
355 : inline iterator_range<phi_use_iterator>
356 133419527 : set_info::phi_uses () const
357 : {
358 266839054 : return { last_phi_use (), nullptr };
359 : }
360 :
361 : inline use_array
362 163651617 : phi_info::inputs () const
363 : {
364 163651617 : if (m_num_inputs == 1)
365 128764206 : return use_array (&m_single_input, 1);
366 34887411 : return use_array (m_inputs, m_num_inputs);
367 : }
368 :
369 : inline use_info *
370 133474467 : phi_info::input_use (unsigned int i) const
371 : {
372 133474467 : if (m_num_inputs == 1)
373 43717110 : return as_a<use_info *> (m_single_input);
374 89757357 : return as_a<use_info *> (m_inputs[i]);
375 : }
376 :
377 : inline set_info *
378 43717110 : phi_info::input_value (unsigned int i) const
379 : {
380 43717110 : return input_use (i)->def ();
381 : }
382 :
383 : inline def_info *
384 57571818 : def_node::first_def () const
385 : {
386 : // This should get optimized into an AND with -2.
387 53821600 : if (m_clobber_or_set.is_first ())
388 : return m_clobber_or_set.known_first ();
389 41253726 : return m_clobber_or_set.known_second ();
390 : }
391 :
392 : inline clobber_info *
393 13714327 : clobber_group::first_clobber () const
394 : {
395 13714327 : 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 3918920 : def_mux::first_def () const
406 : {
407 3834888 : if (is_first ())
408 : return known_first ();
409 3909174 : return known_second ()->first_def ();
410 : }
411 :
412 : inline def_info *
413 4810068 : def_mux::last_def () const
414 : {
415 4810068 : if (is_first ())
416 : return known_first ();
417 :
418 3510874 : def_node *node = known_second ();
419 3510874 : if (auto *clobber = ::dyn_cast<clobber_group *> (node))
420 3087952 : return clobber->last_clobber ();
421 :
422 422922 : return node->first_def ();
423 : }
424 :
425 : inline set_info *
426 1205558 : def_mux::set () const
427 : {
428 1205558 : if (is_first ())
429 4530 : return ::safe_dyn_cast<set_info *> (known_first ());
430 1342917 : return ::dyn_cast<set_info *> (known_second ()->first_def ());
431 : }
432 :
433 : inline def_info *
434 2151998 : def_lookup::last_def_of_prev_group () const
435 : {
436 2151998 : if (!mux)
437 : return nullptr;
438 :
439 2151276 : if (comparison > 0)
440 720356 : return mux.last_def ();
441 :
442 2856966 : return mux.first_def ()->prev_def ();
443 : }
444 :
445 : inline def_info *
446 2151957 : def_lookup::first_def_of_next_group () const
447 : {
448 2151957 : if (!mux)
449 : return nullptr;
450 :
451 2151235 : if (comparison < 0)
452 371746 : return mux.first_def ();
453 :
454 1779489 : return mux.last_def ()->next_def ();
455 : }
456 :
457 : inline set_info *
458 2310945 : def_lookup::matching_set () const
459 : {
460 2310945 : if (comparison == 0)
461 1205558 : 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 1966660 : def_lookup::matching_set_or_first_def_of_next_group () const
475 : {
476 1966660 : if (set_info *set = matching_set ())
477 : return set;
478 1966619 : 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 91964095 : use_lookup::matching_use () const
495 : {
496 91964095 : 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 25279933 : inline insn_note::insn_note (insn_note_kind kind)
512 25279933 : : m_next_note (nullptr),
513 25279933 : m_kind (kind),
514 25279933 : m_data8 (0),
515 25279933 : m_data16 (0),
516 : m_data32 (0)
517 : {
518 : }
519 :
520 : template<typename T>
521 : inline T
522 1726 : insn_note::as_a ()
523 : {
524 : using deref_type = decltype (*std::declval<T> ());
525 : using derived = typename std::remove_reference<deref_type>::type;
526 1726 : gcc_checking_assert (m_kind == derived::kind);
527 1726 : return static_cast<T> (this);
528 : }
529 :
530 : template<typename T>
531 : inline T
532 1290 : insn_note::dyn_cast ()
533 : {
534 : using deref_type = decltype (*std::declval<T> ());
535 : using derived = typename std::remove_reference<deref_type>::type;
536 1290 : if (m_kind == derived::kind)
537 : return static_cast<T> (this);
538 : return nullptr;
539 : }
540 :
541 : inline bool
542 1084723038 : insn_info::operator< (const insn_info &other) const
543 : {
544 1084723038 : if (this == &other)
545 : return false;
546 :
547 794107898 : if (LIKELY (m_point != other.m_point))
548 794107555 : return m_point < other.m_point;
549 :
550 343 : return slow_compare_with (other) < 0;
551 : }
552 :
553 : inline bool
554 117690390 : insn_info::operator> (const insn_info &other) const
555 : {
556 117188926 : return other < *this;
557 : }
558 :
559 : inline bool
560 313919833 : insn_info::operator<= (const insn_info &other) const
561 : {
562 313919833 : return !(other < *this);
563 : }
564 :
565 : inline bool
566 48797531 : insn_info::operator>= (const insn_info &other) const
567 : {
568 48797531 : return !(*this < other);
569 : }
570 :
571 : inline int
572 976700209 : insn_info::compare_with (const insn_info *other) const
573 : {
574 976700209 : if (this == other)
575 : return 0;
576 :
577 950632204 : if (LIKELY (m_point != other->m_point))
578 : // Assume that points remain in [0, INT_MAX].
579 950631684 : return m_point - other->m_point;
580 :
581 520 : return slow_compare_with (*other);
582 : }
583 :
584 : inline insn_info *
585 281678447 : insn_info::prev_nondebug_insn () const
586 : {
587 281678447 : gcc_checking_assert (!is_debug_insn ());
588 281678447 : return m_prev_sametype_or_last_debug_insn.known_first ();
589 : }
590 :
591 : inline insn_info *
592 352821597 : insn_info::next_nondebug_insn () const
593 : {
594 352821597 : gcc_checking_assert (!is_debug_insn ());
595 352821597 : const insn_info *from = this;
596 352821597 : if (insn_info *first_debug = m_next_nondebug_or_debug_insn.second_or_null ())
597 28113587 : from = first_debug->last_debug_insn ();
598 352821597 : return from->m_next_nondebug_or_debug_insn.known_first ();
599 : }
600 :
601 : inline insn_info *
602 2243875 : insn_info::prev_any_insn () const
603 : {
604 2243875 : 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 2243875 : auto *prev = m_prev_sametype_or_last_debug_insn.known_first ();
611 2243875 : if (prev)
612 : {
613 4487750 : auto *next = prev->next_any_insn ();
614 2243875 : 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 115232 : return next->m_prev_sametype_or_last_debug_insn.known_second ();
619 : }
620 : return prev;
621 : }
622 :
623 : inline insn_info *
624 1419586133 : insn_info::next_any_insn () const
625 : {
626 : // This should get optimized into an AND with -2.
627 1419586133 : if (m_next_nondebug_or_debug_insn.is_first ())
628 : return m_next_nondebug_or_debug_insn.known_first ();
629 389260363 : 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 16597002 : insn_info::is_bb_head () const
640 : {
641 16597002 : 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 1087877094 : insn_info::ebb () const
652 : {
653 1056078450 : return m_bb->ebb ();
654 : }
655 :
656 : inline int
657 8311 : insn_info::uid () const
658 : {
659 8311 : return m_cost_or_uid < 0 ? m_cost_or_uid : INSN_UID (m_rtl);
660 : }
661 :
662 : inline use_array
663 505021030 : insn_info::uses () const
664 : {
665 409991050 : 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 330231636 : insn_info::defs () const
676 : {
677 291974321 : return def_array (m_accesses, m_num_defs);
678 : }
679 :
680 : inline unsigned int
681 27970676 : insn_info::cost () const
682 : {
683 27970676 : if (m_cost_or_uid < 0)
684 : return 0;
685 27970676 : if (m_cost_or_uid == UNKNOWN_COST)
686 14352202 : calculate_cost ();
687 27970676 : return m_cost_or_uid;
688 : }
689 :
690 : template<typename T>
691 : inline const T *
692 2193153 : 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 2193153 : 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 28131747 : insn_info::last_debug_insn () const
707 : {
708 28131747 : return m_prev_sametype_or_last_debug_insn.known_second ();
709 : }
710 :
711 274521464 : 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 2468124 : insn_range_info::clamp_insn_to_range (insn_info *insn) const
742 : {
743 2468124 : if (*first > *insn)
744 0 : return first;
745 2468124 : if (*last < *insn)
746 23072 : 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 52550573 : 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 52550573 : return (resource.is_reg ()
810 52550573 : && 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 91954784 : ebb_info::next_ebb () const
823 : {
824 91954784 : if (bb_info *next_bb = m_last_bb->next_bb ())
825 80068860 : return next_bb->ebb ();
826 : return nullptr;
827 : }
828 :
829 : inline iterator_range<phi_iterator>
830 82995784 : ebb_info::phis () const
831 : {
832 82995784 : return { m_first_phi, nullptr };
833 : }
834 :
835 : inline iterator_range<bb_iterator>
836 2520 : ebb_info::bbs () const
837 : {
838 2520 : 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 4311433 : ebb_info::insn_range () const
873 : {
874 4311433 : return { m_phi_insn, m_last_bb->end_insn () };
875 : }
876 :
877 : inline void
878 14784682 : ebb_info::set_first_call_clobbers (ebb_call_clobbers_info *call_clobbers)
879 : {
880 14784682 : m_first_call_clobbers = call_clobbers;
881 14784682 : }
882 :
883 : inline ebb_call_clobbers_info *
884 40062865 : ebb_info::first_call_clobbers () const
885 : {
886 40062865 : return m_first_call_clobbers;
887 : }
888 :
889 : inline iterator_range<ebb_call_clobbers_iterator>
890 79752813 : ebb_info::call_clobbers () const
891 : {
892 79752813 : return { m_first_call_clobbers, nullptr };
893 : }
894 :
895 71646005 : inline insn_change::insn_change (insn_info *insn)
896 71646005 : : m_insn (insn),
897 71646005 : new_defs (insn->defs ()),
898 71646005 : new_uses (insn->uses ()),
899 71646005 : move_range (insn),
900 71646005 : new_cost (UNKNOWN_COST),
901 71646005 : m_is_deletion (false)
902 : {
903 : }
904 :
905 25109127 : inline insn_change::insn_change (insn_info *insn, delete_action)
906 25109127 : : m_insn (insn),
907 25109127 : new_defs (),
908 25109127 : new_uses (),
909 25109127 : move_range (insn),
910 25109127 : new_cost (0),
911 25109127 : 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 11885924 : function_info::ebbs () const
929 : {
930 11885924 : 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 3855746 : function_info::nondebug_insns () const
953 : {
954 3855746 : 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 100258389 : function_info::is_single_dominating_def (const set_info *set) const
977 : {
978 100258389 : return (set->is_first_def ()
979 83277051 : && set->is_last_def ()
980 159567808 : && (!HARD_REGISTER_NUM_P (set->regno ())
981 4853167 : || !TEST_HARD_REG_BIT (m_clobbered_by_calls, set->regno ())));
982 : }
983 :
984 : inline set_info *
985 60840492 : function_info::single_dominating_def (unsigned int regno) const
986 : {
987 60840492 : if (set_info *set = safe_dyn_cast<set_info *> (m_defs[regno + 1]))
988 58319617 : if (is_single_dominating_def (set))
989 34584956 : return set;
990 : return nullptr;
991 : }
992 :
993 : template<typename IgnorePredicates>
994 : bool
995 2519849 : 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 2519849 : 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 1966660 : insn_info *insn = change.move_range.clamp_insn_to_range (change.insn ());
1006 1966660 : def_array new_defs = insert_temp_clobber (watermark, insn, regno,
1007 : change.new_defs);
1008 3302 : if (!new_defs.is_valid ())
1009 : return false;
1010 :
1011 : // Find a definition at or neighboring INSN.
1012 1966660 : insn_range_info move_range = change.move_range;
1013 1966660 : if (!restrict_movement_for_dead_range (move_range, regno, insn, ignore))
1014 : return false;
1015 :
1016 1963358 : change.new_defs = new_defs;
1017 1963358 : change.move_range = move_range;
1018 1963358 : 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 7742009 : ignore_changing_insns::
1035 7742009 : ignore_changing_insns (array_slice<insn_change *const> changes)
1036 7742009 : : m_changes (changes)
1037 : {
1038 : }
1039 :
1040 : inline bool
1041 38385108 : ignore_changing_insns::should_ignore_insn (const insn_info *insn)
1042 : {
1043 102429816 : for (const insn_change *change : m_changes)
1044 72767946 : if (change->insn () == insn)
1045 : return true;
1046 : return false;
1047 : }
1048 :
1049 : }
|