Branch data Line data Source code
1 : : // Implementation of access-related 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 : : #define INCLUDE_ALGORITHM
21 : : #define INCLUDE_FUNCTIONAL
22 : : #define INCLUDE_ARRAY
23 : : #include "config.h"
24 : : #include "system.h"
25 : : #include "coretypes.h"
26 : : #include "backend.h"
27 : : #include "rtl.h"
28 : : #include "df.h"
29 : : #include "rtl-ssa.h"
30 : : #include "rtl-ssa/internals.h"
31 : : #include "rtl-ssa/internals.inl"
32 : :
33 : : using namespace rtl_ssa;
34 : :
35 : : // This clobber belongs to a clobber_group but m_group appears to be
36 : : // out of date. Update it and return the new (correct) value.
37 : : clobber_group *
38 : 1761 : clobber_info::recompute_group ()
39 : : {
40 : 1761 : using splay_tree = clobber_info::splay_tree;
41 : :
42 : : // Splay this clobber to the root of the tree while searching for a node
43 : : // that has the correct group. The root always has the correct group,
44 : : // so the search always breaks early and does not install this clobber
45 : : // as the root.
46 : 1761 : clobber_info *cursor = m_parent;
47 : 4257 : auto find_group = [](clobber_info *node, unsigned int)
48 : : {
49 : 2496 : return node->m_group->has_been_superceded () ? nullptr : node->m_group;
50 : : };
51 : 1761 : clobber_group *group = splay_tree::splay_and_search (this, nullptr,
52 : : find_group);
53 : 1761 : gcc_checking_assert (m_parent);
54 : :
55 : : // If the previous splay operation did anything, this clobber is now an
56 : : // ancestor of CURSOR, and all the nodes inbetween have a stale group.
57 : : // Since we have visited the nodes, we might as well update them too.
58 : : //
59 : : // If the previous splay operation did nothing, start the update from
60 : : // this clobber instead. In that case we change at most two clobbers:
61 : : // this clobber and possibly its parent.
62 : 1761 : if (cursor == m_parent)
63 : 1733 : cursor = this;
64 : :
65 : : // Walk up the tree from CURSOR updating clobbers that need it.
66 : : // This walk always includes this clobber.
67 : 4220 : while (cursor->m_group != group)
68 : : {
69 : 2459 : cursor->m_group = group;
70 : 2459 : cursor = cursor->m_parent;
71 : : }
72 : :
73 : 1761 : gcc_checking_assert (m_group == group);
74 : 1761 : return group;
75 : : }
76 : :
77 : : // See the comment above the declaration.
78 : : void
79 : 0 : resource_info::print_identifier (pretty_printer *pp) const
80 : : {
81 : 0 : if (is_mem ())
82 : 0 : pp_string (pp, "mem");
83 : : else
84 : : {
85 : 0 : char tmp[3 * sizeof (regno) + 2];
86 : 0 : snprintf (tmp, sizeof (tmp), "r%d", regno);
87 : 0 : pp_string (pp, tmp);
88 : : }
89 : 0 : }
90 : :
91 : : // See the comment above the declaration.
92 : : void
93 : 0 : resource_info::print_context (pretty_printer *pp) const
94 : : {
95 : 0 : if (HARD_REGISTER_NUM_P (regno))
96 : : {
97 : 0 : if (const char *name = reg_names[regno])
98 : : {
99 : 0 : pp_space (pp);
100 : 0 : pp_left_paren (pp);
101 : 0 : pp_string (pp, name);
102 : 0 : if (mode != E_BLKmode)
103 : : {
104 : 0 : pp_colon (pp);
105 : 0 : pp_string (pp, GET_MODE_NAME (mode));
106 : : }
107 : 0 : pp_right_paren (pp);
108 : : }
109 : : }
110 : 0 : else if (is_reg ())
111 : : {
112 : 0 : pp_space (pp);
113 : 0 : pp_left_paren (pp);
114 : 0 : if (mode != E_BLKmode)
115 : : {
116 : 0 : pp_string (pp, GET_MODE_NAME (mode));
117 : 0 : pp_space (pp);
118 : : }
119 : 0 : pp_string (pp, "pseudo");
120 : 0 : pp_right_paren (pp);
121 : : }
122 : 0 : }
123 : :
124 : : // See the comment above the declaration.
125 : : void
126 : 0 : resource_info::print (pretty_printer *pp) const
127 : : {
128 : 0 : print_identifier (pp);
129 : 0 : print_context (pp);
130 : 0 : }
131 : :
132 : : // Some properties can naturally be described using adjectives that attach
133 : : // to nouns like "use" or "definition". Print such adjectives to PP.
134 : : void
135 : 0 : access_info::print_prefix_flags (pretty_printer *pp) const
136 : : {
137 : 0 : if (m_is_temp)
138 : 0 : pp_string (pp, "temporary ");
139 : 0 : if (m_has_been_superceded)
140 : 0 : pp_string (pp, "superceded ");
141 : 0 : }
142 : :
143 : : // Print properties not handled by print_prefix_flags to PP, putting
144 : : // each property on a new line indented by two extra spaces.
145 : : void
146 : 0 : access_info::print_properties_on_new_lines (pretty_printer *pp) const
147 : : {
148 : 0 : if (m_is_pre_post_modify)
149 : : {
150 : 0 : pp_newline_and_indent (pp, 2);
151 : 0 : pp_string (pp, "set by a pre/post-modify");
152 : 0 : pp_indentation (pp) -= 2;
153 : : }
154 : 0 : if (m_includes_address_uses)
155 : : {
156 : 0 : pp_newline_and_indent (pp, 2);
157 : 0 : pp_string (pp, "appears inside an address");
158 : 0 : pp_indentation (pp) -= 2;
159 : : }
160 : 0 : if (m_includes_read_writes)
161 : : {
162 : 0 : pp_newline_and_indent (pp, 2);
163 : 0 : pp_string (pp, "appears in a read/write context");
164 : 0 : pp_indentation (pp) -= 2;
165 : : }
166 : 0 : if (m_includes_subregs)
167 : : {
168 : 0 : pp_newline_and_indent (pp, 2);
169 : 0 : pp_string (pp, "appears inside a subreg");
170 : 0 : pp_indentation (pp) -= 2;
171 : : }
172 : 0 : }
173 : :
174 : : // Return true if there are no known issues with the integrity of the
175 : : // link information.
176 : : inline bool
177 : 1549911696 : use_info::check_integrity ()
178 : : {
179 : 4652147412 : auto subsequence_id = [](use_info *use)
180 : : {
181 : 1551117858 : if (use->is_in_nondebug_insn ())
182 : : return 1;
183 : 639248032 : if (use->is_in_debug_insn ())
184 : 311584274 : return 2;
185 : : return 3;
186 : : };
187 : :
188 : 1549911696 : use_info *prev = prev_use ();
189 : 1549911696 : use_info *next = next_use ();
190 : :
191 : 2629587513 : if (prev && subsequence_id (prev) > subsequence_id (this))
192 : : return false;
193 : 2195066909 : if (next && subsequence_id (next) < subsequence_id (this))
194 : : return false;
195 : 1549911696 : if (m_is_last_nondebug_insn_use != calculate_is_last_nondebug_insn_use ())
196 : : return false;
197 : :
198 : 1549911696 : if (!prev && last_use ()->next_use ())
199 : : return false;
200 : 1549911696 : if (!next)
201 : 964653768 : if (use_info *use = last_nondebug_insn_use ())
202 : 880383908 : if (!use->m_is_last_nondebug_insn_use)
203 : 0 : return false;
204 : :
205 : : return true;
206 : : }
207 : :
208 : : // See the comment above the declaration.
209 : : void
210 : 0 : use_info::print_location (pretty_printer *pp) const
211 : : {
212 : 0 : if (is_in_phi ())
213 : 0 : pp_access (pp, phi (), PP_ACCESS_INCLUDE_LOCATION);
214 : : else
215 : 0 : insn ()->print_identifier_and_location (pp);
216 : 0 : }
217 : :
218 : : // See the comment above the declaration.
219 : : void
220 : 0 : use_info::print_def (pretty_printer *pp) const
221 : : {
222 : 0 : if (const set_info *set = def ())
223 : 0 : pp_access (pp, set, 0);
224 : : else
225 : : {
226 : 0 : pp_string (pp, "undefined ");
227 : 0 : resource ().print (pp);
228 : : }
229 : 0 : }
230 : :
231 : : // See the comment above the declaration.
232 : : void
233 : 0 : use_info::print (pretty_printer *pp, unsigned int flags) const
234 : : {
235 : 0 : print_prefix_flags (pp);
236 : :
237 : 0 : const set_info *set = def ();
238 : 0 : if (set && set->mode () != mode ())
239 : : {
240 : 0 : pp_string (pp, GET_MODE_NAME (mode ()));
241 : 0 : pp_space (pp);
242 : : }
243 : :
244 : 0 : pp_string (pp, "use of ");
245 : 0 : print_def (pp);
246 : 0 : if (flags & PP_ACCESS_INCLUDE_LOCATION)
247 : : {
248 : 0 : pp_string (pp, " by ");
249 : 0 : print_location (pp);
250 : : }
251 : 0 : if (set && (flags & PP_ACCESS_INCLUDE_LINKS))
252 : : {
253 : 0 : pp_newline_and_indent (pp, 2);
254 : 0 : pp_string (pp, "defined in ");
255 : 0 : set->insn ()->print_location (pp);
256 : 0 : pp_indentation (pp) -= 2;
257 : : }
258 : 0 : if (flags & PP_ACCESS_INCLUDE_PROPERTIES)
259 : 0 : print_properties_on_new_lines (pp);
260 : 0 : }
261 : :
262 : : // See the comment above the declaration.
263 : : void
264 : 0 : def_info::print_identifier (pretty_printer *pp) const
265 : : {
266 : 0 : resource ().print_identifier (pp);
267 : 0 : pp_colon (pp);
268 : 0 : insn ()->print_identifier (pp);
269 : 0 : resource ().print_context (pp);
270 : 0 : }
271 : :
272 : : // See the comment above the declaration.
273 : : void
274 : 0 : def_info::print_location (pretty_printer *pp) const
275 : : {
276 : 0 : insn ()->print_identifier_and_location (pp);
277 : 0 : }
278 : :
279 : : // See the comment above the declaration.
280 : : void
281 : 0 : clobber_info::print (pretty_printer *pp, unsigned int flags) const
282 : : {
283 : 0 : print_prefix_flags (pp);
284 : 0 : if (is_call_clobber ())
285 : 0 : pp_string (pp, "call ");
286 : 0 : pp_string (pp, "clobber ");
287 : 0 : print_identifier (pp);
288 : 0 : if (flags & PP_ACCESS_INCLUDE_LOCATION)
289 : : {
290 : 0 : pp_string (pp, " in ");
291 : 0 : insn ()->print_location (pp);
292 : : }
293 : 0 : if (flags & PP_ACCESS_INCLUDE_PROPERTIES)
294 : 0 : print_properties_on_new_lines (pp);
295 : 0 : }
296 : :
297 : : // See the comment above the declaration.
298 : : void
299 : 0 : set_info::print_uses_on_new_lines (pretty_printer *pp) const
300 : : {
301 : 0 : for (const use_info *use : all_uses ())
302 : : {
303 : 0 : pp_newline_and_indent (pp, 2);
304 : 0 : if (use->is_live_out_use ())
305 : : {
306 : 0 : pp_string (pp, "live out from ");
307 : 0 : use->insn ()->print_location (pp);
308 : : }
309 : : else
310 : : {
311 : 0 : pp_string (pp, "used by ");
312 : 0 : use->print_location (pp);
313 : : }
314 : 0 : pp_indentation (pp) -= 2;
315 : : }
316 : 0 : if (m_use_tree)
317 : : {
318 : 0 : pp_newline_and_indent (pp, 2);
319 : 0 : pp_string (pp, "splay tree:");
320 : 0 : pp_newline_and_indent (pp, 2);
321 : 0 : auto print_use = [](pretty_printer *pp,
322 : : splay_tree_node<use_info *> *node)
323 : : {
324 : 0 : pp_string (pp, "use by ");
325 : 0 : node->value ()->print_location (pp);
326 : 0 : };
327 : 0 : m_use_tree.print (pp, m_use_tree.root (), print_use);
328 : 0 : pp_indentation (pp) -= 4;
329 : : }
330 : 0 : }
331 : :
332 : : // See the comment above the declaration.
333 : : void
334 : 0 : set_info::print (pretty_printer *pp, unsigned int flags) const
335 : : {
336 : 0 : print_prefix_flags (pp);
337 : 0 : pp_string (pp, "set ");
338 : 0 : print_identifier (pp);
339 : 0 : if (flags & PP_ACCESS_INCLUDE_LOCATION)
340 : : {
341 : 0 : pp_string (pp, " in ");
342 : 0 : insn ()->print_location (pp);
343 : : }
344 : 0 : if (flags & PP_ACCESS_INCLUDE_PROPERTIES)
345 : 0 : print_properties_on_new_lines (pp);
346 : 0 : if (flags & PP_ACCESS_INCLUDE_LINKS)
347 : 0 : print_uses_on_new_lines (pp);
348 : 0 : }
349 : :
350 : : // See the comment above the declaration.
351 : : void
352 : 0 : phi_info::print (pretty_printer *pp, unsigned int flags) const
353 : : {
354 : 0 : print_prefix_flags (pp);
355 : 0 : pp_string (pp, "phi node ");
356 : 0 : print_identifier (pp);
357 : 0 : if (flags & PP_ACCESS_INCLUDE_LOCATION)
358 : : {
359 : 0 : pp_string (pp, " in ");
360 : 0 : insn ()->print_location (pp);
361 : : }
362 : :
363 : 0 : if (flags & PP_ACCESS_INCLUDE_PROPERTIES)
364 : 0 : print_properties_on_new_lines (pp);
365 : :
366 : 0 : if (flags & PP_ACCESS_INCLUDE_LINKS)
367 : : {
368 : 0 : basic_block cfg_bb = bb ()->cfg_bb ();
369 : 0 : pp_newline_and_indent (pp, 2);
370 : 0 : pp_string (pp, "inputs:");
371 : 0 : unsigned int i = 0;
372 : 0 : for (const use_info *input : inputs ())
373 : : {
374 : 0 : basic_block pred_cfg_bb = EDGE_PRED (cfg_bb, i)->src;
375 : 0 : pp_newline_and_indent (pp, 2);
376 : 0 : pp_string (pp, "bb");
377 : 0 : pp_decimal_int (pp, pred_cfg_bb->index);
378 : 0 : pp_colon (pp);
379 : 0 : pp_space (pp);
380 : 0 : input->print_def (pp);
381 : 0 : pp_indentation (pp) -= 2;
382 : 0 : i += 1;
383 : : }
384 : 0 : pp_indentation (pp) -= 2;
385 : :
386 : 0 : print_uses_on_new_lines (pp);
387 : : }
388 : 0 : }
389 : :
390 : : // See the comment above the declaration.
391 : : void
392 : 0 : set_node::print (pretty_printer *pp) const
393 : : {
394 : 0 : pp_access (pp, first_def ());
395 : 0 : }
396 : :
397 : : // See the comment above the declaration.
398 : : clobber_info *
399 : 8 : clobber_group::prev_clobber (insn_info *insn) const
400 : : {
401 : 8 : int comparison = lookup_clobber (insn);
402 : 8 : if (comparison <= 0)
403 : 16 : return dyn_cast<clobber_info *> (m_clobber_tree.root ()->prev_def ());
404 : 0 : return m_clobber_tree.root ();
405 : : }
406 : :
407 : : // See the comment above the declaration.
408 : : clobber_info *
409 : 8 : clobber_group::next_clobber (insn_info *insn) const
410 : : {
411 : 8 : int comparison = lookup_clobber (insn);
412 : 8 : if (comparison >= 0)
413 : 16 : return dyn_cast<clobber_info *> (m_clobber_tree.root ()->next_def ());
414 : 0 : return m_clobber_tree.root ();
415 : : }
416 : :
417 : : // See the comment above the declaration.
418 : : void
419 : 0 : clobber_group::print (pretty_printer *pp) const
420 : : {
421 : 0 : auto print_clobber = [](pretty_printer *pp, const def_info *clobber)
422 : : {
423 : 0 : pp_access (pp, clobber);
424 : : };
425 : 0 : pp_string (pp, "grouped clobber");
426 : 0 : for (const def_info *clobber : clobbers ())
427 : : {
428 : 0 : pp_newline_and_indent (pp, 2);
429 : 0 : print_clobber (pp, clobber);
430 : 0 : pp_indentation (pp) -= 2;
431 : : }
432 : 0 : pp_newline_and_indent (pp, 2);
433 : 0 : pp_string (pp, "splay tree");
434 : 0 : pp_newline_and_indent (pp, 2);
435 : 0 : m_clobber_tree.print (pp, print_clobber);
436 : 0 : pp_indentation (pp) -= 4;
437 : 0 : }
438 : :
439 : : // A wrapper around rtl_ssa::lookup_clobber that ensures that the root
440 : : // of the splay tree always has the correct group.
441 : : int
442 : 323415 : clobber_group::lookup_clobber (insn_info *insn) const
443 : : {
444 : 323415 : auto &tree = const_cast<clobber_tree &> (m_clobber_tree);
445 : 323415 : int result = rtl_ssa::lookup_clobber (tree, insn);
446 : 323415 : tree->update_group (const_cast<clobber_group *> (this));
447 : 323415 : return result;
448 : : }
449 : :
450 : : // See the comment above the declaration.
451 : : def_info *
452 : 181772 : def_lookup::prev_def (insn_info *insn) const
453 : : {
454 : 181772 : if (mux && comparison == 0)
455 : 8 : if (auto *node = mux.dyn_cast<def_node *> ())
456 : 8 : if (auto *group = dyn_cast<clobber_group *> (node))
457 : 8 : if (clobber_info *clobber = group->prev_clobber (insn))
458 : : return clobber;
459 : :
460 : 181764 : return last_def_of_prev_group ();
461 : : }
462 : :
463 : : // See the comment above the declaration.
464 : : def_info *
465 : 181772 : def_lookup::next_def (insn_info *insn) const
466 : : {
467 : 181772 : if (mux && comparison == 0)
468 : 8 : if (auto *node = mux.dyn_cast<def_node *> ())
469 : 8 : if (auto *group = dyn_cast<clobber_group *> (node))
470 : 8 : if (clobber_info *clobber = group->next_clobber (insn))
471 : : return clobber;
472 : :
473 : 181764 : return first_def_of_next_group ();
474 : : }
475 : :
476 : : // Return a clobber_group for CLOBBER, creating one if CLOBBER doesn't
477 : : // already belong to a group.
478 : : clobber_group *
479 : 87239246 : function_info::need_clobber_group (clobber_info *clobber)
480 : : {
481 : 87239246 : if (clobber->is_in_group ())
482 : 68444133 : return clobber->group ();
483 : 18795113 : return allocate<clobber_group> (clobber);
484 : : }
485 : :
486 : : // Return a def_node for inserting DEF into the associated resource's
487 : : // splay tree. Use a clobber_group if DEF is a clobber and a set_node
488 : : // otherwise.
489 : : def_node *
490 : 20473188 : function_info::need_def_node (def_info *def)
491 : : {
492 : 20473188 : if (auto *clobber = dyn_cast<clobber_info *> (def))
493 : 4235526 : return need_clobber_group (clobber);
494 : 16237662 : return allocate<set_node> (as_a<set_info *> (def));
495 : : }
496 : :
497 : : // LAST is the last thing to define LAST->resource (), and is where any
498 : : // splay tree root for LAST->resource () is stored. Require such a splay tree
499 : : // to exist, creating a new one if necessary. Return the root of the tree.
500 : : //
501 : : // The caller must call LAST->set_splay_root after it has finished with
502 : : // the splay tree.
503 : : def_splay_tree
504 : 2572414 : function_info::need_def_splay_tree (def_info *last)
505 : : {
506 : 2572414 : if (def_node *root = last->splay_root ())
507 : 2032328 : return root;
508 : :
509 : : // Use a left-spine rooted at the last node.
510 : 540086 : def_node *root = need_def_node (last);
511 : 540086 : def_node *parent = root;
512 : 36520883 : while (def_info *prev = first_def (parent)->prev_def ())
513 : : {
514 : 19752830 : def_node *node = need_def_node (prev);
515 : 19752830 : def_splay_tree::insert_child (parent, 0, node);
516 : 19752830 : parent = node;
517 : 19752830 : }
518 : 540086 : return root;
519 : : }
520 : :
521 : : // Search TREE for either:
522 : : //
523 : : // - a set_info at INSN or
524 : : // - a clobber_group whose range includes INSN
525 : : //
526 : : // If such a node exists, install it as the root of TREE and return 0.
527 : : // Otherwise arbitrarily choose between:
528 : : //
529 : : // (1) Installing the closest preceding node as the root and returning 1.
530 : : // (2) Installing the closest following node as the root and returning -1.
531 : : //
532 : : // Note that this routine should not be used to check whether INSN
533 : : // itself defines a resource; that can be checked more cheaply using
534 : : // find_access_index.
535 : : int
536 : 2695950 : rtl_ssa::lookup_def (def_splay_tree &tree, insn_info *insn)
537 : : {
538 : 30830353 : auto go_left = [&](def_node *node)
539 : : {
540 : 47785061 : return *insn < *first_def (node)->insn ();
541 : 2695950 : };
542 : 8930939 : auto go_right = [&](def_node *node)
543 : : {
544 : 12469978 : return *insn > *last_def (node)->insn ();
545 : 2695950 : };
546 : 2695950 : return tree.lookup (go_left, go_right);
547 : : }
548 : :
549 : : // Search TREE for a clobber in INSN. If such a clobber exists, install
550 : : // it as the root of TREE and return 0. Otherwise arbitrarily choose between:
551 : : //
552 : : // (1) Installing the closest preceding clobber as the root and returning 1.
553 : : // (2) Installing the closest following clobber as the root and returning -1.
554 : : int
555 : 323415 : rtl_ssa::lookup_clobber (clobber_tree &tree, insn_info *insn)
556 : : {
557 : 1555659 : auto compare = [&](clobber_info *clobber)
558 : : {
559 : 1232244 : return insn->compare_with (clobber->insn ());
560 : 323415 : };
561 : 323415 : return tree.lookup (compare);
562 : : }
563 : :
564 : : // Search for a definition of RESOURCE at INSN and return the result of
565 : : // the search as a def_lookup. See the comment above the class for more
566 : : // details.
567 : : def_lookup
568 : 2364264 : function_info::find_def (resource_info resource, insn_info *insn)
569 : : {
570 : 2364264 : def_info *first = m_defs[resource.regno + 1];
571 : 2364264 : if (!first)
572 : : // There are no nodes. The comparison result is pretty meaningless
573 : : // in this case.
574 : 710 : return { nullptr, -1 };
575 : :
576 : : // See whether the first node matches.
577 : 2363554 : auto first_result = clobber_group_or_single_def (first);
578 : 2363554 : if (*insn <= *last_def (first_result)->insn ())
579 : : {
580 : 192326 : int comparison = (*insn >= *first->insn () ? 0 : -1);
581 : 192326 : return { first_result, comparison };
582 : : }
583 : :
584 : : // See whether the last node matches.
585 : 2171228 : def_info *last = first->last_def ();
586 : 2171228 : auto last_result = clobber_group_or_single_def (last);
587 : 3299388 : if (*insn >= *first_def (last_result)->insn ())
588 : : {
589 : 411012 : int comparison = (*insn <= *last->insn () ? 0 : 1);
590 : 411012 : return { last_result, comparison };
591 : : }
592 : :
593 : : // Resort to using a splay tree to search for the result.
594 : 1760216 : def_splay_tree tree = need_def_splay_tree (last);
595 : 1760216 : int comparison = lookup_def (tree, insn);
596 : 1760216 : last->set_splay_root (tree.root ());
597 : 1760216 : return { tree.root (), comparison };
598 : : }
599 : :
600 : : // Add DEF to the function's list of definitions of DEF->resource (),
601 : : // inserting DEF immediately before BEFORE. DEF is not currently in the list.
602 : : void
603 : 369617 : function_info::insert_def_before (def_info *def, def_info *before)
604 : : {
605 : 739234 : gcc_checking_assert (!def->has_def_links ()
606 : : && *before->insn () > *def->insn ());
607 : :
608 : 369617 : def->copy_prev_from (before);
609 : 369617 : if (def_info *prev = def->prev_def ())
610 : : {
611 : 299325 : gcc_checking_assert (*prev->insn () < *def->insn ());
612 : 299325 : prev->set_next_def (def);
613 : : }
614 : : else
615 : 70292 : m_defs[def->regno () + 1] = def;
616 : :
617 : 369617 : def->set_next_def (before);
618 : 369617 : before->set_prev_def (def);
619 : 369617 : }
620 : :
621 : : // Add DEF to the function's list of definitions of DEF->resource (),
622 : : // inserting DEF immediately after AFTER. DEF is not currently in the list.
623 : : void
624 : 102432215 : function_info::insert_def_after (def_info *def, def_info *after)
625 : : {
626 : 204864430 : gcc_checking_assert (!def->has_def_links ()
627 : : && *after->insn () < *def->insn ());
628 : :
629 : 102432215 : def->copy_next_from (after);
630 : 102432215 : if (def_info *next = def->next_def ())
631 : : {
632 : 512873 : gcc_checking_assert (*next->insn () > *def->insn ());
633 : 512873 : next->set_prev_def (def);
634 : : }
635 : : else
636 : 101919342 : m_defs[def->regno () + 1]->set_last_def (def);
637 : :
638 : 102432215 : def->set_prev_def (after);
639 : 102432215 : after->set_next_def (def);
640 : 102432215 : }
641 : :
642 : : // Remove DEF from the function's list of definitions of DEF->resource ().
643 : : void
644 : 12646371 : function_info::remove_def_from_list (def_info *def)
645 : : {
646 : 12646371 : def_info *prev = def->prev_def ();
647 : 12646371 : def_info *next = def->next_def ();
648 : :
649 : 12646371 : if (next)
650 : 6314283 : next->copy_prev_from (def);
651 : : else
652 : 6332088 : m_defs[def->regno () + 1]->set_last_def (prev);
653 : :
654 : 12646371 : if (prev)
655 : 12496399 : prev->copy_next_from (def);
656 : : else
657 : 149972 : m_defs[def->regno () + 1] = next;
658 : :
659 : 12646371 : def->clear_def_links ();
660 : 12646371 : }
661 : :
662 : : // Add CLOBBER to GROUP and insert it into the function's list of
663 : : // accesses to CLOBBER->resource (). CLOBBER is not currently part
664 : : // of an active group and is not currently in the list.
665 : : void
666 : 323399 : function_info::add_clobber (clobber_info *clobber, clobber_group *group)
667 : : {
668 : : // Search for either the previous or next clobber in the group.
669 : : // The result is less than zero if CLOBBER should come before NEIGHBOR
670 : : // or greater than zero if CLOBBER should come after NEIGHBOR.
671 : 323399 : int comparison = group->lookup_clobber (clobber->insn ());
672 : 323399 : gcc_checking_assert (comparison != 0);
673 : 323399 : clobber_info *neighbor = group->m_clobber_tree.root ();
674 : :
675 : : // If CLOBBER comes before NEIGHBOR, insert CLOBBER to NEIGHBOR's left,
676 : : // otherwise insert CLOBBER to NEIGHBOR's right.
677 : 323399 : clobber_info::splay_tree::insert_child (neighbor, comparison > 0, clobber);
678 : 323399 : clobber->set_group (group);
679 : :
680 : : // Insert the clobber into the function-wide list and update the
681 : : // bounds of the group.
682 : 323399 : if (comparison > 0)
683 : : {
684 : 24074 : insert_def_after (clobber, neighbor);
685 : 24074 : if (neighbor == group->last_clobber ())
686 : 0 : group->set_last_clobber (clobber);
687 : : }
688 : : else
689 : : {
690 : 299325 : insert_def_before (clobber, neighbor);
691 : 299325 : if (neighbor == group->first_clobber ())
692 : 0 : group->set_first_clobber (clobber);
693 : : }
694 : 323399 : }
695 : :
696 : : // Remove CLOBBER from GROUP, given that GROUP contains other clobbers too.
697 : : // Also remove CLOBBER from the function's list of accesses to
698 : : // CLOBBER->resource ().
699 : : void
700 : 805445 : function_info::remove_clobber (clobber_info *clobber, clobber_group *group)
701 : : {
702 : 805445 : if (clobber == group->first_clobber ())
703 : : {
704 : 563004 : auto *new_first = as_a<clobber_info *> (clobber->next_def ());
705 : 281502 : group->set_first_clobber (new_first);
706 : 281502 : new_first->update_group (group);
707 : : }
708 : 523943 : else if (clobber == group->last_clobber ())
709 : : {
710 : 325614 : auto *new_last = as_a<clobber_info *> (clobber->prev_def ());
711 : 162807 : group->set_last_clobber (new_last);
712 : 162807 : new_last->update_group (group);
713 : : }
714 : :
715 : 805445 : clobber_info *replacement = clobber_info::splay_tree::remove_node (clobber);
716 : 805445 : if (clobber == group->m_clobber_tree.root ())
717 : : {
718 : 346698 : group->m_clobber_tree = replacement;
719 : 346698 : replacement->update_group (group);
720 : : }
721 : 805445 : clobber->set_group (nullptr);
722 : :
723 : 805445 : remove_def_from_list (clobber);
724 : 805445 : }
725 : :
726 : : // Add CLOBBER immediately before the first clobber in GROUP, given that
727 : : // CLOBBER is not currently part of any group.
728 : : void
729 : 224657 : function_info::prepend_clobber_to_group (clobber_info *clobber,
730 : : clobber_group *group)
731 : : {
732 : 224657 : clobber_info *next = group->first_clobber ();
733 : 224657 : clobber_info::splay_tree::insert_child (next, 0, clobber);
734 : 224657 : group->set_first_clobber (clobber);
735 : 224657 : clobber->set_group (group);
736 : 224657 : }
737 : :
738 : : // Add CLOBBER immediately after the last clobber in GROUP, given that
739 : : // CLOBBER is not currently part of any group.
740 : : void
741 : 82779535 : function_info::append_clobber_to_group (clobber_info *clobber,
742 : : clobber_group *group)
743 : : {
744 : 82779535 : clobber_info *prev = group->last_clobber ();
745 : 82779535 : clobber_info::splay_tree::insert_child (prev, 1, clobber);
746 : 82779535 : group->set_last_clobber (clobber);
747 : 82779535 : clobber->set_group (group);
748 : 82779535 : }
749 : :
750 : : // Put CLOBBER1 and CLOBBER2 into the same clobber_group, given that
751 : : // CLOBBER1 occurs immediately before CLOBBER2 and that the two clobbers
752 : : // are not currently in the same group. LAST is the last definition of
753 : : // the associated resource, and is where any splay tree is stored.
754 : : void
755 : 1838 : function_info::merge_clobber_groups (clobber_info *clobber1,
756 : : clobber_info *clobber2,
757 : : def_info *last)
758 : : {
759 : 1838 : if (clobber1->is_in_group () && clobber2->is_in_group ())
760 : : {
761 : 701 : clobber_group *group1 = clobber1->group ();
762 : 701 : clobber_group *group2 = clobber2->group ();
763 : 701 : gcc_checking_assert (clobber1 == group1->last_clobber ()
764 : : && clobber2 == group2->first_clobber ());
765 : :
766 : 701 : if (def_splay_tree tree = last->splay_root ())
767 : : {
768 : : // Remove GROUP2 from the splay tree.
769 : 205 : int comparison = lookup_def (tree, clobber2->insn ());
770 : 205 : gcc_checking_assert (comparison == 0);
771 : 205 : tree.remove_root ();
772 : 205 : last->set_splay_root (tree.root ());
773 : : }
774 : :
775 : : // Splice the trees together.
776 : 701 : group1->m_clobber_tree.splice_next_tree (group2->m_clobber_tree);
777 : :
778 : : // Bring the two extremes of GROUP2 under GROUP1. Any other
779 : : // clobbers in the group are updated lazily on demand.
780 : 701 : clobber2->set_group (group1);
781 : 701 : group2->last_clobber ()->set_group (group1);
782 : 701 : group1->set_last_clobber (group2->last_clobber ());
783 : :
784 : : // Record that GROUP2 is no more.
785 : 701 : group2->set_first_clobber (nullptr);
786 : 701 : group2->set_last_clobber (nullptr);
787 : 701 : group2->m_clobber_tree = nullptr;
788 : : }
789 : : else
790 : : {
791 : : // In this case there can be no active splay tree.
792 : 1137 : gcc_assert (!last->splay_root ());
793 : 1137 : if (clobber2->is_in_group ())
794 : 472 : prepend_clobber_to_group (clobber1, clobber2->group ());
795 : : else
796 : 665 : append_clobber_to_group (clobber2, need_clobber_group (clobber1));
797 : : }
798 : 1838 : }
799 : :
800 : : // GROUP spans INSN, and INSN now sets the resource that GROUP clobbers.
801 : : // Split GROUP around INSN, to form two new groups. The first of the
802 : : // returned groups comes before INSN and the second comes after INSN.
803 : : //
804 : : // The caller is responsible for updating the def_splay_tree and chaining
805 : : // the defs together.
806 : : std::array<clobber_group *, 2>
807 : 0 : function_info::split_clobber_group (clobber_group *group, insn_info *insn)
808 : : {
809 : : // Search for either the previous or next clobber in the group.
810 : : // The result is less than zero if CLOBBER should come before NEIGHBOR
811 : : // or greater than zero if CLOBBER should come after NEIGHBOR.
812 : 0 : clobber_tree &tree1 = group->m_clobber_tree;
813 : 0 : int comparison = lookup_clobber (tree1, insn);
814 : 0 : gcc_checking_assert (comparison != 0);
815 : 0 : clobber_info *neighbor = tree1.root ();
816 : :
817 : 0 : clobber_tree tree2;
818 : 0 : clobber_info *prev;
819 : 0 : clobber_info *next;
820 : 0 : if (comparison > 0)
821 : : {
822 : : // NEIGHBOR is the last clobber in what will become the first group.
823 : 0 : tree2 = tree1.split_after_root ();
824 : 0 : prev = neighbor;
825 : 0 : next = as_a<clobber_info *> (prev->next_def ());
826 : : }
827 : : else
828 : : {
829 : : // NEIGHBOR is the first clobber in what will become the second group.
830 : 0 : tree2 = neighbor;
831 : 0 : tree1 = tree2.split_before_root ();
832 : 0 : next = neighbor;
833 : 0 : prev = as_a<clobber_info *> (next->prev_def ());
834 : : }
835 : :
836 : : // Create a new group for each side of the split. We need to invalidate
837 : : // the old group so that clobber_info::group can tell whether a lazy
838 : : // update is needed.
839 : 0 : clobber_info *first_clobber = group->first_clobber ();
840 : 0 : clobber_info *last_clobber = group->last_clobber ();
841 : 0 : auto *group1 = allocate<clobber_group> (first_clobber, prev, tree1.root ());
842 : 0 : auto *group2 = allocate<clobber_group> (next, last_clobber, tree2.root ());
843 : :
844 : : // Invalidate the old group.
845 : 0 : group->set_last_clobber (nullptr);
846 : :
847 : 0 : return { group1, group2 };
848 : : }
849 : :
850 : : // Add DEF to the end of the function's list of definitions of
851 : : // DEF->resource (). There is known to be no associated splay tree yet.
852 : : void
853 : 511464416 : function_info::append_def (def_info *def)
854 : : {
855 : 511464416 : gcc_checking_assert (!def->has_def_links ());
856 : 511464416 : def_info **head = &m_defs[def->regno () + 1];
857 : 511464416 : def_info *first = *head;
858 : 511464416 : if (!first)
859 : : {
860 : : // This is the only definition of the resource.
861 : 161156754 : def->set_last_def (def);
862 : 161156754 : *head = def;
863 : 161156754 : return;
864 : : }
865 : :
866 : 350307662 : def_info *prev = first->last_def ();
867 : 350307662 : gcc_checking_assert (!prev->splay_root ());
868 : :
869 : : // Maintain the invariant that two clobbers must not appear in
870 : : // neighboring nodes of the splay tree.
871 : 350307662 : auto *clobber = dyn_cast<clobber_info *> (def);
872 : 350307662 : auto *prev_clobber = dyn_cast<clobber_info *> (prev);
873 : 350307662 : if (clobber && prev_clobber)
874 : 82620527 : append_clobber_to_group (clobber, need_clobber_group (prev_clobber));
875 : :
876 : 350307662 : prev->set_next_def (def);
877 : 350307662 : def->set_prev_def (prev);
878 : 350307662 : first->set_last_def (def);
879 : : }
880 : :
881 : : // Add DEF to the function's list of definitions of DEF->resource ().
882 : : // Also insert it into the associated splay tree, if there is one.
883 : : // DEF is not currently part of the list and is not in the splay tree.
884 : : void
885 : 102816125 : function_info::add_def (def_info *def)
886 : : {
887 : 205632250 : gcc_checking_assert (!def->has_def_links ()
888 : : && !def->m_is_temp
889 : : && !def->m_has_been_superceded);
890 : 102816125 : def_info **head = &m_defs[def->regno () + 1];
891 : 102816125 : def_info *first = *head;
892 : 102816125 : if (!first)
893 : : {
894 : : // This is the only definition of the resource.
895 : 14293 : def->set_last_def (def);
896 : 14293 : *head = def;
897 : 14293 : return;
898 : : }
899 : :
900 : 102801832 : def_info *last = first->last_def ();
901 : 102801832 : insn_info *insn = def->insn ();
902 : :
903 : 102801832 : int comparison;
904 : 102801832 : def_node *neighbor = nullptr;
905 : 102801832 : def_info *prev = nullptr;
906 : 102801832 : def_info *next = nullptr;
907 : 102801832 : if (*insn > *last->insn ())
908 : : {
909 : : // This definition comes after all other definitions.
910 : 101919342 : comparison = 1;
911 : 101919342 : if (def_splay_tree tree = last->splay_root ())
912 : : {
913 : 15841 : tree.splay_max_node ();
914 : 15841 : last->set_splay_root (tree.root ());
915 : 15841 : neighbor = tree.root ();
916 : : }
917 : 101919342 : prev = last;
918 : : }
919 : 882490 : else if (*insn < *first->insn ())
920 : : {
921 : : // This definition comes before all other definitions.
922 : 70292 : comparison = -1;
923 : 70292 : if (def_splay_tree tree = last->splay_root ())
924 : : {
925 : 14890 : tree.splay_min_node ();
926 : 14890 : last->set_splay_root (tree.root ());
927 : 14890 : neighbor = tree.root ();
928 : : }
929 : 70292 : next = first;
930 : : }
931 : : else
932 : : {
933 : : // Search the splay tree for an insertion point.
934 : 812198 : def_splay_tree tree = need_def_splay_tree (last);
935 : 812198 : comparison = lookup_def (tree, insn);
936 : 812198 : last->set_splay_root (tree.root ());
937 : 812198 : neighbor = tree.root ();
938 : :
939 : : // Deal with cases in which we found an overlapping live range.
940 : 812198 : if (comparison == 0)
941 : : {
942 : 323399 : auto *group = as_a<clobber_group *> (tree.root ());
943 : 323399 : if (auto *clobber = dyn_cast<clobber_info *> (def))
944 : : {
945 : 323399 : add_clobber (clobber, group);
946 : 323399 : return;
947 : : }
948 : 0 : auto new_groups = split_clobber_group (group, insn);
949 : :
950 : : // Insert the two new groups immediately after GROUP.
951 : 0 : def_splay_tree::insert_child (group, 1, new_groups[1]);
952 : 0 : def_splay_tree::insert_child (group, 1, new_groups[0]);
953 : :
954 : : // Remove GROUP.
955 : 0 : tree.remove_root ();
956 : 0 : last->set_splay_root (tree.root ());
957 : :
958 : 0 : prev = new_groups[0]->last_clobber ();
959 : 0 : next = new_groups[1]->first_clobber ();
960 : :
961 : : // DEF comes after the first group. (new_groups[1] and -1 would
962 : : // also work.)
963 : 0 : neighbor = new_groups[0];
964 : 0 : comparison = 1;
965 : : }
966 : : // COMPARISON is < 0 if DEF comes before NEIGHBOR or > 0 if DEF comes
967 : : // after NEIGHBOR.
968 : 488799 : else if (comparison < 0)
969 : : {
970 : 244895 : next = first_def (neighbor);
971 : 733694 : prev = next->prev_def ();
972 : : }
973 : : else
974 : : {
975 : 243904 : prev = last_def (neighbor);
976 : 732703 : next = prev->next_def ();
977 : : }
978 : : }
979 : :
980 : : // See if we should merge CLOBBER with a neighboring clobber.
981 : 102478433 : auto *clobber = dyn_cast<clobber_info *> (def);
982 : 102478433 : auto *prev_clobber = safe_dyn_cast<clobber_info *> (prev);
983 : 102478433 : auto *next_clobber = safe_dyn_cast<clobber_info *> (next);
984 : : // We shouldn't have consecutive clobber_groups.
985 : 102478433 : gcc_checking_assert (!(clobber && prev_clobber && next_clobber));
986 : 102478433 : if (clobber && prev_clobber)
987 : 158343 : append_clobber_to_group (clobber, need_clobber_group (prev_clobber));
988 : 102320090 : else if (clobber && next_clobber)
989 : 224185 : prepend_clobber_to_group (clobber, need_clobber_group (next_clobber));
990 : 102095905 : else if (neighbor)
991 : : {
992 : : // If DEF comes before NEIGHBOR, insert DEF to NEIGHBOR's left,
993 : : // otherwise insert DEF to NEIGHBOR's right.
994 : 180272 : def_node *node = need_def_node (def);
995 : 180272 : def_splay_tree::insert_child (neighbor, comparison >= 0, node);
996 : : }
997 : 102478433 : if (prev)
998 : 102408141 : insert_def_after (def, prev);
999 : : else
1000 : 70292 : insert_def_before (def, next);
1001 : : }
1002 : :
1003 : : // Remove DEF from the function's list of definitions of DEF->resource ().
1004 : : // Also remove DEF from the associated splay tree, if there is one.
1005 : : void
1006 : 14320791 : function_info::remove_def (def_info *def)
1007 : : {
1008 : 14320791 : def_info **head = &m_defs[def->regno () + 1];
1009 : 14320791 : def_info *first = *head;
1010 : 14320791 : gcc_checking_assert (first);
1011 : 14320791 : if (first->is_last_def ())
1012 : : {
1013 : : // DEF is the only definition of the resource.
1014 : 1674420 : gcc_checking_assert (first == def);
1015 : 1674420 : *head = nullptr;
1016 : 1674420 : def->clear_def_links ();
1017 : 1674420 : return;
1018 : : }
1019 : :
1020 : : // If CLOBBER belongs to a clobber_group that contains other clobbers
1021 : : // too, then we need to update the clobber_group and the list, but any
1022 : : // splay tree that contains the clobber_group is unaffected.
1023 : 12646371 : if (auto *clobber = dyn_cast<clobber_info *> (def))
1024 : 1073134 : if (clobber->is_in_group ())
1025 : : {
1026 : 924299 : clobber_group *group = clobber->group ();
1027 : 924299 : if (group->first_clobber () != group->last_clobber ())
1028 : : {
1029 : 805445 : remove_clobber (clobber, group);
1030 : 805445 : return;
1031 : : }
1032 : : }
1033 : :
1034 : : // If we've created a splay tree for this resource, remove the entry
1035 : : // for DEF.
1036 : 11840926 : def_info *last = first->last_def ();
1037 : 11840926 : if (def_splay_tree tree = last->splay_root ())
1038 : : {
1039 : 123331 : int comparison = lookup_def (tree, def->insn ());
1040 : 123331 : gcc_checking_assert (comparison == 0);
1041 : 123331 : tree.remove_root ();
1042 : 123331 : last->set_splay_root (tree.root ());
1043 : : }
1044 : :
1045 : : // If the definition came between two clobbers, merge them into a single
1046 : : // group.
1047 : 11840926 : auto *prev_clobber = safe_dyn_cast<clobber_info *> (def->prev_def ());
1048 : 11840926 : auto *next_clobber = safe_dyn_cast<clobber_info *> (def->next_def ());
1049 : 11840926 : if (prev_clobber && next_clobber)
1050 : 1838 : merge_clobber_groups (prev_clobber, next_clobber, last);
1051 : :
1052 : 11840926 : remove_def_from_list (def);
1053 : : }
1054 : :
1055 : : // Require DEF to have a splay tree that contains all non-phi uses.
1056 : : void
1057 : 9246519 : function_info::need_use_splay_tree (set_info *def)
1058 : : {
1059 : 9246519 : if (!def->m_use_tree)
1060 : 40760782 : for (use_info *use : def->all_insn_uses ())
1061 : : {
1062 : 36631818 : auto *use_node = allocate<splay_tree_node<use_info *>> (use);
1063 : 36631818 : def->m_use_tree.insert_max_node (use_node);
1064 : : }
1065 : 9246519 : }
1066 : :
1067 : : // Compare two instructions by their position in a use splay tree. Return >0
1068 : : // if INSN1 comes after INSN2, <0 if INSN1 comes before INSN2, or 0 if they are
1069 : : // the same instruction.
1070 : : static inline int
1071 : 972838336 : compare_use_insns (insn_info *insn1, insn_info *insn2)
1072 : : {
1073 : : // Debug instructions go after nondebug instructions.
1074 : 972838336 : int diff = insn1->is_debug_insn () - insn2->is_debug_insn ();
1075 : 972838336 : if (diff != 0)
1076 : : return diff;
1077 : 895121982 : return insn1->compare_with (insn2);
1078 : : }
1079 : :
1080 : : // Search TREE for a use in INSN. If such a use exists, install it as
1081 : : // the root of TREE and return 0. Otherwise arbitrarily choose between:
1082 : : //
1083 : : // (1) Installing the closest preceding use as the root and returning 1.
1084 : : // (2) Installing the closest following use as the root and returning -1.
1085 : : int
1086 : 11006291 : rtl_ssa::lookup_use (splay_tree<use_info *> &tree, insn_info *insn)
1087 : : {
1088 : 74142493 : auto compare = [&](splay_tree_node<use_info *> *node)
1089 : : {
1090 : 63136202 : return compare_use_insns (insn, node->value ()->insn ());
1091 : 11006291 : };
1092 : 11006291 : return tree.lookup (compare);
1093 : : }
1094 : :
1095 : : // See the comment above the declaration.
1096 : : use_lookup
1097 : 92696080 : function_info::find_use (set_info *def, insn_info *insn)
1098 : : {
1099 : 92696080 : gcc_assert (!insn->is_debug_insn ());
1100 : 92696080 : use_info *first = def->first_nondebug_insn_use ();
1101 : 53303122 : if (!first)
1102 : : // There are no uses. The comparison result is pretty meaningless
1103 : : // in this case.
1104 : 39392958 : return { nullptr, -1 };
1105 : :
1106 : : // See whether the first use matches.
1107 : 53303122 : if (*insn <= *first->insn ())
1108 : : {
1109 : 7845219 : int comparison = (insn == first->insn () ? 0 : -1);
1110 : 7845219 : return { first, comparison };
1111 : : }
1112 : :
1113 : : // See whether the last use matches.
1114 : 45457903 : use_info *last = def->last_nondebug_insn_use ();
1115 : 45457903 : if (*insn >= *last->insn ())
1116 : : {
1117 : 43647070 : int comparison = (insn == last->insn () ? 0 : 1);
1118 : 43647070 : return { last, comparison };
1119 : : }
1120 : :
1121 : : // Resort to using a splay tree to search for the result.
1122 : 1810833 : need_use_splay_tree (def);
1123 : 1810833 : int comparison = lookup_use (def->m_use_tree, insn);
1124 : 1810833 : return { def->m_use_tree.root ()->value (), comparison };
1125 : : }
1126 : :
1127 : : // Add USE to USE->def ()'s list of uses. inserting USE immediately before
1128 : : // BEFORE. USE is not currently in the list.
1129 : : //
1130 : : // This routine should not be used for inserting phi uses.
1131 : : void
1132 : 21603955 : function_info::insert_use_before (use_info *use, use_info *before)
1133 : : {
1134 : 43207910 : gcc_checking_assert (!use->has_use_links () && use->is_in_any_insn ());
1135 : :
1136 : 21603955 : set_info *def = use->def ();
1137 : :
1138 : 21603955 : use->copy_prev_from (before);
1139 : 21603955 : use->set_next_use (before);
1140 : :
1141 : 21603955 : if (use_info *prev = use->prev_use ())
1142 : 2457984 : prev->set_next_use (use);
1143 : : else
1144 : 19192639 : use->def ()->set_first_use (use);
1145 : :
1146 : 21603955 : before->set_prev_use (use);
1147 : 21603955 : if (use->is_in_nondebug_insn () && before->is_in_debug_insn_or_phi ())
1148 : 36876184 : def->last_use ()->set_last_nondebug_insn_use (use);
1149 : :
1150 : 21603955 : gcc_checking_assert (use->check_integrity () && before->check_integrity ());
1151 : 21603955 : }
1152 : :
1153 : : // Add USE to USE->def ()'s list of uses. inserting USE immediately after
1154 : : // AFTER. USE is not currently in the list.
1155 : : //
1156 : : // This routine should not be used for inserting phi uses.
1157 : : void
1158 : 448982813 : function_info::insert_use_after (use_info *use, use_info *after)
1159 : : {
1160 : 448982813 : set_info *def = use->def ();
1161 : 897965626 : gcc_checking_assert (after->is_in_any_insn ()
1162 : : && !use->has_use_links ()
1163 : : && use->is_in_any_insn ());
1164 : :
1165 : 448982813 : use->set_prev_use (after);
1166 : 448982813 : use->copy_next_from (after);
1167 : :
1168 : 448982813 : after->set_next_use (use);
1169 : :
1170 : 448982813 : if (use_info *next = use->next_use ())
1171 : : {
1172 : : // The last node doesn't change, but we might need to update its
1173 : : // last_nondebug_insn_use record.
1174 : 87953482 : if (use->is_in_nondebug_insn () && next->is_in_debug_insn_or_phi ())
1175 : 168414970 : def->last_use ()->set_last_nondebug_insn_use (use);
1176 : 87953482 : next->set_prev_use (use);
1177 : : }
1178 : : else
1179 : : {
1180 : : // USE is now the last node.
1181 : 361029331 : if (use->is_in_nondebug_insn ())
1182 : 311266339 : use->set_last_nondebug_insn_use (use);
1183 : 361029331 : def->first_use ()->set_last_use (use);
1184 : : }
1185 : :
1186 : 448982813 : gcc_checking_assert (use->check_integrity () && after->check_integrity ());
1187 : 448982813 : }
1188 : :
1189 : : // If USE has a known definition, add USE to that definition's list of uses.
1190 : : // Also update the associated splay tree, if any.
1191 : : void
1192 : 1106351639 : function_info::add_use (use_info *use)
1193 : : {
1194 : 2212703278 : gcc_checking_assert (!use->has_use_links ()
1195 : : && !use->m_is_temp
1196 : : && !use->m_has_been_superceded);
1197 : :
1198 : 1106351639 : set_info *def = use->def ();
1199 : 1106351639 : if (!def)
1200 : 1098915953 : return;
1201 : :
1202 : 1044218885 : use_info *first = def->first_use ();
1203 : 1044218885 : if (!first)
1204 : : {
1205 : : // This is the only use of the definition.
1206 : 447659896 : use->set_last_use (use);
1207 : 447659896 : if (use->is_in_nondebug_insn ())
1208 : 391939265 : use->set_last_nondebug_insn_use (use);
1209 : :
1210 : 447659896 : def->set_first_use (use);
1211 : :
1212 : 447659896 : gcc_checking_assert (use->check_integrity ());
1213 : : return;
1214 : : }
1215 : :
1216 : 596558989 : if (use->is_in_phi ())
1217 : : {
1218 : : // Add USE at the end of the list, as the new first phi.
1219 : 125972221 : use_info *last = first->last_use ();
1220 : :
1221 : 125972221 : use->set_prev_use (last);
1222 : 125972221 : use->copy_next_from (last);
1223 : :
1224 : 125972221 : last->set_next_use (use);
1225 : 125972221 : first->set_last_use (use);
1226 : :
1227 : 125972221 : gcc_checking_assert (use->check_integrity ());
1228 : : return;
1229 : : }
1230 : :
1231 : : // If there is currently no splay tree for this definition, see if can
1232 : : // get away with a pure list-based update.
1233 : 470586768 : insn_info *insn = use->insn ();
1234 : 935435005 : auto quick_path = [&]()
1235 : : {
1236 : : // Check if USE should come before all current uses.
1237 : 464848237 : if (first->is_in_phi () || compare_use_insns (insn, first->insn ()) < 0)
1238 : : {
1239 : 19016641 : insert_use_before (use, first);
1240 : 19016641 : return true;
1241 : : }
1242 : :
1243 : : // Check if USE should come after all current uses in the same
1244 : : // subsequence (i.e. the list of nondebug insn uses or the list
1245 : : // of debug insn uses).
1246 : 445831596 : use_info *last = first->last_use ();
1247 : 445831596 : if (use->is_in_debug_insn ())
1248 : : {
1249 : 50250882 : if (last->is_in_phi ())
1250 : : return false;
1251 : : }
1252 : : else
1253 : 395580714 : last = last->last_nondebug_insn_use ();
1254 : :
1255 : 445127182 : if (compare_use_insns (insn, last->insn ()) > 0)
1256 : : {
1257 : 444134441 : insert_use_after (use, last);
1258 : 444134441 : return true;
1259 : : }
1260 : :
1261 : : return false;
1262 : 470586768 : };
1263 : 470586768 : if (!def->m_use_tree && quick_path ())
1264 : : return;
1265 : :
1266 : : // Search the splay tree for an insertion point. COMPARISON is less
1267 : : // than zero if USE should come before NEIGHBOR, or greater than zero
1268 : : // if USE should come after NEIGHBOR.
1269 : 7435686 : need_use_splay_tree (def);
1270 : 7435686 : int comparison = lookup_use (def->m_use_tree, insn);
1271 : 7435686 : gcc_checking_assert (comparison != 0);
1272 : 7435686 : use_info *neighbor = def->m_use_tree.root ()->value ();
1273 : :
1274 : : // If USE comes before NEIGHBOR, insert USE to NEIGHBOR's left,
1275 : : // otherwise insert USE to NEIGHBOR's right.
1276 : 7435686 : auto *use_node = allocate<splay_tree_node<use_info *>> (use);
1277 : 7435686 : def->m_use_tree.insert_relative (comparison, use_node);
1278 : 7435686 : if (comparison > 0)
1279 : 4848372 : insert_use_after (use, neighbor);
1280 : : else
1281 : 2587314 : insert_use_before (use, neighbor);
1282 : : }
1283 : :
1284 : : void
1285 : 0 : function_info::reparent_use (use_info *use, set_info *new_def)
1286 : : {
1287 : 0 : remove_use (use);
1288 : 0 : use->set_def (new_def);
1289 : 0 : add_use (use);
1290 : 0 : }
1291 : :
1292 : : // If USE has a known definition, remove USE from that definition's list
1293 : : // of uses. Also remove if it from the associated splay tree, if any.
1294 : : void
1295 : 45243504 : function_info::remove_use (use_info *use)
1296 : : {
1297 : 45243504 : set_info *def = use->def ();
1298 : 45243504 : if (!def)
1299 : : return;
1300 : :
1301 : : // Remove USE from the splay tree.
1302 : 45168888 : if (def->m_use_tree && use->is_in_any_insn ())
1303 : : {
1304 : 1759772 : int comparison = lookup_use (def->m_use_tree, use->insn ());
1305 : 1759772 : gcc_checking_assert (comparison == 0);
1306 : 1759772 : def->m_use_tree.remove_root ();
1307 : : }
1308 : :
1309 : 45168888 : use_info *prev = use->prev_use ();
1310 : 45168888 : use_info *next = use->next_use ();
1311 : :
1312 : 45168888 : use_info *first = def->first_use ();
1313 : 45168888 : use_info *last = first->last_use ();
1314 : 45168888 : if (last->last_nondebug_insn_use () == use)
1315 : 16848958 : last->set_last_nondebug_insn_use (prev);
1316 : :
1317 : 45168888 : if (next)
1318 : 14946872 : next->copy_prev_from (use);
1319 : : else
1320 : 30222016 : first->set_last_use (prev);
1321 : :
1322 : 45168888 : if (prev)
1323 : 20159171 : prev->copy_next_from (use);
1324 : : else
1325 : 50019434 : def->set_first_use (next);
1326 : :
1327 : 45168888 : use->clear_use_links ();
1328 : 45168888 : gcc_checking_assert ((!prev || prev->check_integrity ())
1329 : : && (!next || next->check_integrity ()));
1330 : : }
1331 : :
1332 : : // Allocate a temporary clobber_info for register REGNO in insn INSN,
1333 : : // including it in the region of the obstack governed by WATERMARK.
1334 : : // Return a new def_array that contains OLD_DEFS and the new clobber.
1335 : : //
1336 : : // OLD_DEFS is known not to define REGNO.
1337 : : def_array
1338 : 2031145 : function_info::insert_temp_clobber (obstack_watermark &watermark,
1339 : : insn_info *insn, unsigned int regno,
1340 : : def_array old_defs)
1341 : : {
1342 : 2031145 : gcc_checking_assert (watermark == &m_temp_obstack);
1343 : 2031145 : auto *clobber = allocate_temp<clobber_info> (insn, regno);
1344 : 2031145 : clobber->m_is_temp = true;
1345 : 2031145 : return insert_access (watermark, clobber, old_defs);
1346 : : }
1347 : :
1348 : : // See the comment above the declaration.
1349 : : bool
1350 : 4650418 : function_info::remains_available_at_insn (const set_info *set,
1351 : : insn_info *insn)
1352 : : {
1353 : 4650418 : auto *ebb = set->ebb ();
1354 : 4650418 : gcc_checking_assert (ebb == insn->ebb ());
1355 : :
1356 : 4650418 : def_info *next_def = set->next_def ();
1357 : 4334524 : if (next_def && *next_def->insn () < *insn)
1358 : : return false;
1359 : :
1360 : 3988866 : if (HARD_REGISTER_NUM_P (set->regno ())
1361 : 3988866 : && TEST_HARD_REG_BIT (m_clobbered_by_calls, set->regno ()))
1362 : 294421 : for (ebb_call_clobbers_info *call_group : ebb->call_clobbers ())
1363 : : {
1364 : 55541 : if (!call_group->clobbers (set->resource ()))
1365 : 1189 : continue;
1366 : :
1367 : 54352 : insn_info *call_insn = next_call_clobbers (*call_group, insn);
1368 : 54352 : if (call_insn && *call_insn < *insn)
1369 : 661552 : return false;
1370 : : }
1371 : :
1372 : : return true;
1373 : : }
1374 : :
1375 : : // See the comment above the declaration.
1376 : : bool
1377 : 457748 : function_info::remains_available_on_exit (const set_info *set, bb_info *bb)
1378 : : {
1379 : 457748 : if (HARD_REGISTER_NUM_P (set->regno ())
1380 : 457748 : && TEST_HARD_REG_BIT (m_clobbered_by_calls, set->regno ()))
1381 : : {
1382 : 39506 : insn_info *search_insn = (set->bb () == bb
1383 : 39506 : ? set->insn ()
1384 : 3143 : : bb->head_insn ());
1385 : 49967 : for (ebb_call_clobbers_info *call_group : bb->ebb ()->call_clobbers ())
1386 : : {
1387 : 13326 : if (!call_group->clobbers (set->resource ()))
1388 : 5 : continue;
1389 : :
1390 : 13321 : insn_info *insn = next_call_clobbers (*call_group, search_insn);
1391 : 13321 : if (insn && insn->bb () == bb)
1392 : 95069 : return false;
1393 : : }
1394 : : }
1395 : :
1396 : 454883 : return (set->is_last_def ()
1397 : 888356 : || *set->next_def ()->insn () > *bb->end_insn ());
1398 : : }
1399 : :
1400 : : // A subroutine of make_uses_available. Try to make USE's definition
1401 : : // available at the head of BB. WILL_BE_DEBUG_USE is true if the
1402 : : // definition will be used only in debug instructions.
1403 : : //
1404 : : // On success:
1405 : : //
1406 : : // - If the use would have the same def () as USE, return USE.
1407 : : //
1408 : : // - If BB already has a degenerate phi for the same definition,
1409 : : // return a temporary use of that phi.
1410 : : //
1411 : : // - Otherwise, the use would need a new degenerate phi. Allocate a
1412 : : // temporary phi and return a temporary use of it.
1413 : : //
1414 : : // Return null on failure.
1415 : : use_info *
1416 : 19598527 : function_info::make_use_available (use_info *use, bb_info *bb,
1417 : : bool will_be_debug_use)
1418 : : {
1419 : 19598527 : set_info *def = use->def ();
1420 : 19598527 : if (!def)
1421 : : return use;
1422 : :
1423 : 19559502 : if (is_single_dominating_def (def))
1424 : : return use;
1425 : :
1426 : 7838637 : if (def->ebb () == bb->ebb ())
1427 : : {
1428 : 4650418 : if (remains_available_at_insn (def, bb->head_insn ()))
1429 : : return use;
1430 : : return nullptr;
1431 : : }
1432 : :
1433 : 3188219 : basic_block cfg_bb = bb->cfg_bb ();
1434 : 3188219 : bb_info *use_bb = use->bb ();
1435 : 3188219 : if (single_pred_p (cfg_bb)
1436 : 1975881 : && single_pred (cfg_bb) == use_bb->cfg_bb ()
1437 : 3645967 : && remains_available_on_exit (def, use_bb))
1438 : : {
1439 : 362679 : if (will_be_debug_use)
1440 : : return use;
1441 : :
1442 : 320010 : resource_info resource = use->resource ();
1443 : 320010 : set_info *ultimate_def = look_through_degenerate_phi (def);
1444 : :
1445 : : // See if there is already a (degenerate) phi for DEF.
1446 : 320010 : insn_info *phi_insn = bb->ebb ()->phi_insn ();
1447 : 320010 : phi_info *phi;
1448 : 320010 : def_lookup dl = find_def (resource, phi_insn);
1449 : 320010 : if (set_info *set = dl.matching_set ())
1450 : : {
1451 : : // There is an existing phi.
1452 : 138238 : phi = as_a<phi_info *> (set);
1453 : 138238 : gcc_checking_assert (phi->input_value (0) == ultimate_def);
1454 : : }
1455 : : else
1456 : : {
1457 : : // Create a temporary placeholder phi. This will become
1458 : : // permanent if the change is later committed.
1459 : 181772 : phi = allocate_temp<phi_info> (phi_insn, resource, 0);
1460 : 181772 : auto *input = allocate_temp<use_info> (phi, resource, ultimate_def);
1461 : 181772 : input->m_is_temp = true;
1462 : 181772 : phi->m_is_temp = true;
1463 : 181772 : phi->make_degenerate (input);
1464 : 181772 : if (def_info *prev = dl.prev_def (phi_insn))
1465 : 181772 : phi->set_prev_def (prev);
1466 : 181772 : if (def_info *next = dl.next_def (phi_insn))
1467 : 156882 : phi->set_next_def (next);
1468 : : }
1469 : :
1470 : : // Create a temporary use of the phi at the head of the first
1471 : : // block, since we know for sure that it's available there.
1472 : 320010 : insn_info *use_insn = bb->ebb ()->first_bb ()->head_insn ();
1473 : 320010 : auto *new_use = allocate_temp<use_info> (use_insn, resource, phi);
1474 : 320010 : new_use->m_is_temp = true;
1475 : 320010 : return new_use;
1476 : : }
1477 : : return nullptr;
1478 : : }
1479 : :
1480 : : // See the comment above the declaration.
1481 : : use_array
1482 : 12384504 : function_info::make_uses_available (obstack_watermark &watermark,
1483 : : use_array uses, bb_info *bb,
1484 : : bool will_be_debug_uses)
1485 : : {
1486 : 12384504 : unsigned int num_uses = uses.size ();
1487 : 12384504 : if (num_uses == 0)
1488 : 386301 : return uses;
1489 : :
1490 : 11998203 : auto **new_uses = XOBNEWVEC (watermark, access_info *, num_uses);
1491 : 28109638 : for (unsigned int i = 0; i < num_uses; ++i)
1492 : : {
1493 : 19598527 : use_info *use = make_use_available (uses[i], bb, will_be_debug_uses);
1494 : 19598527 : if (!use)
1495 : 3487092 : return use_array (access_array::invalid ());
1496 : 16111435 : new_uses[i] = use;
1497 : : }
1498 : 8511111 : return use_array (new_uses, num_uses);
1499 : : }
1500 : :
1501 : : set_info *
1502 : 0 : function_info::create_set (obstack_watermark &watermark,
1503 : : insn_info *insn,
1504 : : resource_info resource)
1505 : : {
1506 : 0 : auto set = change_alloc<set_info> (watermark, insn, resource);
1507 : 0 : set->m_is_temp = true;
1508 : 0 : return set;
1509 : : }
1510 : :
1511 : : use_info *
1512 : 0 : function_info::create_use (obstack_watermark &watermark,
1513 : : insn_info *insn,
1514 : : set_info *set)
1515 : : {
1516 : 0 : auto use = change_alloc<use_info> (watermark, insn, set->resource (), set);
1517 : 0 : use->m_is_temp = true;
1518 : 0 : return use;
1519 : : }
1520 : :
1521 : : // Return true if ACCESS1 can represent ACCESS2 and if ACCESS2 can
1522 : : // represent ACCESS1.
1523 : : static bool
1524 : 10103680 : can_merge_accesses (access_info *access1, access_info *access2)
1525 : : {
1526 : 10103680 : if (access1 == access2)
1527 : : return true;
1528 : :
1529 : 10103680 : auto *use1 = dyn_cast<use_info *> (access1);
1530 : 10103680 : auto *use2 = dyn_cast<use_info *> (access2);
1531 : 10103680 : return use1 && use2 && use1->def () == use2->def ();
1532 : : }
1533 : :
1534 : : // See the comment above the declaration.
1535 : : access_array
1536 : 64721690 : rtl_ssa::merge_access_arrays_base (obstack_watermark &watermark,
1537 : : access_array accesses1,
1538 : : access_array accesses2)
1539 : : {
1540 : 64721690 : if (accesses1.empty ())
1541 : 2220561 : return accesses2;
1542 : 62501129 : if (accesses2.empty ())
1543 : 17745922 : return accesses1;
1544 : :
1545 : 44755207 : auto i1 = accesses1.begin ();
1546 : 44755207 : auto end1 = accesses1.end ();
1547 : 44755207 : auto i2 = accesses2.begin ();
1548 : 44755207 : auto end2 = accesses2.end ();
1549 : :
1550 : 44755207 : access_array_builder builder (watermark);
1551 : 44755207 : builder.reserve (accesses1.size () + accesses2.size ());
1552 : :
1553 : 166652351 : while (i1 != end1 && i2 != end2)
1554 : : {
1555 : 79624128 : access_info *access1 = *i1;
1556 : 79624128 : access_info *access2 = *i2;
1557 : :
1558 : 79624128 : unsigned int regno1 = access1->regno ();
1559 : 79624128 : unsigned int regno2 = access2->regno ();
1560 : 79624128 : if (regno1 == regno2)
1561 : : {
1562 : 10103680 : if (!can_merge_accesses (access1, access2))
1563 : 2482191 : return access_array::invalid ();
1564 : :
1565 : 7621489 : builder.quick_push (access1);
1566 : 7621489 : ++i1;
1567 : 7621489 : ++i2;
1568 : : }
1569 : 69520448 : else if (regno1 < regno2)
1570 : : {
1571 : 39344229 : builder.quick_push (access1);
1572 : 39344229 : ++i1;
1573 : : }
1574 : : else
1575 : : {
1576 : 30176219 : builder.quick_push (access2);
1577 : 30176219 : ++i2;
1578 : : }
1579 : : }
1580 : 70025571 : for (; i1 != end1; ++i1)
1581 : 27752555 : builder.quick_push (*i1);
1582 : 64182930 : for (; i2 != end2; ++i2)
1583 : 21909914 : builder.quick_push (*i2);
1584 : :
1585 : 42273016 : return builder.finish ();
1586 : 44755207 : }
1587 : :
1588 : : // See the comment above the declaration.
1589 : : access_array
1590 : 2031145 : rtl_ssa::insert_access_base (obstack_watermark &watermark,
1591 : : access_info *access1, access_array accesses2)
1592 : : {
1593 : 2031145 : access_array_builder builder (watermark);
1594 : 2031145 : builder.reserve (1 + accesses2.size ());
1595 : :
1596 : 2031145 : unsigned int regno1 = access1->regno ();
1597 : 2031145 : auto i2 = accesses2.begin ();
1598 : 2031145 : auto end2 = accesses2.end ();
1599 : 5707968 : while (i2 != end2)
1600 : : {
1601 : 2033265 : access_info *access2 = *i2;
1602 : :
1603 : 2033265 : unsigned int regno2 = access2->regno ();
1604 : 2033265 : if (regno1 == regno2)
1605 : : {
1606 : 0 : if (!can_merge_accesses (access1, access2))
1607 : 0 : return access_array::invalid ();
1608 : :
1609 : 0 : builder.quick_push (access1);
1610 : 0 : access1 = nullptr;
1611 : 0 : ++i2;
1612 : 0 : break;
1613 : : }
1614 : 2033265 : else if (regno1 < regno2)
1615 : : {
1616 : 387587 : builder.quick_push (access1);
1617 : 387587 : access1 = nullptr;
1618 : 387587 : break;
1619 : : }
1620 : : else
1621 : : {
1622 : 1645678 : builder.quick_push (access2);
1623 : 1645678 : ++i2;
1624 : : }
1625 : : }
1626 : 387587 : if (access1)
1627 : 1643558 : builder.quick_push (access1);
1628 : 2418734 : for (; i2 != end2; ++i2)
1629 : 387589 : builder.quick_push (*i2);
1630 : :
1631 : 2031145 : return builder.finish ();
1632 : 2031145 : }
1633 : :
1634 : : // See the comment above the declaration.
1635 : : use_array
1636 : 31411591 : rtl_ssa::remove_uses_of_def (obstack_watermark &watermark, use_array uses,
1637 : : def_info *def)
1638 : : {
1639 : 31411591 : access_array_builder uses_builder (watermark);
1640 : 31411591 : uses_builder.reserve (uses.size ());
1641 : 85050147 : for (use_info *use : uses)
1642 : 53638556 : if (use->def () != def)
1643 : 22226965 : uses_builder.quick_push (use);
1644 : 31411591 : return use_array (uses_builder.finish ());
1645 : 31411591 : }
1646 : :
1647 : : // See the comment above the declaration.
1648 : : access_array
1649 : 54802241 : rtl_ssa::remove_note_accesses_base (obstack_watermark &watermark,
1650 : : access_array accesses)
1651 : : {
1652 : 57689799 : auto predicate = [](access_info *a) {
1653 : 2887558 : return !a->only_occurs_in_notes ();
1654 : : };
1655 : :
1656 : 124523927 : for (access_info *access : accesses)
1657 : 70750403 : if (access->only_occurs_in_notes ())
1658 : 1028717 : return filter_accesses (watermark, accesses, predicate);
1659 : :
1660 : 53773524 : return accesses;
1661 : : }
1662 : :
1663 : : // See the comment above the declaration.
1664 : : bool
1665 : 8554198 : rtl_ssa::accesses_reference_same_resource (access_array accesses1,
1666 : : access_array accesses2)
1667 : : {
1668 : 8554198 : auto i1 = accesses1.begin ();
1669 : 8554198 : auto end1 = accesses1.end ();
1670 : 8554198 : auto i2 = accesses2.begin ();
1671 : 8554198 : auto end2 = accesses2.end ();
1672 : :
1673 : 27067104 : while (i1 != end1 && i2 != end2)
1674 : : {
1675 : 10584196 : access_info *access1 = *i1;
1676 : 10584196 : access_info *access2 = *i2;
1677 : :
1678 : 10584196 : unsigned int regno1 = access1->regno ();
1679 : 10584196 : unsigned int regno2 = access2->regno ();
1680 : 10584196 : if (regno1 == regno2)
1681 : : return true;
1682 : :
1683 : 9958708 : if (regno1 < regno2)
1684 : 4875146 : ++i1;
1685 : : else
1686 : 5083562 : ++i2;
1687 : : }
1688 : : return false;
1689 : : }
1690 : :
1691 : : // See the comment above the declaration.
1692 : : bool
1693 : 8554198 : rtl_ssa::insn_clobbers_resources (insn_info *insn, access_array accesses)
1694 : : {
1695 : 8554198 : if (accesses_reference_same_resource (insn->defs (), accesses))
1696 : : return true;
1697 : :
1698 : 7928710 : if (insn->is_call () && accesses_include_hard_registers (accesses))
1699 : : {
1700 : 732 : function_abi abi = insn_callee_abi (insn->rtl ());
1701 : 769 : for (const access_info *access : accesses)
1702 : : {
1703 : 732 : if (!HARD_REGISTER_NUM_P (access->regno ()))
1704 : : break;
1705 : 732 : if (abi.clobbers_reg_p (access->mode (), access->regno ()))
1706 : 695 : return true;
1707 : : }
1708 : : }
1709 : :
1710 : : return false;
1711 : : }
1712 : :
1713 : : // Print RESOURCE to PP.
1714 : : void
1715 : 0 : rtl_ssa::pp_resource (pretty_printer *pp, resource_info resource)
1716 : : {
1717 : 0 : resource.print (pp);
1718 : 0 : }
1719 : :
1720 : : // Print ACCESS to PP. FLAGS is a bitmask of PP_ACCESS_* flags.
1721 : : void
1722 : 0 : rtl_ssa::pp_access (pretty_printer *pp, const access_info *access,
1723 : : unsigned int flags)
1724 : : {
1725 : 0 : if (!access)
1726 : 0 : pp_string (pp, "<null>");
1727 : 0 : else if (auto *phi = dyn_cast<const phi_info *> (access))
1728 : 0 : phi->print (pp, flags);
1729 : 0 : else if (auto *set = dyn_cast<const set_info *> (access))
1730 : 0 : set->print (pp, flags);
1731 : 0 : else if (auto *clobber = dyn_cast<const clobber_info *> (access))
1732 : 0 : clobber->print (pp, flags);
1733 : 0 : else if (auto *use = dyn_cast<const use_info *> (access))
1734 : 0 : use->print (pp, flags);
1735 : : else
1736 : : pp_string (pp, "??? Unknown access");
1737 : 0 : }
1738 : :
1739 : : // Print ACCESSES to PP. FLAGS is a bitmask of PP_ACCESS_* flags.
1740 : : void
1741 : 0 : rtl_ssa::pp_accesses (pretty_printer *pp, access_array accesses,
1742 : : unsigned int flags)
1743 : : {
1744 : 0 : if (accesses.empty ())
1745 : 0 : pp_string (pp, "none");
1746 : : else
1747 : : {
1748 : 0 : bool is_first = true;
1749 : 0 : for (access_info *access : accesses)
1750 : : {
1751 : 0 : if (is_first)
1752 : : is_first = false;
1753 : : else
1754 : 0 : pp_newline_and_indent (pp, 0);
1755 : 0 : pp_access (pp, access, flags);
1756 : : }
1757 : : }
1758 : 0 : }
1759 : :
1760 : : // Print NODE to PP.
1761 : : void
1762 : 0 : rtl_ssa::pp_def_node (pretty_printer *pp, const def_node *node)
1763 : : {
1764 : 0 : if (!node)
1765 : 0 : pp_string (pp, "<null>");
1766 : 0 : else if (auto *group = dyn_cast<const clobber_group *> (node))
1767 : 0 : group->print (pp);
1768 : 0 : else if (auto *set = dyn_cast<const set_node *> (node))
1769 : 0 : set->print (pp);
1770 : : else
1771 : 0 : pp_string (pp, "??? Unknown def node");
1772 : 0 : }
1773 : :
1774 : : // Print MUX to PP.
1775 : : void
1776 : 0 : rtl_ssa::pp_def_mux (pretty_printer *pp, def_mux mux)
1777 : : {
1778 : 0 : if (auto *node = mux.dyn_cast<def_node *> ())
1779 : 0 : pp_def_node (pp, node);
1780 : : else
1781 : 0 : pp_access (pp, mux.as_a<def_info *> ());
1782 : 0 : }
1783 : :
1784 : : // Print DL to PP.
1785 : : void
1786 : 0 : rtl_ssa::pp_def_lookup (pretty_printer *pp, def_lookup dl)
1787 : : {
1788 : 0 : pp_string (pp, "comparison result of ");
1789 : 0 : pp_decimal_int (pp, dl.comparison);
1790 : 0 : pp_string (pp, " for ");
1791 : 0 : pp_newline_and_indent (pp, 0);
1792 : 0 : pp_def_mux (pp, dl.mux);
1793 : 0 : }
1794 : :
1795 : : // Print TREE to PP.
1796 : : void
1797 : 0 : rtl_ssa::pp_def_splay_tree (pretty_printer *pp, def_splay_tree tree)
1798 : : {
1799 : 0 : tree.print (pp, pp_def_node);
1800 : 0 : }
1801 : :
1802 : : // Dump RESOURCE to FILE.
1803 : : void
1804 : 0 : dump (FILE *file, resource_info resource)
1805 : : {
1806 : 0 : dump_using (file, pp_resource, resource);
1807 : 0 : }
1808 : :
1809 : : // Dump ACCESS to FILE. FLAGS is a bitmask of PP_ACCESS_* flags.
1810 : : void
1811 : 0 : dump (FILE *file, const access_info *access, unsigned int flags)
1812 : : {
1813 : 0 : dump_using (file, pp_access, access, flags);
1814 : 0 : }
1815 : :
1816 : : // Dump ACCESSES to FILE. FLAGS is a bitmask of PP_ACCESS_* flags.
1817 : : void
1818 : 0 : dump (FILE *file, access_array accesses, unsigned int flags)
1819 : : {
1820 : 0 : dump_using (file, pp_accesses, accesses, flags);
1821 : 0 : }
1822 : :
1823 : : // Print NODE to FILE.
1824 : : void
1825 : 0 : dump (FILE *file, const def_node *node)
1826 : : {
1827 : 0 : dump_using (file, pp_def_node, node);
1828 : 0 : }
1829 : :
1830 : : // Print MUX to FILE.
1831 : : void
1832 : 0 : dump (FILE *file, def_mux mux)
1833 : : {
1834 : 0 : dump_using (file, pp_def_mux, mux);
1835 : 0 : }
1836 : :
1837 : : // Print RESULT to FILE.
1838 : : void
1839 : 0 : dump (FILE *file, def_lookup result)
1840 : : {
1841 : 0 : dump_using (file, pp_def_lookup, result);
1842 : 0 : }
1843 : :
1844 : : // Print TREE to FILE.
1845 : : void
1846 : 0 : dump (FILE *file, def_splay_tree tree)
1847 : : {
1848 : 0 : dump_using (file, pp_def_splay_tree, tree);
1849 : 0 : }
1850 : :
1851 : : // Debug interfaces to the dump routines above.
1852 : 0 : void debug (const resource_info &x) { dump (stderr, x); }
1853 : 0 : void debug (const access_info *x) { dump (stderr, x); }
1854 : 0 : void debug (const access_array &x) { dump (stderr, x); }
1855 : 0 : void debug (const def_node *x) { dump (stderr, x); }
1856 : 0 : void debug (const def_mux &x) { dump (stderr, x); }
1857 : 0 : void debug (const def_lookup &x) { dump (stderr, x); }
1858 : 0 : void debug (const def_splay_tree &x) { dump (stderr, x); }
|