Branch data Line data Source code
1 : : // Implementation of public inline member functions for RTL SSA -*- C++ -*-
2 : : // Copyright (C) 2020-2025 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 : 79516054 : access_array_builder::reserve (unsigned int num_accesses)
31 : : {
32 : 79516054 : obstack_make_room (m_obstack, num_accesses * sizeof (access_info *));
33 : 79516054 : }
34 : :
35 : : inline void
36 : 155483819 : access_array_builder::quick_push (access_info *access)
37 : : {
38 : 131613296 : obstack_ptr_grow_fast (m_obstack, access);
39 : 25160768 : }
40 : :
41 : : inline array_slice<access_info *>
42 : 77033863 : access_array_builder::finish ()
43 : : {
44 : 77033863 : unsigned num_accesses
45 : 77033863 : = obstack_object_size (m_obstack) / sizeof (access_info *);
46 : 77033863 : if (num_accesses == 0)
47 : 13669755 : return {};
48 : :
49 : 63364108 : auto **base = static_cast<access_info **> (obstack_finish (m_obstack));
50 : 63364108 : keep ();
51 : 63364108 : return { base, num_accesses };
52 : : }
53 : :
54 : : inline bool
55 : 148426994 : access_info::is_set_with_nondebug_insn_uses () const
56 : : {
57 : 148426994 : return m_is_set_with_nondebug_insn_uses;
58 : : }
59 : :
60 : : inline bool
61 : 1260173068 : use_info::is_in_debug_insn () const
62 : : {
63 : 1260173068 : return m_insn_or_phi.is_first () && m_is_in_debug_insn_or_phi;
64 : : }
65 : :
66 : : inline bb_info *
67 : 248557316 : use_info::bb () const
68 : : {
69 : 146585824 : if (m_insn_or_phi.is_first ())
70 : 248557316 : return m_insn_or_phi.known_first ()->bb ();
71 : 4408851 : return m_insn_or_phi.known_second ()->bb ();
72 : : }
73 : :
74 : : inline ebb_info *
75 : 46315892 : use_info::ebb () const
76 : : {
77 : 214964126 : return bb ()->ebb ();
78 : : }
79 : :
80 : : inline use_info *
81 : 1671334254 : use_info::prev_use () const
82 : : {
83 : 2732900436 : return m_last_use_or_prev_use.second_or_null ();
84 : : }
85 : :
86 : : inline use_info *
87 : 5417289323 : use_info::next_use () const
88 : : {
89 : 8258770026 : 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 : 162377521 : use_info::next_nondebug_insn_use () const
106 : : {
107 : 162377521 : if (m_is_last_nondebug_insn_use)
108 : : return nullptr;
109 : 30405197 : return m_last_nondebug_insn_use_or_next_use.known_second ();
110 : : }
111 : :
112 : : inline use_info *
113 : 45099969 : 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 : 45099969 : if (use_info *use = next_use ())
118 : 41814437 : if (use->is_in_any_insn ())
119 : 40877613 : 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 : 39797255 : 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 : 39797255 : if (use_info *use = prev_use ())
138 : 36844884 : 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 : 971387883 : use_info::last_use () const
147 : : {
148 : 1407336169 : 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 : 527147782 : use_info::last_nondebug_insn_use () const
155 : : {
156 : 1491801550 : return m_last_nondebug_insn_use_or_next_use.known_first ();
157 : : }
158 : :
159 : : inline def_info *
160 : 142704296 : def_info::prev_def () const
161 : : {
162 : 307075861 : return m_last_def_or_prev_def.second_or_null ();
163 : : }
164 : :
165 : : inline def_info *
166 : 338448789 : def_info::next_def () const
167 : : {
168 : 638255049 : return m_splay_root_or_next_def.second_or_null ();
169 : : }
170 : :
171 : : inline bool
172 : 98254400 : def_info::is_first_def () const
173 : : {
174 : 98254400 : return m_last_def_or_prev_def.is_first ();
175 : : }
176 : :
177 : : inline bool
178 : 96426271 : def_info::is_last_def () const
179 : : {
180 : 84488938 : return m_splay_root_or_next_def.is_first ();
181 : : }
182 : :
183 : : inline bb_info *
184 : 772095289 : def_info::bb () const
185 : : {
186 : 767015040 : return m_insn->bb ();
187 : : }
188 : :
189 : : inline ebb_info *
190 : 1076190911 : def_info::ebb () const
191 : : {
192 : 1084471409 : return m_insn->ebb ();
193 : : }
194 : :
195 : : inline clobber_group *
196 : 95718684 : clobber_info::group () const
197 : : {
198 : 95718684 : if (!m_group || !m_group->has_been_superceded ())
199 : : return m_group;
200 : 1761 : return const_cast<clobber_info *> (this)->recompute_group ();
201 : : }
202 : :
203 : : inline use_info *
204 : 114551698 : set_info::last_use () const
205 : : {
206 : 114551698 : return m_first_use ? m_first_use->last_use () : nullptr;
207 : : }
208 : :
209 : : inline use_info *
210 : 339825221 : set_info::first_nondebug_insn_use () const
211 : : {
212 : 339825221 : if (m_is_set_with_nondebug_insn_uses)
213 : 278305757 : return m_first_use;
214 : : return nullptr;
215 : : }
216 : :
217 : : inline use_info *
218 : 86398180 : set_info::last_nondebug_insn_use () const
219 : : {
220 : 86398180 : if (m_is_set_with_nondebug_insn_uses)
221 : 86398180 : 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 : 4258434 : set_info::first_any_insn_use () const
241 : : {
242 : 4222356 : 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 : 138449987 : set_info::last_phi_use () const
249 : : {
250 : 138449987 : if (m_first_use)
251 : : {
252 : 130795543 : use_info *last = m_first_use->last_use ();
253 : 130795543 : if (last->is_in_phi ())
254 : 2296870 : return last;
255 : : }
256 : : return nullptr;
257 : : }
258 : :
259 : : inline bool
260 : 6520284 : set_info::has_nondebug_uses () const
261 : : {
262 : 19275840 : return has_nondebug_insn_uses () || has_phi_uses ();
263 : : }
264 : :
265 : : inline bool
266 : 8438305 : set_info::has_nondebug_insn_uses () const
267 : : {
268 : 8438305 : return m_is_set_with_nondebug_insn_uses;
269 : : }
270 : :
271 : : inline bool
272 : 33849470 : set_info::has_phi_uses () const
273 : : {
274 : 33849470 : return m_first_use && m_first_use->last_use ()->is_in_phi ();
275 : : }
276 : :
277 : : inline use_info *
278 : 33703288 : set_info::single_nondebug_use () const
279 : : {
280 : 33703288 : if (!has_phi_uses ())
281 : 31785267 : return single_nondebug_insn_use ();
282 : 1918021 : if (!has_nondebug_insn_uses ())
283 : 0 : return single_phi_use ();
284 : : return nullptr;
285 : : }
286 : :
287 : : inline use_info *
288 : 107463653 : set_info::single_nondebug_insn_use () const
289 : : {
290 : 107463653 : use_info *first = first_nondebug_insn_use ();
291 : 96434317 : if (first && !first->next_nondebug_insn_use ())
292 : 71099180 : 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 : 16269621 : set_info::all_uses () const
321 : : {
322 : 16269621 : 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 : 139665488 : set_info::nondebug_insn_uses () const
333 : : {
334 : 340784772 : 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 : 4258434 : set_info::all_insn_uses () const
351 : : {
352 : 45148686 : return { first_any_insn_use (), nullptr };
353 : : }
354 : :
355 : : inline iterator_range<phi_use_iterator>
356 : 134662657 : set_info::phi_uses () const
357 : : {
358 : 269325314 : return { last_phi_use (), nullptr };
359 : : }
360 : :
361 : : inline use_array
362 : 164791371 : phi_info::inputs () const
363 : : {
364 : 164791371 : if (m_num_inputs == 1)
365 : 129326693 : return use_array (&m_single_input, 1);
366 : 35464678 : return use_array (m_inputs, m_num_inputs);
367 : : }
368 : :
369 : : inline use_info *
370 : 136155773 : phi_info::input_use (unsigned int i) const
371 : : {
372 : 136155773 : if (m_num_inputs == 1)
373 : 43775094 : return as_a<use_info *> (m_single_input);
374 : 92380679 : return as_a<use_info *> (m_inputs[i]);
375 : : }
376 : :
377 : : inline set_info *
378 : 43775094 : phi_info::input_value (unsigned int i) const
379 : : {
380 : 43775094 : return input_use (i)->def ();
381 : : }
382 : :
383 : : inline def_info *
384 : 56567982 : def_node::first_def () const
385 : : {
386 : : // This should get optimized into an AND with -2.
387 : 52913034 : if (m_clobber_or_set.is_first ())
388 : : return m_clobber_or_set.known_first ();
389 : 40087187 : return m_clobber_or_set.known_second ();
390 : : }
391 : :
392 : : inline clobber_info *
393 : 13938591 : clobber_group::first_clobber () const
394 : : {
395 : 13938591 : 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 : 4036845 : def_mux::first_def () const
406 : : {
407 : 3956539 : if (is_first ())
408 : : return known_first ();
409 : 4028139 : return known_second ()->first_def ();
410 : : }
411 : :
412 : : inline def_info *
413 : 4922259 : def_mux::last_def () const
414 : : {
415 : 4922259 : if (is_first ())
416 : : return known_first ();
417 : :
418 : 3637716 : def_node *node = known_second ();
419 : 3637716 : if (auto *clobber = ::dyn_cast<clobber_group *> (node))
420 : 3221642 : return clobber->last_clobber ();
421 : :
422 : 416074 : return node->first_def ();
423 : : }
424 : :
425 : : inline set_info *
426 : 1259760 : def_mux::set () const
427 : : {
428 : 1259760 : if (is_first ())
429 : 4011 : return ::safe_dyn_cast<set_info *> (known_first ());
430 : 1390641 : return ::dyn_cast<set_info *> (known_second ()->first_def ());
431 : : }
432 : :
433 : : inline def_info *
434 : 2212909 : def_lookup::last_def_of_prev_group () const
435 : : {
436 : 2212909 : if (!mux)
437 : : return nullptr;
438 : :
439 : 2212199 : if (comparison > 0)
440 : 718927 : return mux.last_def ();
441 : :
442 : 2982190 : return mux.first_def ()->prev_def ();
443 : : }
444 : :
445 : : inline def_info *
446 : 2212833 : def_lookup::first_def_of_next_group () const
447 : : {
448 : 2212833 : if (!mux)
449 : : return nullptr;
450 : :
451 : 2212123 : if (comparison < 0)
452 : 372345 : return mux.first_def ();
453 : :
454 : 1839778 : return mux.last_def ()->next_def ();
455 : : }
456 : :
457 : : inline set_info *
458 : 2364264 : def_lookup::matching_set () const
459 : : {
460 : 2364264 : if (comparison == 0)
461 : 1259760 : 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 : 2031145 : def_lookup::matching_set_or_first_def_of_next_group () const
475 : : {
476 : 2031145 : if (set_info *set = matching_set ())
477 : : return set;
478 : 2031069 : 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 : 92696080 : use_lookup::matching_use () const
495 : : {
496 : 92696080 : 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 : 25698248 : inline insn_note::insn_note (insn_note_kind kind)
512 : 25698248 : : m_next_note (nullptr),
513 : 25698248 : m_kind (kind),
514 : 25698248 : m_data8 (0),
515 : 25698248 : m_data16 (0),
516 : : m_data32 (0)
517 : : {
518 : : }
519 : :
520 : : template<typename T>
521 : : inline T
522 : 2004 : insn_note::as_a ()
523 : : {
524 : : using deref_type = decltype (*std::declval<T> ());
525 : : using derived = typename std::remove_reference<deref_type>::type;
526 : 2004 : gcc_checking_assert (m_kind == derived::kind);
527 : 2004 : return static_cast<T> (this);
528 : : }
529 : :
530 : : template<typename T>
531 : : inline T
532 : 1621 : insn_note::dyn_cast ()
533 : : {
534 : : using deref_type = decltype (*std::declval<T> ());
535 : : using derived = typename std::remove_reference<deref_type>::type;
536 : 1621 : if (m_kind == derived::kind)
537 : : return static_cast<T> (this);
538 : : return nullptr;
539 : : }
540 : :
541 : : inline bool
542 : 1088254612 : insn_info::operator< (const insn_info &other) const
543 : : {
544 : 1088254612 : if (this == &other)
545 : : return false;
546 : :
547 : 796862476 : if (LIKELY (m_point != other.m_point))
548 : 796862025 : return m_point < other.m_point;
549 : :
550 : 451 : return slow_compare_with (other) < 0;
551 : : }
552 : :
553 : : inline bool
554 : 118603250 : insn_info::operator> (const insn_info &other) const
555 : : {
556 : 118112591 : return other < *this;
557 : : }
558 : :
559 : : inline bool
560 : 314450838 : insn_info::operator<= (const insn_info &other) const
561 : : {
562 : 314450838 : return !(other < *this);
563 : : }
564 : :
565 : : inline bool
566 : 47821457 : insn_info::operator>= (const insn_info &other) const
567 : : {
568 : 47821457 : return !(*this < other);
569 : : }
570 : :
571 : : inline int
572 : 972486694 : insn_info::compare_with (const insn_info *other) const
573 : : {
574 : 972486694 : if (this == other)
575 : : return 0;
576 : :
577 : 945758646 : if (LIKELY (m_point != other->m_point))
578 : : // Assume that points remain in [0, INT_MAX].
579 : 945758095 : return m_point - other->m_point;
580 : :
581 : 551 : return slow_compare_with (*other);
582 : : }
583 : :
584 : : inline insn_info *
585 : 284871998 : insn_info::prev_nondebug_insn () const
586 : : {
587 : 284871998 : gcc_checking_assert (!is_debug_insn ());
588 : 284871998 : return m_prev_sametype_or_last_debug_insn.known_first ();
589 : : }
590 : :
591 : : inline insn_info *
592 : 356962804 : insn_info::next_nondebug_insn () const
593 : : {
594 : 356962804 : gcc_checking_assert (!is_debug_insn ());
595 : 356962804 : const insn_info *from = this;
596 : 356962804 : if (insn_info *first_debug = m_next_nondebug_or_debug_insn.second_or_null ())
597 : 29307797 : from = first_debug->last_debug_insn ();
598 : 356962804 : return from->m_next_nondebug_or_debug_insn.known_first ();
599 : : }
600 : :
601 : : inline insn_info *
602 : 2261066 : insn_info::prev_any_insn () const
603 : : {
604 : 2261066 : 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 : 2261066 : auto *prev = m_prev_sametype_or_last_debug_insn.known_first ();
611 : 2261066 : if (prev)
612 : : {
613 : 4522132 : auto *next = prev->next_any_insn ();
614 : 2261066 : 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 : 117560 : return next->m_prev_sametype_or_last_debug_insn.known_second ();
619 : : }
620 : : return prev;
621 : : }
622 : :
623 : : inline insn_info *
624 : 1437063730 : insn_info::next_any_insn () const
625 : : {
626 : : // This should get optimized into an AND with -2.
627 : 1437063730 : if (m_next_nondebug_or_debug_insn.is_first ())
628 : : return m_next_nondebug_or_debug_insn.known_first ();
629 : 394666142 : 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 : 16678968 : insn_info::is_bb_head () const
640 : : {
641 : 16678968 : 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 : 1090962955 : insn_info::ebb () const
652 : : {
653 : 1058862416 : return m_bb->ebb ();
654 : : }
655 : :
656 : : inline int
657 : 9489 : insn_info::uid () const
658 : : {
659 : 9489 : return m_cost_or_uid < 0 ? m_cost_or_uid : INSN_UID (m_rtl);
660 : : }
661 : :
662 : : inline use_array
663 : 508106946 : insn_info::uses () const
664 : : {
665 : 413033909 : 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 : 332034377 : insn_info::defs () const
676 : : {
677 : 293687452 : return def_array (m_accesses, m_num_defs);
678 : : }
679 : :
680 : : inline unsigned int
681 : 27945081 : insn_info::cost () const
682 : : {
683 : 27945081 : if (m_cost_or_uid < 0)
684 : : return 0;
685 : 27945081 : if (m_cost_or_uid == UNKNOWN_COST)
686 : 14338928 : calculate_cost ();
687 : 27945081 : return m_cost_or_uid;
688 : : }
689 : :
690 : : template<typename T>
691 : : inline const T *
692 : 2210470 : 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 : 2210470 : 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 : 29329187 : insn_info::last_debug_insn () const
707 : : {
708 : 29329187 : return m_prev_sametype_or_last_debug_insn.known_second ();
709 : : }
710 : :
711 : 276410628 : 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 : 2521804 : insn_range_info::clamp_insn_to_range (insn_info *insn) const
742 : : {
743 : 2521804 : if (*first > *insn)
744 : 0 : return first;
745 : 2521804 : if (*last < *insn)
746 : 22931 : 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 : 53777382 : 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 : 53777382 : return (resource.is_reg ()
810 : 53777382 : && 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 : 93037456 : ebb_info::next_ebb () const
823 : : {
824 : 93037456 : if (bb_info *next_bb = m_last_bb->next_bb ())
825 : 81129476 : return next_bb->ebb ();
826 : : return nullptr;
827 : : }
828 : :
829 : : inline iterator_range<phi_iterator>
830 : 83910160 : ebb_info::phis () const
831 : : {
832 : 83910160 : return { m_first_phi, nullptr };
833 : : }
834 : :
835 : : inline iterator_range<bb_iterator>
836 : 2007 : ebb_info::bbs () const
837 : : {
838 : 2007 : 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 : 4315954 : ebb_info::insn_range () const
873 : : {
874 : 4315954 : return { m_phi_insn, m_last_bb->end_insn () };
875 : : }
876 : :
877 : : inline void
878 : 15029459 : ebb_info::set_first_call_clobbers (ebb_call_clobbers_info *call_clobbers)
879 : : {
880 : 15029459 : m_first_call_clobbers = call_clobbers;
881 : 15029459 : }
882 : :
883 : : inline ebb_call_clobbers_info *
884 : 40725613 : ebb_info::first_call_clobbers () const
885 : : {
886 : 40725613 : return m_first_call_clobbers;
887 : : }
888 : :
889 : : inline iterator_range<ebb_call_clobbers_iterator>
890 : 81028572 : ebb_info::call_clobbers () const
891 : : {
892 : 81028572 : return { m_first_call_clobbers, nullptr };
893 : : }
894 : :
895 : 71660067 : inline insn_change::insn_change (insn_info *insn)
896 : 71660067 : : m_insn (insn),
897 : 71660067 : new_defs (insn->defs ()),
898 : 71660067 : new_uses (insn->uses ()),
899 : 71660067 : move_range (insn),
900 : 71660067 : new_cost (UNKNOWN_COST),
901 : 71660067 : m_is_deletion (false)
902 : : {
903 : : }
904 : :
905 : 25395203 : inline insn_change::insn_change (insn_info *insn, delete_action)
906 : 25395203 : : m_insn (insn),
907 : 25395203 : new_defs (),
908 : 25395203 : new_uses (),
909 : 25395203 : move_range (insn),
910 : 25395203 : new_cost (0),
911 : 25395203 : 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 : 11907980 : function_info::ebbs () const
929 : : {
930 : 11907980 : 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 : 3864190 : function_info::nondebug_insns () const
953 : : {
954 : 3864190 : 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 : 98254400 : function_info::is_single_dominating_def (const set_info *set) const
977 : : {
978 : 98254400 : return (set->is_first_def ()
979 : 81650597 : && set->is_last_def ()
980 : 155973223 : && (!HARD_REGISTER_NUM_P (set->regno ())
981 : 4765068 : || !TEST_HARD_REG_BIT (m_clobbered_by_calls, set->regno ())));
982 : : }
983 : :
984 : : inline set_info *
985 : 60496068 : function_info::single_dominating_def (unsigned int regno) const
986 : : {
987 : 60496068 : if (set_info *set = safe_dyn_cast<set_info *> (m_defs[regno + 1]))
988 : 57940888 : if (is_single_dominating_def (set))
989 : 34224497 : return set;
990 : : return nullptr;
991 : : }
992 : :
993 : : template<typename IgnorePredicates>
994 : : bool
995 : 2584282 : 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 : 2584282 : 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 : 2031145 : insn_info *insn = change.move_range.clamp_insn_to_range (change.insn ());
1006 : 2031145 : def_array new_defs = insert_temp_clobber (watermark, insn, regno,
1007 : : change.new_defs);
1008 : 3026 : if (!new_defs.is_valid ())
1009 : : return false;
1010 : :
1011 : : // Find a definition at or neighboring INSN.
1012 : 2031145 : insn_range_info move_range = change.move_range;
1013 : 2031145 : if (!restrict_movement_for_dead_range (move_range, regno, insn, ignore))
1014 : : return false;
1015 : :
1016 : 2028119 : change.new_defs = new_defs;
1017 : 2028119 : change.move_range = move_range;
1018 : 2028119 : 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 : 7741327 : ignore_changing_insns::
1035 : 7741327 : ignore_changing_insns (array_slice<insn_change *const> changes)
1036 : 7741327 : : m_changes (changes)
1037 : : {
1038 : : }
1039 : :
1040 : : inline bool
1041 : 38403103 : ignore_changing_insns::should_ignore_insn (const insn_info *insn)
1042 : : {
1043 : 102580525 : for (const insn_change *change : m_changes)
1044 : 72843486 : if (change->insn () == insn)
1045 : : return true;
1046 : : return false;
1047 : : }
1048 : :
1049 : : }
|