Branch data Line data Source code
1 : : // Implementation of public inline member functions for RTL SSA -*- C++ -*-
2 : : // Copyright (C) 2020-2024 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 : 68668807 : access_array_builder::reserve (unsigned int num_accesses)
31 : : {
32 : 68668807 : obstack_make_room (m_obstack, num_accesses * sizeof (access_info *));
33 : 68668807 : }
34 : :
35 : : inline void
36 : 137619399 : access_array_builder::quick_push (access_info *access)
37 : : {
38 : 117717477 : obstack_ptr_grow_fast (m_obstack, access);
39 : 20812516 : }
40 : :
41 : : inline array_slice<access_info *>
42 : 66594811 : access_array_builder::finish ()
43 : : {
44 : 66594811 : unsigned num_accesses
45 : 66594811 : = obstack_object_size (m_obstack) / sizeof (access_info *);
46 : 66594811 : if (num_accesses == 0)
47 : 10836335 : return {};
48 : :
49 : 55758476 : auto **base = static_cast<access_info **> (obstack_finish (m_obstack));
50 : 55758476 : keep ();
51 : 55758476 : return { base, num_accesses };
52 : : }
53 : :
54 : : inline bool
55 : 123610162 : access_info::is_set_with_nondebug_insn_uses () const
56 : : {
57 : 123610162 : return m_is_set_with_nondebug_insn_uses;
58 : : }
59 : :
60 : : inline bool
61 : 809484559 : use_info::is_in_debug_insn () const
62 : : {
63 : 809484559 : return m_insn_or_phi.is_first () && m_is_in_debug_insn_or_phi;
64 : : }
65 : :
66 : : inline bb_info *
67 : 215334075 : use_info::bb () const
68 : : {
69 : 123317747 : if (m_insn_or_phi.is_first ())
70 : 215334075 : return m_insn_or_phi.known_first ()->bb ();
71 : 4062123 : return m_insn_or_phi.known_second ()->bb ();
72 : : }
73 : :
74 : : inline ebb_info *
75 : 32309009 : use_info::ebb () const
76 : : {
77 : 174064539 : return bb ()->ebb ();
78 : : }
79 : :
80 : : inline use_info *
81 : 1047040044 : use_info::prev_use () const
82 : : {
83 : 1722679929 : return m_last_use_or_prev_use.second_or_null ();
84 : : }
85 : :
86 : : inline use_info *
87 : 3392151719 : use_info::next_use () const
88 : : {
89 : 5203851729 : 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 : 87063049 : use_info::next_nondebug_insn_use () const
106 : : {
107 : 87063049 : if (m_is_last_nondebug_insn_use)
108 : : return nullptr;
109 : 24923594 : return m_last_nondebug_insn_use_or_next_use.known_second ();
110 : : }
111 : :
112 : : inline use_info *
113 : 39234766 : 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 : 39234766 : if (use_info *use = next_use ())
118 : 36141487 : if (use->is_in_any_insn ())
119 : 35550755 : 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 : 25298761 : 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 : 25298761 : if (use_info *use = prev_use ())
138 : 23387984 : 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 : 637053643 : use_info::last_use () const
147 : : {
148 : 925322010 : 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 : 350925286 : use_info::last_nondebug_insn_use () const
155 : : {
156 : 940603818 : return m_last_nondebug_insn_use_or_next_use.known_first ();
157 : : }
158 : :
159 : : inline def_info *
160 : 118280885 : def_info::prev_def () const
161 : : {
162 : 254517149 : return m_last_def_or_prev_def.second_or_null ();
163 : : }
164 : :
165 : : inline def_info *
166 : 262289979 : def_info::next_def () const
167 : : {
168 : 528076325 : return m_splay_root_or_next_def.second_or_null ();
169 : : }
170 : :
171 : : inline bool
172 : 70924366 : def_info::is_first_def () const
173 : : {
174 : 70924366 : return m_last_def_or_prev_def.is_first ();
175 : : }
176 : :
177 : : inline bool
178 : 74512144 : def_info::is_last_def () const
179 : : {
180 : 63747965 : return m_splay_root_or_next_def.is_first ();
181 : : }
182 : :
183 : : inline bb_info *
184 : 474341597 : def_info::bb () const
185 : : {
186 : 464825595 : return m_insn->bb ();
187 : : }
188 : :
189 : : inline ebb_info *
190 : 674313101 : def_info::ebb () const
191 : : {
192 : 674313101 : return m_insn->ebb ();
193 : : }
194 : :
195 : : inline clobber_group *
196 : 72241477 : clobber_info::group () const
197 : : {
198 : 72241477 : if (!m_group || !m_group->has_been_superceded ())
199 : : return m_group;
200 : 889 : return const_cast<clobber_info *> (this)->recompute_group ();
201 : : }
202 : :
203 : : inline use_info *
204 : 71441062 : set_info::last_use () const
205 : : {
206 : 71441062 : return m_first_use ? m_first_use->last_use () : nullptr;
207 : : }
208 : :
209 : : inline use_info *
210 : 133954481 : set_info::first_nondebug_insn_use () const
211 : : {
212 : 133954481 : if (m_is_set_with_nondebug_insn_uses)
213 : 127233068 : return m_first_use;
214 : : return nullptr;
215 : : }
216 : :
217 : : inline use_info *
218 : 87318315 : set_info::last_nondebug_insn_use () const
219 : : {
220 : 87318315 : if (m_is_set_with_nondebug_insn_uses)
221 : 64090377 : 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 : 3721651 : set_info::first_any_insn_use () const
241 : : {
242 : 3684011 : 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 : 92600552 : set_info::last_phi_use () const
249 : : {
250 : 92600552 : if (m_first_use)
251 : : {
252 : 88070231 : use_info *last = m_first_use->last_use ();
253 : 88070231 : if (last->is_in_phi ())
254 : 1551196 : return last;
255 : : }
256 : : return nullptr;
257 : : }
258 : :
259 : : inline bool
260 : 6213501 : set_info::has_nondebug_uses () const
261 : : {
262 : 11040054 : return has_nondebug_insn_uses () || has_phi_uses ();
263 : : }
264 : :
265 : : inline bool
266 : 7900036 : set_info::has_nondebug_insn_uses () const
267 : : {
268 : 7900036 : return m_is_set_with_nondebug_insn_uses;
269 : : }
270 : :
271 : : inline bool
272 : 31397999 : set_info::has_phi_uses () const
273 : : {
274 : 31397999 : return m_first_use && m_first_use->last_use ()->is_in_phi ();
275 : : }
276 : :
277 : : inline use_info *
278 : 31223247 : set_info::single_nondebug_use () const
279 : : {
280 : 31223247 : if (!has_phi_uses ())
281 : 29536712 : return single_nondebug_insn_use ();
282 : 1686535 : if (!has_nondebug_insn_uses ())
283 : 0 : return single_phi_use ();
284 : : return nullptr;
285 : : }
286 : :
287 : : inline use_info *
288 : 29536712 : set_info::single_nondebug_insn_use () const
289 : : {
290 : 29536712 : use_info *first = first_nondebug_insn_use ();
291 : 29528452 : if (first && !first->next_nondebug_insn_use ())
292 : 16655679 : 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 : 10181235 : set_info::all_uses () const
321 : : {
322 : 10181235 : 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 : 104417769 : set_info::nondebug_insn_uses () const
333 : : {
334 : 266370135 : 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 : 3721651 : set_info::all_insn_uses () const
351 : : {
352 : 38229905 : return { first_any_insn_use (), nullptr };
353 : : }
354 : :
355 : : inline iterator_range<phi_use_iterator>
356 : 90284138 : set_info::phi_uses () const
357 : : {
358 : 180568276 : return { last_phi_use (), nullptr };
359 : : }
360 : :
361 : : inline use_array
362 : 60117351 : phi_info::inputs () const
363 : : {
364 : 60117351 : if (m_num_inputs == 1)
365 : 40037097 : return use_array (&m_single_input, 1);
366 : 20080254 : return use_array (m_inputs, m_num_inputs);
367 : : }
368 : :
369 : : inline use_info *
370 : 113773647 : phi_info::input_use (unsigned int i) const
371 : : {
372 : 113773647 : if (m_num_inputs == 1)
373 : 57861870 : return as_a<use_info *> (m_single_input);
374 : 55911777 : return as_a<use_info *> (m_inputs[i]);
375 : : }
376 : :
377 : : inline set_info *
378 : 27652799 : phi_info::input_value (unsigned int i) const
379 : : {
380 : 27652799 : return input_use (i)->def ();
381 : : }
382 : :
383 : : inline def_info *
384 : 53306490 : def_node::first_def () const
385 : : {
386 : : // This should get optimized into an AND with -2.
387 : 49960325 : if (m_clobber_or_set.is_first ())
388 : : return m_clobber_or_set.known_first ();
389 : 38353287 : return m_clobber_or_set.known_second ();
390 : : }
391 : :
392 : : inline clobber_info *
393 : 12868984 : clobber_group::first_clobber () const
394 : : {
395 : 12868984 : 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 : 3665233 : def_mux::first_def () const
406 : : {
407 : 3581447 : if (is_first ())
408 : : return known_first ();
409 : 3657133 : return known_second ()->first_def ();
410 : : }
411 : :
412 : : inline def_info *
413 : 4516383 : def_mux::last_def () const
414 : : {
415 : 4516383 : if (is_first ())
416 : : return known_first ();
417 : :
418 : 3314114 : def_node *node = known_second ();
419 : 3314114 : if (auto *clobber = ::dyn_cast<clobber_group *> (node))
420 : 2923278 : return clobber->last_clobber ();
421 : :
422 : 390836 : return node->first_def ();
423 : : }
424 : :
425 : : inline set_info *
426 : 1150302 : def_mux::set () const
427 : : {
428 : 1150302 : if (is_first ())
429 : 3030 : return ::safe_dyn_cast<set_info *> (known_first ());
430 : 1275021 : return ::dyn_cast<set_info *> (known_second ()->first_def ());
431 : : }
432 : :
433 : : inline def_info *
434 : 2021355 : def_lookup::last_def_of_prev_group () const
435 : : {
436 : 2021355 : if (!mux)
437 : : return nullptr;
438 : :
439 : 2020660 : if (comparison > 0)
440 : 666449 : return mux.last_def ();
441 : :
442 : 2704370 : return mux.first_def ()->prev_def ();
443 : : }
444 : :
445 : : inline def_info *
446 : 2021352 : def_lookup::first_def_of_next_group () const
447 : : {
448 : 2021352 : if (!mux)
449 : : return nullptr;
450 : :
451 : 2020657 : if (comparison < 0)
452 : 334695 : return mux.first_def ();
453 : :
454 : 1685962 : return mux.last_def ()->next_def ();
455 : : }
456 : :
457 : : inline set_info *
458 : 2164667 : def_lookup::matching_set () const
459 : : {
460 : 2164667 : if (comparison == 0)
461 : 1150302 : 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 : 1843626 : def_lookup::matching_set_or_first_def_of_next_group () const
475 : : {
476 : 1843626 : if (set_info *set = matching_set ())
477 : : return set;
478 : 1843623 : return first_def_of_next_group ();
479 : : }
480 : :
481 : 16132792 : inline insn_note::insn_note (insn_note_kind kind)
482 : 16132792 : : m_next_note (nullptr),
483 : 16132792 : m_kind (kind),
484 : 16132792 : m_data8 (0),
485 : 16132792 : m_data16 (0),
486 : : m_data32 (0)
487 : : {
488 : : }
489 : :
490 : : template<typename T>
491 : : inline T
492 : 2606 : insn_note::as_a ()
493 : : {
494 : : using deref_type = decltype (*std::declval<T> ());
495 : : using derived = typename std::remove_reference<deref_type>::type;
496 : 2606 : gcc_checking_assert (m_kind == derived::kind);
497 : 2606 : return static_cast<T> (this);
498 : : }
499 : :
500 : : template<typename T>
501 : : inline T
502 : 2454 : insn_note::dyn_cast ()
503 : : {
504 : : using deref_type = decltype (*std::declval<T> ());
505 : : using derived = typename std::remove_reference<deref_type>::type;
506 : 2454 : if (m_kind == derived::kind)
507 : : return static_cast<T> (this);
508 : : return nullptr;
509 : : }
510 : :
511 : : inline bool
512 : 780870959 : insn_info::operator< (const insn_info &other) const
513 : : {
514 : 780870959 : if (this == &other)
515 : : return false;
516 : :
517 : 541997771 : if (LIKELY (m_point != other.m_point))
518 : 541997333 : return m_point < other.m_point;
519 : :
520 : 438 : return slow_compare_with (other) < 0;
521 : : }
522 : :
523 : : inline bool
524 : 73313762 : insn_info::operator> (const insn_info &other) const
525 : : {
526 : 72738242 : return other < *this;
527 : : }
528 : :
529 : : inline bool
530 : 216827789 : insn_info::operator<= (const insn_info &other) const
531 : : {
532 : 216827789 : return !(other < *this);
533 : : }
534 : :
535 : : inline bool
536 : 2163972 : insn_info::operator>= (const insn_info &other) const
537 : : {
538 : 2163972 : return !(*this < other);
539 : : }
540 : :
541 : : inline int
542 : 648374645 : insn_info::compare_with (const insn_info *other) const
543 : : {
544 : 648374645 : if (this == other)
545 : : return 0;
546 : :
547 : 625662373 : if (LIKELY (m_point != other->m_point))
548 : : // Assume that points remain in [0, INT_MAX].
549 : 625661508 : return m_point - other->m_point;
550 : :
551 : 865 : return slow_compare_with (*other);
552 : : }
553 : :
554 : : inline insn_info *
555 : 255013283 : insn_info::prev_nondebug_insn () const
556 : : {
557 : 255013283 : gcc_checking_assert (!is_debug_insn ());
558 : 255013283 : return m_prev_sametype_or_last_debug_insn.known_first ();
559 : : }
560 : :
561 : : inline insn_info *
562 : 163168639 : insn_info::next_nondebug_insn () const
563 : : {
564 : 163168639 : gcc_checking_assert (!is_debug_insn ());
565 : 163168639 : const insn_info *from = this;
566 : 163168639 : if (insn_info *first_debug = m_next_nondebug_or_debug_insn.second_or_null ())
567 : 13289044 : from = first_debug->last_debug_insn ();
568 : 163168639 : return from->m_next_nondebug_or_debug_insn.known_first ();
569 : : }
570 : :
571 : : inline insn_info *
572 : 2363761 : insn_info::prev_any_insn () const
573 : : {
574 : 2363761 : if (auto *last_debug = m_prev_sametype_or_last_debug_insn.second_or_null ())
575 : : // This instruction is the first in a subsequence of debug instructions.
576 : : // Move to the following nondebug instruction and get the previous one
577 : : // from there.
578 : 0 : return (last_debug->m_next_nondebug_or_debug_insn.known_first ()
579 : 0 : ->m_prev_sametype_or_last_debug_insn.known_first ());
580 : 2363761 : auto *prev = m_prev_sametype_or_last_debug_insn.known_first ();
581 : 2363761 : if (prev)
582 : : {
583 : 4727522 : auto *next = prev->next_any_insn ();
584 : 2363761 : if (next != this)
585 : : // This instruction is a non-debug instruction and there are some
586 : : // debug instructions between it and PREV. NEXT is the first of
587 : : // the debug instructions; get the last.
588 : 133261 : return next->m_prev_sametype_or_last_debug_insn.known_second ();
589 : : }
590 : : return prev;
591 : : }
592 : :
593 : : inline insn_info *
594 : 918287995 : insn_info::next_any_insn () const
595 : : {
596 : : // This should get optimized into an AND with -2.
597 : 918287995 : if (m_next_nondebug_or_debug_insn.is_first ())
598 : : return m_next_nondebug_or_debug_insn.known_first ();
599 : 240126736 : return m_next_nondebug_or_debug_insn.known_second ();
600 : : }
601 : :
602 : : inline bool
603 : 0 : insn_info::is_phi () const
604 : : {
605 : 0 : return this == ebb ()->phi_insn ();
606 : : }
607 : :
608 : : inline bool
609 : 12025058 : insn_info::is_bb_head () const
610 : : {
611 : 12025058 : return this == m_bb->head_insn ();
612 : : }
613 : :
614 : : inline bool
615 : : insn_info::is_bb_end () const
616 : : {
617 : : return this == m_bb->end_insn ();
618 : : }
619 : :
620 : : inline ebb_info *
621 : 684492380 : insn_info::ebb () const
622 : : {
623 : 651613847 : return m_bb->ebb ();
624 : : }
625 : :
626 : : inline int
627 : 13057 : insn_info::uid () const
628 : : {
629 : 13057 : return m_cost_or_uid < 0 ? m_cost_or_uid : INSN_UID (m_rtl);
630 : : }
631 : :
632 : : inline use_array
633 : 427490932 : insn_info::uses () const
634 : : {
635 : 346035483 : return use_array (m_accesses + m_num_defs, m_num_uses);
636 : : }
637 : :
638 : : inline bool
639 : : insn_info::has_call_clobbers () const
640 : : {
641 : : return find_note<insn_call_clobbers_note> ();
642 : : }
643 : :
644 : : inline def_array
645 : 206173702 : insn_info::defs () const
646 : : {
647 : 181336341 : return def_array (m_accesses, m_num_defs);
648 : : }
649 : :
650 : : inline unsigned int
651 : 27366540 : insn_info::cost () const
652 : : {
653 : 27366540 : if (m_cost_or_uid < 0)
654 : : return 0;
655 : 27366540 : if (m_cost_or_uid == UNKNOWN_COST)
656 : 13989651 : calculate_cost ();
657 : 27366540 : return m_cost_or_uid;
658 : : }
659 : :
660 : : template<typename T>
661 : : inline const T *
662 : 2315451 : insn_info::find_note () const
663 : : {
664 : : // We could break if the note kind is > T::kind, but since the number
665 : : // of notes should be very small, the check is unlikely to pay for itself.
666 : 2315451 : for (const insn_note *note = first_note (); note; note = note->next_note ())
667 : 0 : if (note->kind () == T::kind)
668 : : return static_cast<const T *> (note);
669 : : return nullptr;
670 : : }
671 : :
672 : : // Only valid for debug instructions that come after a nondebug instruction,
673 : : // and so start a subsequence of debug instructions. Return the last debug
674 : : // instruction in the subsequence.
675 : : inline insn_info *
676 : 13304366 : insn_info::last_debug_insn () const
677 : : {
678 : 13304366 : return m_prev_sametype_or_last_debug_insn.known_second ();
679 : : }
680 : :
681 : 244705303 : inline insn_range_info::insn_range_info (insn_info *first, insn_info *last)
682 : : : first (first), last (last)
683 : : {
684 : : }
685 : :
686 : : inline bool
687 : : insn_range_info::operator== (const insn_range_info &other) const
688 : : {
689 : : return first == other.first && last == other.last;
690 : : }
691 : :
692 : : inline bool
693 : : insn_range_info::operator!= (const insn_range_info &other) const
694 : : {
695 : : return first != other.first || last != other.last;
696 : : }
697 : :
698 : : inline insn_info *
699 : : insn_range_info::singleton () const
700 : : {
701 : : return first == last ? last : nullptr;
702 : : }
703 : :
704 : : inline bool
705 : : insn_range_info::includes (insn_info *insn) const
706 : : {
707 : : return *insn >= *first && *insn <= *last;
708 : : }
709 : :
710 : : inline insn_info *
711 : 2419146 : insn_range_info::clamp_insn_to_range (insn_info *insn) const
712 : : {
713 : 2419146 : if (*first > *insn)
714 : 3 : return first;
715 : 2419143 : if (*last < *insn)
716 : 21982 : return last;
717 : : return insn;
718 : : }
719 : :
720 : : inline bool
721 : : insn_range_info::is_subrange_of (const insn_range_info &other) const
722 : : {
723 : : return *first >= *other.first && *last <= *other.last;
724 : : }
725 : :
726 : : inline iterator_range<any_insn_iterator>
727 : : bb_info::all_insns () const
728 : : {
729 : : return { m_head_insn, m_end_insn->next_any_insn () };
730 : : }
731 : :
732 : : inline iterator_range<reverse_any_insn_iterator>
733 : : bb_info::reverse_all_insns () const
734 : : {
735 : : return { m_end_insn, m_head_insn->prev_any_insn () };
736 : : }
737 : :
738 : : inline iterator_range<nondebug_insn_iterator>
739 : : bb_info::nondebug_insns () const
740 : : {
741 : : return { m_head_insn, m_end_insn->next_nondebug_insn () };
742 : : }
743 : :
744 : : inline iterator_range<reverse_nondebug_insn_iterator>
745 : : bb_info::reverse_nondebug_insns () const
746 : : {
747 : : return { m_end_insn, m_head_insn->prev_nondebug_insn () };
748 : : }
749 : :
750 : : inline iterator_range<any_insn_iterator>
751 : 0 : bb_info::real_insns () const
752 : : {
753 : 0 : return { m_head_insn->next_any_insn (), m_end_insn };
754 : : }
755 : :
756 : : inline iterator_range<reverse_any_insn_iterator>
757 : : bb_info::reverse_real_insns () const
758 : : {
759 : : return { m_end_insn->prev_any_insn (), m_head_insn };
760 : : }
761 : :
762 : : inline iterator_range<nondebug_insn_iterator>
763 : : bb_info::real_nondebug_insns () const
764 : : {
765 : : return { m_head_insn->next_nondebug_insn (), m_end_insn };
766 : : }
767 : :
768 : : inline iterator_range<reverse_nondebug_insn_iterator>
769 : : bb_info::reverse_real_nondebug_insns () const
770 : : {
771 : : return { m_end_insn->prev_nondebug_insn (), m_head_insn };
772 : : }
773 : :
774 : : inline bool
775 : 47219553 : ebb_call_clobbers_info::clobbers (resource_info resource) const
776 : : {
777 : : // Only register clobbers are tracked this way. Other clobbers are
778 : : // recorded explicitly.
779 : 47219553 : return (resource.is_reg ()
780 : 47219553 : && m_abi->clobbers_reg_p (resource.mode, resource.regno));
781 : : }
782 : :
783 : : inline ebb_info *
784 : : ebb_info::prev_ebb () const
785 : : {
786 : : if (bb_info *prev_bb = m_first_bb->prev_bb ())
787 : : return prev_bb->ebb ();
788 : : return nullptr;
789 : : }
790 : :
791 : : inline ebb_info *
792 : 57388566 : ebb_info::next_ebb () const
793 : : {
794 : 57388566 : if (bb_info *next_bb = m_last_bb->next_bb ())
795 : 49693242 : return next_bb->ebb ();
796 : : return nullptr;
797 : : }
798 : :
799 : : inline iterator_range<phi_iterator>
800 : 51356417 : ebb_info::phis () const
801 : : {
802 : 51356417 : return { m_first_phi, nullptr };
803 : : }
804 : :
805 : : inline iterator_range<bb_iterator>
806 : 7242 : ebb_info::bbs () const
807 : : {
808 : 7242 : return { m_first_bb, m_last_bb->next_bb () };
809 : : }
810 : :
811 : : inline iterator_range<reverse_bb_iterator>
812 : : ebb_info::reverse_bbs () const
813 : : {
814 : : return { m_last_bb, m_first_bb->prev_bb () };
815 : : }
816 : :
817 : : inline iterator_range<any_insn_iterator>
818 : : ebb_info::all_insns () const
819 : : {
820 : : return { m_phi_insn, m_last_bb->end_insn ()->next_any_insn () };
821 : : }
822 : :
823 : : inline iterator_range<reverse_any_insn_iterator>
824 : : ebb_info::reverse_all_insns () const
825 : : {
826 : : return { m_last_bb->end_insn (), m_phi_insn->prev_any_insn () };
827 : : }
828 : :
829 : : inline iterator_range<nondebug_insn_iterator>
830 : : ebb_info::nondebug_insns () const
831 : : {
832 : : return { m_phi_insn, m_last_bb->end_insn ()->next_nondebug_insn () };
833 : : }
834 : :
835 : : inline iterator_range<reverse_nondebug_insn_iterator>
836 : : ebb_info::reverse_nondebug_insns () const
837 : : {
838 : : return { m_last_bb->end_insn (), m_phi_insn->prev_nondebug_insn () };
839 : : }
840 : :
841 : : inline insn_range_info
842 : : ebb_info::insn_range () const
843 : : {
844 : : return { m_phi_insn, m_last_bb->end_insn () };
845 : : }
846 : :
847 : : inline void
848 : 9261180 : ebb_info::set_first_call_clobbers (ebb_call_clobbers_info *call_clobbers)
849 : : {
850 : 9261180 : m_first_call_clobbers = call_clobbers;
851 : 9261180 : }
852 : :
853 : : inline ebb_call_clobbers_info *
854 : 25390778 : ebb_info::first_call_clobbers () const
855 : : {
856 : 25390778 : return m_first_call_clobbers;
857 : : }
858 : :
859 : : inline iterator_range<ebb_call_clobbers_iterator>
860 : 67764433 : ebb_info::call_clobbers () const
861 : : {
862 : 67764433 : return { m_first_call_clobbers, nullptr };
863 : : }
864 : :
865 : 55648330 : inline insn_change::insn_change (insn_info *insn)
866 : 55648330 : : m_insn (insn),
867 : 55648330 : new_defs (insn->defs ()),
868 : 55648330 : new_uses (insn->uses ()),
869 : 55648330 : move_range (insn),
870 : 55648330 : new_cost (UNKNOWN_COST),
871 : 55648330 : m_is_deletion (false)
872 : : {
873 : : }
874 : :
875 : 20334327 : inline insn_change::insn_change (insn_info *insn, delete_action)
876 : 20334327 : : m_insn (insn),
877 : 20334327 : new_defs (),
878 : 20334327 : new_uses (),
879 : 20334327 : move_range (insn),
880 : 20334327 : new_cost (0),
881 : 20334327 : m_is_deletion (true)
882 : : {
883 : : }
884 : :
885 : : inline iterator_range<bb_iterator>
886 : : function_info::bbs () const
887 : : {
888 : : return { m_first_bb, nullptr };
889 : : }
890 : :
891 : : inline iterator_range<reverse_bb_iterator>
892 : : function_info::reverse_bbs () const
893 : : {
894 : : return { m_last_bb, nullptr };
895 : : }
896 : :
897 : : inline iterator_range<ebb_iterator>
898 : 7695324 : function_info::ebbs () const
899 : : {
900 : 7695324 : return { m_first_bb->ebb (), nullptr };
901 : : }
902 : :
903 : : inline iterator_range<reverse_ebb_iterator>
904 : : function_info::reverse_ebbs () const
905 : : {
906 : : return { m_last_bb->ebb (), nullptr };
907 : : }
908 : :
909 : : inline iterator_range<any_insn_iterator>
910 : : function_info::all_insns () const
911 : : {
912 : : return { m_first_insn, nullptr };
913 : : }
914 : :
915 : : inline iterator_range<reverse_any_insn_iterator>
916 : : function_info::reverse_all_insns () const
917 : : {
918 : : return { m_last_insn, nullptr };
919 : : }
920 : :
921 : : inline iterator_range<nondebug_insn_iterator>
922 : 1849346 : function_info::nondebug_insns () const
923 : : {
924 : 1849346 : return { m_first_insn, nullptr };
925 : : }
926 : :
927 : : inline iterator_range<reverse_nondebug_insn_iterator>
928 : : function_info::reverse_nondebug_insns () const
929 : : {
930 : : return { m_last_insn, nullptr };
931 : : }
932 : :
933 : : inline iterator_range<def_iterator>
934 : : function_info::mem_defs () const
935 : : {
936 : : return { m_defs[0], nullptr };
937 : : }
938 : :
939 : : inline iterator_range<def_iterator>
940 : : function_info::reg_defs (unsigned int regno) const
941 : : {
942 : : return { m_defs[regno + 1], nullptr };
943 : : }
944 : :
945 : : inline bool
946 : 70924366 : function_info::is_single_dominating_def (const set_info *set) const
947 : : {
948 : 70924366 : return (set->is_first_def ()
949 : 64080278 : && set->is_last_def ()
950 : 113542188 : && (!HARD_REGISTER_NUM_P (set->regno ())
951 : 3769255 : || !TEST_HARD_REG_BIT (m_clobbered_by_calls, set->regno ())));
952 : : }
953 : :
954 : : inline set_info *
955 : 55565533 : function_info::single_dominating_def (unsigned int regno) const
956 : : {
957 : 55565533 : if (set_info *set = safe_dyn_cast<set_info *> (m_defs[regno + 1]))
958 : 53316099 : if (is_single_dominating_def (set))
959 : 31479064 : return set;
960 : : return nullptr;
961 : : }
962 : :
963 : : template<typename IgnorePredicates>
964 : : bool
965 : 2399590 : function_info::add_regno_clobber (obstack_watermark &watermark,
966 : : insn_change &change, unsigned int regno,
967 : : IgnorePredicates ignore)
968 : : {
969 : : // Check whether CHANGE already clobbers REGNO.
970 : 2399590 : if (find_access (change.new_defs, regno))
971 : : return true;
972 : :
973 : : // Get the closest position to INSN at which the new instruction
974 : : // could be placed.
975 : 1843626 : insn_info *insn = change.move_range.clamp_insn_to_range (change.insn ());
976 : 1843626 : def_array new_defs = insert_temp_clobber (watermark, insn, regno,
977 : : change.new_defs);
978 : 2362 : if (!new_defs.is_valid ())
979 : : return false;
980 : :
981 : : // Find a definition at or neighboring INSN.
982 : 1843626 : insn_range_info move_range = change.move_range;
983 : 1843626 : if (!restrict_movement_for_dead_range (move_range, regno, insn, ignore))
984 : : return false;
985 : :
986 : 1841264 : change.new_defs = new_defs;
987 : 1841264 : change.move_range = move_range;
988 : 1841264 : return true;
989 : : }
990 : :
991 : : template<typename T, typename... Ts>
992 : : inline T *
993 : 0 : function_info::change_alloc (obstack_watermark &wm, Ts... args)
994 : : {
995 : : static_assert (std::is_trivially_destructible<T>::value,
996 : : "destructor won't be called");
997 : : static_assert (alignof (T) <= obstack_alignment,
998 : : "too much alignment required");
999 : 0 : void *addr = XOBNEW (wm, T);
1000 : 0 : return new (addr) T (std::forward<Ts> (args)...);
1001 : : }
1002 : :
1003 : : inline
1004 : : ignore_changing_insns::
1005 : : ignore_changing_insns (array_slice<insn_change *const> changes)
1006 : : : m_changes (changes)
1007 : : {
1008 : : }
1009 : :
1010 : : inline bool
1011 : : ignore_changing_insns::should_ignore_insn (const insn_info *insn)
1012 : : {
1013 : : for (const insn_change *change : m_changes)
1014 : : if (change->insn () == insn)
1015 : : return true;
1016 : : return false;
1017 : : }
1018 : :
1019 : : }
|