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 79341270 : access_array_builder::reserve (unsigned int num_accesses)
31 : {
32 79341270 : obstack_make_room (m_obstack, num_accesses * sizeof (access_info *));
33 79341270 : }
34 :
35 : inline void
36 155456189 : access_array_builder::quick_push (access_info *access)
37 : {
38 131741591 : obstack_ptr_grow_fast (m_obstack, access);
39 24911202 : }
40 :
41 : inline array_slice<access_info *>
42 76829124 : access_array_builder::finish ()
43 : {
44 76829124 : unsigned num_accesses
45 76829124 : = obstack_object_size (m_obstack) / sizeof (access_info *);
46 76829124 : if (num_accesses == 0)
47 13632032 : return {};
48 :
49 63197092 : auto **base = static_cast<access_info **> (obstack_finish (m_obstack));
50 63197092 : keep ();
51 63197092 : return { base, num_accesses };
52 : }
53 :
54 : inline bool
55 146744713 : access_info::is_set_with_nondebug_insn_uses () const
56 : {
57 146744713 : return m_is_set_with_nondebug_insn_uses;
58 : }
59 :
60 : inline bool
61 1247827848 : use_info::is_in_debug_insn () const
62 : {
63 1247827848 : return m_insn_or_phi.is_first () && m_is_in_debug_insn_or_phi;
64 : }
65 :
66 : inline bb_info *
67 248808725 : use_info::bb () const
68 : {
69 147437441 : if (m_insn_or_phi.is_first ())
70 248808725 : return m_insn_or_phi.known_first ()->bb ();
71 4519831 : return m_insn_or_phi.known_second ()->bb ();
72 : }
73 :
74 : inline ebb_info *
75 46206854 : use_info::ebb () const
76 : {
77 214268072 : return bb ()->ebb ();
78 : }
79 :
80 : inline use_info *
81 1665473913 : use_info::prev_use () const
82 : {
83 2722243631 : return m_last_use_or_prev_use.second_or_null ();
84 : }
85 :
86 : inline use_info *
87 5411645377 : use_info::next_use () const
88 : {
89 8231154743 : 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 161378591 : use_info::next_nondebug_insn_use () const
106 : {
107 161378591 : if (m_is_last_nondebug_insn_use)
108 : return nullptr;
109 30836929 : return m_last_nondebug_insn_use_or_next_use.known_second ();
110 : }
111 :
112 : inline use_info *
113 46069998 : 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 46069998 : if (use_info *use = next_use ())
118 42782946 : if (use->is_in_any_insn ())
119 41901722 : 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 37733857 : 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 37733857 : if (use_info *use = prev_use ())
138 34862336 : 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 968304631 : use_info::last_use () const
147 : {
148 1403115345 : 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 531261369 : use_info::last_nondebug_insn_use () const
155 : {
156 1493439260 : return m_last_nondebug_insn_use_or_next_use.known_first ();
157 : }
158 :
159 : inline def_info *
160 141122036 : def_info::prev_def () const
161 : {
162 303361533 : return m_last_def_or_prev_def.second_or_null ();
163 : }
164 :
165 : inline def_info *
166 336912018 : def_info::next_def () const
167 : {
168 634975276 : return m_splay_root_or_next_def.second_or_null ();
169 : }
170 :
171 : inline bool
172 100068752 : def_info::is_first_def () const
173 : {
174 100068752 : return m_last_def_or_prev_def.is_first ();
175 : }
176 :
177 : inline bool
178 97527609 : def_info::is_last_def () const
179 : {
180 84726640 : return m_splay_root_or_next_def.is_first ();
181 : }
182 :
183 : inline bb_info *
184 763752554 : def_info::bb () const
185 : {
186 759184326 : return m_insn->bb ();
187 : }
188 :
189 : inline ebb_info *
190 1075219964 : def_info::ebb () const
191 : {
192 1083918128 : return m_insn->ebb ();
193 : }
194 :
195 : inline clobber_group *
196 95206859 : clobber_info::group () const
197 : {
198 95206859 : 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 110211178 : set_info::last_use () const
205 : {
206 110211178 : return m_first_use ? m_first_use->last_use () : nullptr;
207 : }
208 :
209 : inline use_info *
210 339877801 : set_info::first_nondebug_insn_use () const
211 : {
212 339877801 : if (m_is_set_with_nondebug_insn_uses)
213 278485368 : return m_first_use;
214 : return nullptr;
215 : }
216 :
217 : inline use_info *
218 88471936 : set_info::last_nondebug_insn_use () const
219 : {
220 88471936 : if (m_is_set_with_nondebug_insn_uses)
221 88471936 : 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 4204147 : set_info::first_any_insn_use () const
241 : {
242 4168276 : 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 137387873 : set_info::last_phi_use () const
249 : {
250 137387873 : if (m_first_use)
251 : {
252 129975902 : use_info *last = m_first_use->last_use ();
253 129975902 : if (last->is_in_phi ())
254 2309751 : return last;
255 : }
256 : return nullptr;
257 : }
258 :
259 : inline bool
260 20136205 : set_info::has_nondebug_uses () const
261 : {
262 99827009 : return has_nondebug_insn_uses () || has_phi_uses ();
263 : }
264 :
265 : inline bool
266 22047875 : set_info::has_nondebug_insn_uses () const
267 : {
268 22047875 : return m_is_set_with_nondebug_insn_uses;
269 : }
270 :
271 : inline bool
272 39820755 : set_info::has_phi_uses () const
273 : {
274 39820755 : return m_first_use && m_first_use->last_use ()->is_in_phi ();
275 : }
276 :
277 : inline use_info *
278 33680249 : set_info::single_nondebug_use () const
279 : {
280 33680249 : if (!has_phi_uses ())
281 31768579 : return single_nondebug_insn_use ();
282 1911670 : if (!has_nondebug_insn_uses ())
283 0 : return single_phi_use ();
284 : return nullptr;
285 : }
286 :
287 : inline use_info *
288 106526869 : set_info::single_nondebug_insn_use () const
289 : {
290 106526869 : use_info *first = first_nondebug_insn_use ();
291 95365002 : if (first && !first->next_nondebug_insn_use ())
292 69586691 : 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 138250774 : set_info::nondebug_insn_uses () const
333 : {
334 338013875 : 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 4204147 : set_info::all_insn_uses () const
351 : {
352 45869377 : return { first_any_insn_use (), nullptr };
353 : }
354 :
355 : inline iterator_range<phi_use_iterator>
356 133582174 : set_info::phi_uses () const
357 : {
358 267164348 : return { last_phi_use (), nullptr };
359 : }
360 :
361 : inline use_array
362 163862529 : phi_info::inputs () const
363 : {
364 163862529 : if (m_num_inputs == 1)
365 129102060 : return use_array (&m_single_input, 1);
366 34760469 : return use_array (m_inputs, m_num_inputs);
367 : }
368 :
369 : inline use_info *
370 134153656 : phi_info::input_use (unsigned int i) const
371 : {
372 134153656 : if (m_num_inputs == 1)
373 44682421 : return as_a<use_info *> (m_single_input);
374 89471235 : return as_a<use_info *> (m_inputs[i]);
375 : }
376 :
377 : inline set_info *
378 44682421 : phi_info::input_value (unsigned int i) const
379 : {
380 44682421 : return input_use (i)->def ();
381 : }
382 :
383 : inline def_info *
384 57520609 : def_node::first_def () const
385 : {
386 : // This should get optimized into an AND with -2.
387 53770309 : if (m_clobber_or_set.is_first ())
388 : return m_clobber_or_set.known_first ();
389 41199603 : return m_clobber_or_set.known_second ();
390 : }
391 :
392 : inline clobber_info *
393 13726744 : clobber_group::first_clobber () const
394 : {
395 13726744 : 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 3933179 : def_mux::first_def () const
406 : {
407 3849289 : if (is_first ())
408 : return known_first ();
409 3923425 : return known_second ()->first_def ();
410 : }
411 :
412 : inline def_info *
413 4822691 : def_mux::last_def () const
414 : {
415 4822691 : if (is_first ())
416 : return known_first ();
417 :
418 3530324 : def_node *node = known_second ();
419 3530324 : if (auto *clobber = ::dyn_cast<clobber_group *> (node))
420 3104558 : return clobber->last_clobber ();
421 :
422 425766 : return node->first_def ();
423 : }
424 :
425 : inline set_info *
426 1204618 : def_mux::set () const
427 : {
428 1204618 : if (is_first ())
429 4547 : return ::safe_dyn_cast<set_info *> (known_first ());
430 1342220 : return ::dyn_cast<set_info *> (known_second ()->first_def ());
431 : }
432 :
433 : inline def_info *
434 2158002 : def_lookup::last_def_of_prev_group () const
435 : {
436 2158002 : if (!mux)
437 : return nullptr;
438 :
439 2157280 : if (comparison > 0)
440 723969 : return mux.last_def ();
441 :
442 2861744 : return mux.first_def ()->prev_def ();
443 : }
444 :
445 : inline def_info *
446 2157956 : def_lookup::first_def_of_next_group () const
447 : {
448 2157956 : if (!mux)
449 : return nullptr;
450 :
451 2157234 : if (comparison < 0)
452 375349 : return mux.first_def ();
453 :
454 1781885 : return mux.last_def ()->next_def ();
455 : }
456 :
457 : inline set_info *
458 2317559 : def_lookup::matching_set () const
459 : {
460 2317559 : if (comparison == 0)
461 1204618 : 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 1972812 : def_lookup::matching_set_or_first_def_of_next_group () const
475 : {
476 1972812 : if (set_info *set = matching_set ())
477 : return set;
478 1972766 : 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 95100158 : use_lookup::matching_use () const
495 : {
496 95100158 : 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 25199566 : inline insn_note::insn_note (insn_note_kind kind)
512 25199566 : : m_next_note (nullptr),
513 25199566 : m_kind (kind),
514 25199566 : m_data8 (0),
515 25199566 : m_data16 (0),
516 : m_data32 (0)
517 : {
518 : }
519 :
520 : template<typename T>
521 : inline T
522 1710 : insn_note::as_a ()
523 : {
524 : using deref_type = decltype (*std::declval<T> ());
525 : using derived = typename std::remove_reference<deref_type>::type;
526 1710 : gcc_checking_assert (m_kind == derived::kind);
527 1710 : return static_cast<T> (this);
528 : }
529 :
530 : template<typename T>
531 : inline T
532 1312 : insn_note::dyn_cast ()
533 : {
534 : using deref_type = decltype (*std::declval<T> ());
535 : using derived = typename std::remove_reference<deref_type>::type;
536 1312 : if (m_kind == derived::kind)
537 : return static_cast<T> (this);
538 : return nullptr;
539 : }
540 :
541 : inline bool
542 1088492224 : insn_info::operator< (const insn_info &other) const
543 : {
544 1088492224 : if (this == &other)
545 : return false;
546 :
547 797026906 : if (LIKELY (m_point != other.m_point))
548 797026573 : return m_point < other.m_point;
549 :
550 333 : return slow_compare_with (other) < 0;
551 : }
552 :
553 : inline bool
554 117741867 : insn_info::operator> (const insn_info &other) const
555 : {
556 117239400 : return other < *this;
557 : }
558 :
559 : inline bool
560 315907680 : insn_info::operator<= (const insn_info &other) const
561 : {
562 315907680 : return !(other < *this);
563 : }
564 :
565 : inline bool
566 50411904 : insn_info::operator>= (const insn_info &other) const
567 : {
568 50411904 : return !(*this < other);
569 : }
570 :
571 : inline int
572 978398976 : insn_info::compare_with (const insn_info *other) const
573 : {
574 978398976 : if (this == other)
575 : return 0;
576 :
577 952265848 : if (LIKELY (m_point != other->m_point))
578 : // Assume that points remain in [0, INT_MAX].
579 952265326 : return m_point - other->m_point;
580 :
581 522 : return slow_compare_with (*other);
582 : }
583 :
584 : inline insn_info *
585 281792711 : insn_info::prev_nondebug_insn () const
586 : {
587 281792711 : gcc_checking_assert (!is_debug_insn ());
588 281792711 : return m_prev_sametype_or_last_debug_insn.known_first ();
589 : }
590 :
591 : inline insn_info *
592 352288248 : insn_info::next_nondebug_insn () const
593 : {
594 352288248 : gcc_checking_assert (!is_debug_insn ());
595 352288248 : const insn_info *from = this;
596 352288248 : if (insn_info *first_debug = m_next_nondebug_or_debug_insn.second_or_null ())
597 27943427 : from = first_debug->last_debug_insn ();
598 352288248 : return from->m_next_nondebug_or_debug_insn.known_first ();
599 : }
600 :
601 : inline insn_info *
602 2237898 : insn_info::prev_any_insn () const
603 : {
604 2237898 : 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 2237898 : auto *prev = m_prev_sametype_or_last_debug_insn.known_first ();
611 2237898 : if (prev)
612 : {
613 4475796 : auto *next = prev->next_any_insn ();
614 2237898 : 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 115754 : return next->m_prev_sametype_or_last_debug_insn.known_second ();
619 : }
620 : return prev;
621 : }
622 :
623 : inline insn_info *
624 1412557523 : insn_info::next_any_insn () const
625 : {
626 : // This should get optimized into an AND with -2.
627 1412557523 : if (m_next_nondebug_or_debug_insn.is_first ())
628 : return m_next_nondebug_or_debug_insn.known_first ();
629 385750617 : 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 16601077 : insn_info::is_bb_head () const
640 : {
641 16601077 : 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 1089846446 : insn_info::ebb () const
652 : {
653 1057976920 : return m_bb->ebb ();
654 : }
655 :
656 : inline int
657 8450 : insn_info::uid () const
658 : {
659 8450 : return m_cost_or_uid < 0 ? m_cost_or_uid : INSN_UID (m_rtl);
660 : }
661 :
662 : inline use_array
663 504090638 : insn_info::uses () const
664 : {
665 409079182 : 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 329989253 : insn_info::defs () const
676 : {
677 291790911 : return def_array (m_accesses, m_num_defs);
678 : }
679 :
680 : inline unsigned int
681 27955778 : insn_info::cost () const
682 : {
683 27955778 : if (m_cost_or_uid < 0)
684 : return 0;
685 27955778 : if (m_cost_or_uid == UNKNOWN_COST)
686 14347543 : calculate_cost ();
687 27955778 : return m_cost_or_uid;
688 : }
689 :
690 : template<typename T>
691 : inline const T *
692 2186816 : 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 2186816 : 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 27961964 : insn_info::last_debug_insn () const
707 : {
708 27961964 : return m_prev_sametype_or_last_debug_insn.known_second ();
709 : }
710 :
711 274785456 : 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 2475279 : insn_range_info::clamp_insn_to_range (insn_info *insn) const
742 : {
743 2475279 : if (*first > *insn)
744 0 : return first;
745 2475279 : if (*last < *insn)
746 23427 : 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 52564523 : 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 52564523 : return (resource.is_reg ()
810 52564523 : && 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 91726896 : ebb_info::next_ebb () const
823 : {
824 91726896 : if (bb_info *next_bb = m_last_bb->next_bb ())
825 79883844 : return next_bb->ebb ();
826 : return nullptr;
827 : }
828 :
829 : inline iterator_range<phi_iterator>
830 82791675 : ebb_info::phis () const
831 : {
832 82791675 : return { m_first_phi, nullptr };
833 : }
834 :
835 : inline iterator_range<bb_iterator>
836 34022887 : ebb_info::bbs () const
837 : {
838 34022887 : 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 4292278 : ebb_info::insn_range () const
873 : {
874 4292278 : return { m_phi_insn, m_last_bb->end_insn () };
875 : }
876 :
877 : inline void
878 14710785 : ebb_info::set_first_call_clobbers (ebb_call_clobbers_info *call_clobbers)
879 : {
880 14710785 : m_first_call_clobbers = call_clobbers;
881 14710785 : }
882 :
883 : inline ebb_call_clobbers_info *
884 39908582 : ebb_info::first_call_clobbers () const
885 : {
886 39908582 : return m_first_call_clobbers;
887 : }
888 :
889 : inline iterator_range<ebb_call_clobbers_iterator>
890 79828476 : ebb_info::call_clobbers () const
891 : {
892 79828476 : return { m_first_call_clobbers, nullptr };
893 : }
894 :
895 71637314 : inline insn_change::insn_change (insn_info *insn)
896 71637314 : : m_insn (insn),
897 71637314 : new_defs (insn->defs ()),
898 71637314 : new_uses (insn->uses ()),
899 71637314 : move_range (insn),
900 71637314 : new_cost (UNKNOWN_COST),
901 71637314 : m_is_deletion (false)
902 : {
903 : }
904 :
905 25120916 : inline insn_change::insn_change (insn_info *insn, delete_action)
906 25120916 : : m_insn (insn),
907 25120916 : new_defs (),
908 25120916 : new_uses (),
909 25120916 : move_range (insn),
910 25120916 : new_cost (0),
911 25120916 : 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 11843052 : function_info::ebbs () const
929 : {
930 11843052 : 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 3841230 : function_info::nondebug_insns () const
953 : {
954 3841230 : 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 100068752 : function_info::is_single_dominating_def (const set_info *set) const
977 : {
978 100068752 : return (set->is_first_def ()
979 83134495 : && set->is_last_def ()
980 159336445 : && (!HARD_REGISTER_NUM_P (set->regno ())
981 4855342 : || !TEST_HARD_REG_BIT (m_clobbered_by_calls, set->regno ())));
982 : }
983 :
984 : inline set_info *
985 60751651 : function_info::single_dominating_def (unsigned int regno) const
986 : {
987 60751651 : if (set_info *set = safe_dyn_cast<set_info *> (m_defs[regno + 1]))
988 58224274 : if (is_single_dominating_def (set))
989 34588792 : return set;
990 : return nullptr;
991 : }
992 :
993 : template<typename IgnorePredicates>
994 : bool
995 2527791 : 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 2527791 : 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 1972812 : insn_info *insn = change.move_range.clamp_insn_to_range (change.insn ());
1006 1972812 : 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 1972812 : insn_range_info move_range = change.move_range;
1013 1972812 : if (!restrict_movement_for_dead_range (move_range, regno, insn, ignore))
1014 : return false;
1015 :
1016 1969510 : change.new_defs = new_defs;
1017 1969510 : change.move_range = move_range;
1018 1969510 : 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 7706682 : ignore_changing_insns::
1035 7706682 : ignore_changing_insns (array_slice<insn_change *const> changes)
1036 7706682 : : m_changes (changes)
1037 : {
1038 : }
1039 :
1040 : inline bool
1041 38204840 : ignore_changing_insns::should_ignore_insn (const insn_info *insn)
1042 : {
1043 101927880 : for (const insn_change *change : m_changes)
1044 72418784 : if (change->insn () == insn)
1045 : return true;
1046 : return false;
1047 : }
1048 :
1049 : }
|