1 // Implementation of access-related functions for RTL SSA -*- C++ -*-
2 // Copyright (C) 2020-2023 Free Software Foundation, Inc.
4 // This file is part of GCC.
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
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
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/>.
20 #define INCLUDE_ALGORITHM
21 #define INCLUDE_FUNCTIONAL
24 #include "coretypes.h"
29 #include "rtl-ssa/internals.h"
30 #include "rtl-ssa/internals.inl"
32 using namespace rtl_ssa
;
34 // This clobber belongs to a clobber_group but m_group appears to be
35 // out of date. Update it and return the new (correct) value.
37 clobber_info::recompute_group ()
39 using splay_tree
= clobber_info::splay_tree
;
41 // Splay this clobber to the root of the tree while searching for a node
42 // that has the correct group. The root always has the correct group,
43 // so the search always breaks early and does not install this clobber
45 clobber_info
*cursor
= m_parent
;
46 auto find_group
= [](clobber_info
*node
, unsigned int)
48 return node
->m_group
->has_been_superceded () ? nullptr : node
->m_group
;
50 clobber_group
*group
= splay_tree::splay_and_search (this, nullptr,
52 gcc_checking_assert (m_parent
);
54 // If the previous splay operation did anything, this clobber is now an
55 // ancestor of CURSOR, and all the nodes inbetween have a stale group.
56 // Since we have visited the nodes, we might as well update them too.
58 // If the previous splay operation did nothing, start the update from
59 // this clobber instead. In that case we change at most two clobbers:
60 // this clobber and possibly its parent.
61 if (cursor
== m_parent
)
64 // Walk up the tree from CURSOR updating clobbers that need it.
65 // This walk always includes this clobber.
66 while (cursor
->m_group
!= group
)
68 cursor
->m_group
= group
;
69 cursor
= cursor
->m_parent
;
72 gcc_checking_assert (m_group
== group
);
76 // See the comment above the declaration.
78 resource_info::print_identifier (pretty_printer
*pp
) const
81 pp_string (pp
, "mem");
84 char tmp
[3 * sizeof (regno
) + 2];
85 snprintf (tmp
, sizeof (tmp
), "r%d", regno
);
90 // See the comment above the declaration.
92 resource_info::print_context (pretty_printer
*pp
) const
94 if (HARD_REGISTER_NUM_P (regno
))
96 if (const char *name
= reg_names
[regno
])
100 pp_string (pp
, name
);
101 if (mode
!= E_BLKmode
)
104 pp_string (pp
, GET_MODE_NAME (mode
));
113 if (mode
!= E_BLKmode
)
115 pp_string (pp
, GET_MODE_NAME (mode
));
118 pp_string (pp
, "pseudo");
123 // See the comment above the declaration.
125 resource_info::print (pretty_printer
*pp
) const
127 print_identifier (pp
);
131 // Some properties can naturally be described using adjectives that attach
132 // to nouns like "use" or "definition". Print such adjectives to PP.
134 access_info::print_prefix_flags (pretty_printer
*pp
) const
137 pp_string (pp
, "temporary ");
138 if (m_has_been_superceded
)
139 pp_string (pp
, "superceded ");
142 // Print properties not handled by print_prefix_flags to PP, putting
143 // each property on a new line indented by two extra spaces.
145 access_info::print_properties_on_new_lines (pretty_printer
*pp
) const
147 if (m_is_pre_post_modify
)
149 pp_newline_and_indent (pp
, 2);
150 pp_string (pp
, "set by a pre/post-modify");
151 pp_indentation (pp
) -= 2;
153 if (m_includes_address_uses
)
155 pp_newline_and_indent (pp
, 2);
156 pp_string (pp
, "appears inside an address");
157 pp_indentation (pp
) -= 2;
159 if (m_includes_read_writes
)
161 pp_newline_and_indent (pp
, 2);
162 pp_string (pp
, "appears in a read/write context");
163 pp_indentation (pp
) -= 2;
165 if (m_includes_subregs
)
167 pp_newline_and_indent (pp
, 2);
168 pp_string (pp
, "appears inside a subreg");
169 pp_indentation (pp
) -= 2;
173 // Return true if there are no known issues with the integrity of the
176 use_info::check_integrity ()
178 auto subsequence_id
= [](use_info
*use
)
180 if (use
->is_in_nondebug_insn ())
182 if (use
->is_in_debug_insn ())
187 use_info
*prev
= prev_use ();
188 use_info
*next
= next_use ();
190 if (prev
&& subsequence_id (prev
) > subsequence_id (this))
192 if (next
&& subsequence_id (next
) < subsequence_id (this))
194 if (m_is_last_nondebug_insn_use
!= calculate_is_last_nondebug_insn_use ())
197 if (!prev
&& last_use ()->next_use ())
200 if (use_info
*use
= last_nondebug_insn_use ())
201 if (!use
->m_is_last_nondebug_insn_use
)
207 // See the comment above the declaration.
209 use_info::print_location (pretty_printer
*pp
) const
212 pp_access (pp
, phi (), PP_ACCESS_INCLUDE_LOCATION
);
214 insn ()->print_identifier_and_location (pp
);
217 // See the comment above the declaration.
219 use_info::print_def (pretty_printer
*pp
) const
221 if (const set_info
*set
= def ())
222 pp_access (pp
, set
, 0);
225 pp_string (pp
, "undefined ");
226 resource ().print (pp
);
230 // See the comment above the declaration.
232 use_info::print (pretty_printer
*pp
, unsigned int flags
) const
234 print_prefix_flags (pp
);
236 const set_info
*set
= def ();
237 if (set
&& set
->mode () != mode ())
239 pp_string (pp
, GET_MODE_NAME (mode ()));
243 pp_string (pp
, "use of ");
245 if (flags
& PP_ACCESS_INCLUDE_LOCATION
)
247 pp_string (pp
, " by ");
250 if (set
&& (flags
& PP_ACCESS_INCLUDE_LINKS
))
252 pp_newline_and_indent (pp
, 2);
253 pp_string (pp
, "defined in ");
254 set
->insn ()->print_location (pp
);
255 pp_indentation (pp
) -= 2;
257 if (flags
& PP_ACCESS_INCLUDE_PROPERTIES
)
258 print_properties_on_new_lines (pp
);
261 // See the comment above the declaration.
263 def_info::print_identifier (pretty_printer
*pp
) const
265 resource ().print_identifier (pp
);
267 insn ()->print_identifier (pp
);
268 resource ().print_context (pp
);
271 // See the comment above the declaration.
273 def_info::print_location (pretty_printer
*pp
) const
275 insn ()->print_identifier_and_location (pp
);
278 // See the comment above the declaration.
280 clobber_info::print (pretty_printer
*pp
, unsigned int flags
) const
282 print_prefix_flags (pp
);
283 if (is_call_clobber ())
284 pp_string (pp
, "call ");
285 pp_string (pp
, "clobber ");
286 print_identifier (pp
);
287 if (flags
& PP_ACCESS_INCLUDE_LOCATION
)
289 pp_string (pp
, " in ");
290 insn ()->print_location (pp
);
292 if (flags
& PP_ACCESS_INCLUDE_PROPERTIES
)
293 print_properties_on_new_lines (pp
);
296 // See the comment above the declaration.
298 set_info::print_uses_on_new_lines (pretty_printer
*pp
) const
300 for (const use_info
*use
: all_uses ())
302 pp_newline_and_indent (pp
, 2);
303 if (use
->is_live_out_use ())
305 pp_string (pp
, "live out from ");
306 use
->insn ()->print_location (pp
);
310 pp_string (pp
, "used by ");
311 use
->print_location (pp
);
313 pp_indentation (pp
) -= 2;
317 pp_newline_and_indent (pp
, 2);
318 pp_string (pp
, "splay tree:");
319 pp_newline_and_indent (pp
, 2);
320 auto print_use
= [](pretty_printer
*pp
,
321 splay_tree_node
<use_info
*> *node
)
323 pp_string (pp
, "use by ");
324 node
->value ()->print_location (pp
);
326 m_use_tree
.print (pp
, m_use_tree
.root (), print_use
);
327 pp_indentation (pp
) -= 4;
331 // See the comment above the declaration.
333 set_info::print (pretty_printer
*pp
, unsigned int flags
) const
335 print_prefix_flags (pp
);
336 pp_string (pp
, "set ");
337 print_identifier (pp
);
338 if (flags
& PP_ACCESS_INCLUDE_LOCATION
)
340 pp_string (pp
, " in ");
341 insn ()->print_location (pp
);
343 if (flags
& PP_ACCESS_INCLUDE_PROPERTIES
)
344 print_properties_on_new_lines (pp
);
345 if (flags
& PP_ACCESS_INCLUDE_LINKS
)
346 print_uses_on_new_lines (pp
);
349 // See the comment above the declaration.
351 phi_info::print (pretty_printer
*pp
, unsigned int flags
) const
353 print_prefix_flags (pp
);
354 pp_string (pp
, "phi node ");
355 print_identifier (pp
);
356 if (flags
& PP_ACCESS_INCLUDE_LOCATION
)
358 pp_string (pp
, " in ");
359 insn ()->print_location (pp
);
362 if (flags
& PP_ACCESS_INCLUDE_PROPERTIES
)
363 print_properties_on_new_lines (pp
);
365 if (flags
& PP_ACCESS_INCLUDE_LINKS
)
367 basic_block cfg_bb
= bb ()->cfg_bb ();
368 pp_newline_and_indent (pp
, 2);
369 pp_string (pp
, "inputs:");
371 for (const use_info
*input
: inputs ())
373 basic_block pred_cfg_bb
= EDGE_PRED (cfg_bb
, i
)->src
;
374 pp_newline_and_indent (pp
, 2);
375 pp_string (pp
, "bb");
376 pp_decimal_int (pp
, pred_cfg_bb
->index
);
379 input
->print_def (pp
);
380 pp_indentation (pp
) -= 2;
383 pp_indentation (pp
) -= 2;
385 print_uses_on_new_lines (pp
);
389 // See the comment above the declaration.
391 set_node::print (pretty_printer
*pp
) const
393 pp_access (pp
, first_def ());
396 // See the comment above the declaration.
398 clobber_group::prev_clobber (insn_info
*insn
) const
400 auto &tree
= const_cast<clobber_tree
&> (m_clobber_tree
);
401 int comparison
= lookup_clobber (tree
, insn
);
403 return dyn_cast
<clobber_info
*> (tree
.root ()->prev_def ());
407 // See the comment above the declaration.
409 clobber_group::next_clobber (insn_info
*insn
) const
411 auto &tree
= const_cast<clobber_tree
&> (m_clobber_tree
);
412 int comparison
= lookup_clobber (tree
, insn
);
414 return dyn_cast
<clobber_info
*> (tree
.root ()->next_def ());
418 // See the comment above the declaration.
420 clobber_group::print (pretty_printer
*pp
) const
422 auto print_clobber
= [](pretty_printer
*pp
, const def_info
*clobber
)
424 pp_access (pp
, clobber
);
426 pp_string (pp
, "grouped clobber");
427 for (const def_info
*clobber
: clobbers ())
429 pp_newline_and_indent (pp
, 2);
430 print_clobber (pp
, clobber
);
431 pp_indentation (pp
) -= 2;
433 pp_newline_and_indent (pp
, 2);
434 pp_string (pp
, "splay tree");
435 pp_newline_and_indent (pp
, 2);
436 m_clobber_tree
.print (pp
, print_clobber
);
437 pp_indentation (pp
) -= 4;
440 // See the comment above the declaration.
442 def_lookup::prev_def (insn_info
*insn
) const
444 if (mux
&& comparison
== 0)
445 if (auto *node
= mux
.dyn_cast
<def_node
*> ())
446 if (auto *group
= dyn_cast
<clobber_group
*> (node
))
447 if (clobber_info
*clobber
= group
->prev_clobber (insn
))
450 return last_def_of_prev_group ();
453 // See the comment above the declaration.
455 def_lookup::next_def (insn_info
*insn
) const
457 if (mux
&& comparison
== 0)
458 if (auto *node
= mux
.dyn_cast
<def_node
*> ())
459 if (auto *group
= dyn_cast
<clobber_group
*> (node
))
460 if (clobber_info
*clobber
= group
->next_clobber (insn
))
463 return first_def_of_next_group ();
466 // Return a clobber_group for CLOBBER, creating one if CLOBBER doesn't
467 // already belong to a group.
469 function_info::need_clobber_group (clobber_info
*clobber
)
471 if (clobber
->is_in_group ())
472 return clobber
->group ();
473 return allocate
<clobber_group
> (clobber
);
476 // Return a def_node for inserting DEF into the associated resource's
477 // splay tree. Use a clobber_group if DEF is a clobber and a set_node
480 function_info::need_def_node (def_info
*def
)
482 if (auto *clobber
= dyn_cast
<clobber_info
*> (def
))
483 return need_clobber_group (clobber
);
484 return allocate
<set_node
> (as_a
<set_info
*> (def
));
487 // LAST is the last thing to define LAST->resource (), and is where any
488 // splay tree root for LAST->resource () is stored. Require such a splay tree
489 // to exist, creating a new one if necessary. Return the root of the tree.
491 // The caller must call LAST->set_splay_root after it has finished with
494 function_info::need_def_splay_tree (def_info
*last
)
496 if (def_node
*root
= last
->splay_root ())
499 // Use a left-spine rooted at the last node.
500 def_node
*root
= need_def_node (last
);
501 def_node
*parent
= root
;
502 while (def_info
*prev
= first_def (parent
)->prev_def ())
504 def_node
*node
= need_def_node (prev
);
505 def_splay_tree::insert_child (parent
, 0, node
);
511 // Search TREE for either:
513 // - a set_info at INSN or
514 // - a clobber_group whose range includes INSN
516 // If such a node exists, install it as the root of TREE and return 0.
517 // Otherwise arbitrarily choose between:
519 // (1) Installing the closest preceding node as the root and returning 1.
520 // (2) Installing the closest following node as the root and returning -1.
522 // Note that this routine should not be used to check whether INSN
523 // itself defines a resource; that can be checked more cheaply using
524 // find_access_index.
526 rtl_ssa::lookup_def (def_splay_tree
&tree
, insn_info
*insn
)
528 auto go_left
= [&](def_node
*node
)
530 return *insn
< *first_def (node
)->insn ();
532 auto go_right
= [&](def_node
*node
)
534 return *insn
> *last_def (node
)->insn ();
536 return tree
.lookup (go_left
, go_right
);
539 // Search TREE for a clobber in INSN. If such a clobber exists, install
540 // it as the root of TREE and return 0. Otherwise arbitrarily choose between:
542 // (1) Installing the closest preceding clobber as the root and returning 1.
543 // (2) Installing the closest following clobber as the root and returning -1.
545 rtl_ssa::lookup_clobber (clobber_tree
&tree
, insn_info
*insn
)
547 auto compare
= [&](clobber_info
*clobber
)
549 return insn
->compare_with (clobber
->insn ());
551 return tree
.lookup (compare
);
554 // Search for a definition of RESOURCE at INSN and return the result of
555 // the search as a def_lookup. See the comment above the class for more
558 function_info::find_def (resource_info resource
, insn_info
*insn
)
560 def_info
*first
= m_defs
[resource
.regno
+ 1];
562 // There are no nodes. The comparison result is pretty meaningless
564 return { nullptr, -1 };
566 // See whether the first node matches.
567 auto first_result
= clobber_group_or_single_def (first
);
568 if (*insn
<= *last_def (first_result
)->insn ())
570 int comparison
= (*insn
>= *first
->insn () ? 0 : -1);
571 return { first_result
, comparison
};
574 // See whether the last node matches.
575 def_info
*last
= first
->last_def ();
576 auto last_result
= clobber_group_or_single_def (last
);
577 if (*insn
>= *first_def (last_result
)->insn ())
579 int comparison
= (*insn
<= *last
->insn () ? 0 : 1);
580 return { last_result
, comparison
};
583 // Resort to using a splay tree to search for the result.
584 def_splay_tree tree
= need_def_splay_tree (last
);
585 int comparison
= lookup_def (tree
, insn
);
586 last
->set_splay_root (tree
.root ());
587 return { tree
.root (), comparison
};
590 // Add DEF to the function's list of definitions of DEF->resource (),
591 // inserting DEF immediately before BEFORE. DEF is not currently in the list.
593 function_info::insert_def_before (def_info
*def
, def_info
*before
)
595 gcc_checking_assert (!def
->has_def_links ()
596 && *before
->insn () > *def
->insn ());
598 def
->copy_prev_from (before
);
599 if (def_info
*prev
= def
->prev_def ())
601 gcc_checking_assert (*prev
->insn () < *def
->insn ());
602 prev
->set_next_def (def
);
605 m_defs
[def
->regno () + 1] = def
;
607 def
->set_next_def (before
);
608 before
->set_prev_def (def
);
611 // Add DEF to the function's list of definitions of DEF->resource (),
612 // inserting DEF immediately after AFTER. DEF is not currently in the list.
614 function_info::insert_def_after (def_info
*def
, def_info
*after
)
616 gcc_checking_assert (!def
->has_def_links ()
617 && *after
->insn () < *def
->insn ());
619 def
->copy_next_from (after
);
620 if (def_info
*next
= def
->next_def ())
622 gcc_checking_assert (*next
->insn () > *def
->insn ());
623 next
->set_prev_def (def
);
626 m_defs
[def
->regno () + 1]->set_last_def (def
);
628 def
->set_prev_def (after
);
629 after
->set_next_def (def
);
632 // Remove DEF from the function's list of definitions of DEF->resource ().
634 function_info::remove_def_from_list (def_info
*def
)
636 def_info
*prev
= def
->prev_def ();
637 def_info
*next
= def
->next_def ();
640 next
->copy_prev_from (def
);
642 m_defs
[def
->regno () + 1]->set_last_def (prev
);
645 prev
->copy_next_from (def
);
647 m_defs
[def
->regno () + 1] = next
;
649 def
->clear_def_links ();
652 // Add CLOBBER to GROUP and insert it into the function's list of
653 // accesses to CLOBBER->resource (). CLOBBER is not currently part
654 // of an active group and is not currently in the list.
656 function_info::add_clobber (clobber_info
*clobber
, clobber_group
*group
)
658 // Search for either the previous or next clobber in the group.
659 // The result is less than zero if CLOBBER should come before NEIGHBOR
660 // or greater than zero if CLOBBER should come after NEIGHBOR.
661 int comparison
= lookup_clobber (group
->m_clobber_tree
, clobber
->insn ());
662 gcc_checking_assert (comparison
!= 0);
663 clobber_info
*neighbor
= group
->m_clobber_tree
.root ();
665 // Since HEIGHBOR is now the root of the splay tree, its group needs
667 neighbor
->update_group (group
);
669 // If CLOBBER comes before NEIGHBOR, insert CLOBBER to NEIGHBOR's left,
670 // otherwise insert CLOBBER to NEIGHBOR's right.
671 clobber_info::splay_tree::insert_child (neighbor
, comparison
> 0, clobber
);
672 clobber
->set_group (group
);
674 // Insert the clobber into the function-wide list and update the
675 // bounds of the group.
678 insert_def_after (clobber
, neighbor
);
679 if (neighbor
== group
->last_clobber ())
680 group
->set_last_clobber (clobber
);
684 insert_def_before (clobber
, neighbor
);
685 if (neighbor
== group
->first_clobber ())
686 group
->set_first_clobber (clobber
);
690 // Remove CLOBBER from GROUP, given that GROUP contains other clobbers too.
691 // Also remove CLOBBER from the function's list of accesses to
692 // CLOBBER->resource ().
694 function_info::remove_clobber (clobber_info
*clobber
, clobber_group
*group
)
696 if (clobber
== group
->first_clobber ())
698 auto *new_first
= as_a
<clobber_info
*> (clobber
->next_def ());
699 group
->set_first_clobber (new_first
);
700 new_first
->update_group (group
);
702 else if (clobber
== group
->last_clobber ())
704 auto *new_last
= as_a
<clobber_info
*> (clobber
->prev_def ());
705 group
->set_last_clobber (new_last
);
706 new_last
->update_group (group
);
709 clobber_info
*replacement
= clobber_info::splay_tree::remove_node (clobber
);
710 if (clobber
== group
->m_clobber_tree
.root ())
712 group
->m_clobber_tree
= replacement
;
713 replacement
->update_group (group
);
715 clobber
->set_group (nullptr);
717 remove_def_from_list (clobber
);
720 // Add CLOBBER immediately before the first clobber in GROUP, given that
721 // CLOBBER is not currently part of any group.
723 function_info::prepend_clobber_to_group (clobber_info
*clobber
,
724 clobber_group
*group
)
726 clobber_info
*next
= group
->first_clobber ();
727 clobber_info::splay_tree::insert_child (next
, 0, clobber
);
728 group
->set_first_clobber (clobber
);
729 clobber
->set_group (group
);
732 // Add CLOBBER immediately after the last clobber in GROUP, given that
733 // CLOBBER is not currently part of any group.
735 function_info::append_clobber_to_group (clobber_info
*clobber
,
736 clobber_group
*group
)
738 clobber_info
*prev
= group
->last_clobber ();
739 clobber_info::splay_tree::insert_child (prev
, 1, clobber
);
740 group
->set_last_clobber (clobber
);
741 clobber
->set_group (group
);
744 // Put CLOBBER1 and CLOBBER2 into the same clobber_group, given that
745 // CLOBBER1 occurs immediately before CLOBBER2 and that the two clobbers
746 // are not currently in the same group. LAST is the last definition of
747 // the associated resource, and is where any splay tree is stored.
749 function_info::merge_clobber_groups (clobber_info
*clobber1
,
750 clobber_info
*clobber2
,
753 if (clobber1
->is_in_group () && clobber2
->is_in_group ())
755 clobber_group
*group1
= clobber1
->group ();
756 clobber_group
*group2
= clobber2
->group ();
757 gcc_checking_assert (clobber1
== group1
->last_clobber ()
758 && clobber2
== group2
->first_clobber ());
760 if (def_splay_tree tree
= last
->splay_root ())
762 // Remove GROUP2 from the splay tree.
763 int comparison
= lookup_def (tree
, clobber2
->insn ());
764 gcc_checking_assert (comparison
== 0);
766 last
->set_splay_root (tree
.root ());
769 // Splice the trees together.
770 group1
->m_clobber_tree
.splice_next_tree (group2
->m_clobber_tree
);
772 // Bring the two extremes of GROUP2 under GROUP1. Any other
773 // clobbers in the group are updated lazily on demand.
774 clobber2
->set_group (group1
);
775 group2
->last_clobber ()->set_group (group1
);
776 group1
->set_last_clobber (group2
->last_clobber ());
778 // Record that GROUP2 is no more.
779 group2
->set_first_clobber (nullptr);
780 group2
->set_last_clobber (nullptr);
781 group2
->m_clobber_tree
= nullptr;
785 // In this case there can be no active splay tree.
786 gcc_assert (!last
->splay_root ());
787 if (clobber2
->is_in_group ())
788 prepend_clobber_to_group (clobber1
, clobber2
->group ());
790 append_clobber_to_group (clobber2
, need_clobber_group (clobber1
));
794 // GROUP spans INSN, and INSN now sets the resource that GROUP clobbers.
795 // Split GROUP around INSN and return the clobber that comes immediately
798 // The resource that GROUP clobbers is known to have an associated
801 function_info::split_clobber_group (clobber_group
*group
, insn_info
*insn
)
803 // Search for either the previous or next clobber in the group.
804 // The result is less than zero if CLOBBER should come before NEIGHBOR
805 // or greater than zero if CLOBBER should come after NEIGHBOR.
806 clobber_tree
&tree1
= group
->m_clobber_tree
;
807 int comparison
= lookup_clobber (tree1
, insn
);
808 gcc_checking_assert (comparison
!= 0);
809 clobber_info
*neighbor
= tree1
.root ();
816 // NEIGHBOR is the last clobber in what will become the first group.
817 tree2
= tree1
.split_after_root ();
819 next
= as_a
<clobber_info
*> (prev
->next_def ());
823 // NEIGHBOR is the first clobber in what will become the second group.
825 tree1
= tree2
.split_before_root ();
827 prev
= as_a
<clobber_info
*> (next
->prev_def ());
830 // Use GROUP to hold PREV and earlier clobbers. Create a new group for
832 clobber_info
*last_clobber
= group
->last_clobber ();
833 clobber_group
*group1
= group
;
834 clobber_group
*group2
= allocate
<clobber_group
> (next
);
836 // Finish setting up GROUP1, making sure that the roots and extremities
837 // have a correct group pointer. Leave the rest to be updated lazily.
838 group1
->set_last_clobber (prev
);
839 tree1
->set_group (group1
);
840 prev
->set_group (group1
);
842 // Finish setting up GROUP2, with the same approach as for GROUP1.
843 group2
->set_first_clobber (next
);
844 group2
->set_last_clobber (last_clobber
);
845 next
->set_group (group2
);
846 tree2
->set_group (group2
);
847 last_clobber
->set_group (group2
);
849 // Insert GROUP2 into the splay tree as an immediate successor of GROUP1.
850 def_splay_tree::insert_child (group1
, 1, group2
);
855 // Add DEF to the end of the function's list of definitions of
856 // DEF->resource (). There is known to be no associated splay tree yet.
858 function_info::append_def (def_info
*def
)
860 gcc_checking_assert (!def
->has_def_links ());
861 def_info
**head
= &m_defs
[def
->regno () + 1];
862 def_info
*first
= *head
;
865 // This is the only definition of the resource.
866 def
->set_last_def (def
);
871 def_info
*prev
= first
->last_def ();
872 gcc_checking_assert (!prev
->splay_root ());
874 // Maintain the invariant that two clobbers must not appear in
875 // neighboring nodes of the splay tree.
876 auto *clobber
= dyn_cast
<clobber_info
*> (def
);
877 auto *prev_clobber
= dyn_cast
<clobber_info
*> (prev
);
878 if (clobber
&& prev_clobber
)
879 append_clobber_to_group (clobber
, need_clobber_group (prev_clobber
));
881 prev
->set_next_def (def
);
882 def
->set_prev_def (prev
);
883 first
->set_last_def (def
);
886 // Add DEF to the function's list of definitions of DEF->resource ().
887 // Also insert it into the associated splay tree, if there is one.
888 // DEF is not currently part of the list and is not in the splay tree.
890 function_info::add_def (def_info
*def
)
892 gcc_checking_assert (!def
->has_def_links ()
894 && !def
->m_has_been_superceded
);
895 def_info
**head
= &m_defs
[def
->regno () + 1];
896 def_info
*first
= *head
;
899 // This is the only definition of the resource.
900 def
->set_last_def (def
);
905 def_info
*last
= first
->last_def ();
906 insn_info
*insn
= def
->insn ();
909 def_node
*root
= nullptr;
910 def_info
*prev
= nullptr;
911 def_info
*next
= nullptr;
912 if (*insn
> *last
->insn ())
914 // This definition comes after all other definitions.
916 if (def_splay_tree tree
= last
->splay_root ())
918 tree
.splay_max_node ();
920 last
->set_splay_root (root
);
924 else if (*insn
< *first
->insn ())
926 // This definition comes before all other definitions.
928 if (def_splay_tree tree
= last
->splay_root ())
930 tree
.splay_min_node ();
932 last
->set_splay_root (root
);
938 // Search the splay tree for an insertion point.
939 def_splay_tree tree
= need_def_splay_tree (last
);
940 comparison
= lookup_def (tree
, insn
);
942 last
->set_splay_root (root
);
944 // Deal with cases in which we found an overlapping live range.
947 auto *group
= as_a
<clobber_group
*> (tree
.root ());
948 if (auto *clobber
= dyn_cast
<clobber_info
*> (def
))
950 add_clobber (clobber
, group
);
953 prev
= split_clobber_group (group
, insn
);
954 next
= prev
->next_def ();
956 // COMPARISON is < 0 if DEF comes before ROOT or > 0 if DEF comes
958 else if (comparison
< 0)
960 next
= first_def (root
);
961 prev
= next
->prev_def ();
965 prev
= last_def (root
);
966 next
= prev
->next_def ();
970 // See if we should merge CLOBBER with a neighboring clobber.
971 auto *clobber
= dyn_cast
<clobber_info
*> (def
);
972 auto *prev_clobber
= safe_dyn_cast
<clobber_info
*> (prev
);
973 auto *next_clobber
= safe_dyn_cast
<clobber_info
*> (next
);
974 // We shouldn't have consecutive clobber_groups.
975 gcc_checking_assert (!(clobber
&& prev_clobber
&& next_clobber
));
976 if (clobber
&& prev_clobber
)
977 append_clobber_to_group (clobber
, need_clobber_group (prev_clobber
));
978 else if (clobber
&& next_clobber
)
979 prepend_clobber_to_group (clobber
, need_clobber_group (next_clobber
));
982 // If DEF comes before ROOT, insert DEF to ROOT's left,
983 // otherwise insert DEF to ROOT's right.
984 def_node
*node
= need_def_node (def
);
985 def_splay_tree::insert_child (root
, comparison
>= 0, node
);
988 insert_def_after (def
, prev
);
990 insert_def_before (def
, next
);
993 // Remove DEF from the function's list of definitions of DEF->resource ().
994 // Also remove DEF from the associated splay tree, if there is one.
996 function_info::remove_def (def_info
*def
)
998 def_info
**head
= &m_defs
[def
->regno () + 1];
999 def_info
*first
= *head
;
1000 gcc_checking_assert (first
);
1001 if (first
->is_last_def ())
1003 // DEF is the only definition of the resource.
1004 gcc_checking_assert (first
== def
);
1006 def
->clear_def_links ();
1010 // If CLOBBER belongs to a clobber_group that contains other clobbers
1011 // too, then we need to update the clobber_group and the list, but any
1012 // splay tree that contains the clobber_group is unaffected.
1013 if (auto *clobber
= dyn_cast
<clobber_info
*> (def
))
1014 if (clobber
->is_in_group ())
1016 clobber_group
*group
= clobber
->group ();
1017 if (group
->first_clobber () != group
->last_clobber ())
1019 remove_clobber (clobber
, group
);
1024 // If we've created a splay tree for this resource, remove the entry
1026 def_info
*last
= first
->last_def ();
1027 if (def_splay_tree tree
= last
->splay_root ())
1029 int comparison
= lookup_def (tree
, def
->insn ());
1030 gcc_checking_assert (comparison
== 0);
1031 tree
.remove_root ();
1032 last
->set_splay_root (tree
.root ());
1035 // If the definition came between two clobbers, merge them into a single
1037 auto *prev_clobber
= safe_dyn_cast
<clobber_info
*> (def
->prev_def ());
1038 auto *next_clobber
= safe_dyn_cast
<clobber_info
*> (def
->next_def ());
1039 if (prev_clobber
&& next_clobber
)
1040 merge_clobber_groups (prev_clobber
, next_clobber
, last
);
1042 remove_def_from_list (def
);
1045 // Require DEF to have a splay tree that contains all non-phi uses.
1047 function_info::need_use_splay_tree (set_info
*def
)
1049 if (!def
->m_use_tree
)
1050 for (use_info
*use
: def
->all_insn_uses ())
1052 auto *use_node
= allocate
<splay_tree_node
<use_info
*>> (use
);
1053 def
->m_use_tree
.insert_max_node (use_node
);
1057 // Compare two instructions by their position in a use splay tree. Return >0
1058 // if INSN1 comes after INSN2, <0 if INSN1 comes before INSN2, or 0 if they are
1059 // the same instruction.
1061 compare_use_insns (insn_info
*insn1
, insn_info
*insn2
)
1063 // Debug instructions go after nondebug instructions.
1064 int diff
= insn1
->is_debug_insn () - insn2
->is_debug_insn ();
1067 return insn1
->compare_with (insn2
);
1070 // Search TREE for a use in INSN. If such a use exists, install it as
1071 // the root of TREE and return 0. Otherwise arbitrarily choose between:
1073 // (1) Installing the closest preceding use as the root and returning 1.
1074 // (2) Installing the closest following use as the root and returning -1.
1076 rtl_ssa::lookup_use (splay_tree
<use_info
*> &tree
, insn_info
*insn
)
1078 auto compare
= [&](splay_tree_node
<use_info
*> *node
)
1080 return compare_use_insns (insn
, node
->value ()->insn ());
1082 return tree
.lookup (compare
);
1085 // Add USE to USE->def ()'s list of uses. inserting USE immediately before
1086 // BEFORE. USE is not currently in the list.
1088 // This routine should not be used for inserting phi uses.
1090 function_info::insert_use_before (use_info
*use
, use_info
*before
)
1092 gcc_checking_assert (!use
->has_use_links () && use
->is_in_any_insn ());
1094 set_info
*def
= use
->def ();
1096 use
->copy_prev_from (before
);
1097 use
->set_next_use (before
);
1099 if (use_info
*prev
= use
->prev_use ())
1100 prev
->set_next_use (use
);
1102 use
->def ()->set_first_use (use
);
1104 before
->set_prev_use (use
);
1105 if (use
->is_in_nondebug_insn () && before
->is_in_debug_insn_or_phi ())
1106 def
->last_use ()->set_last_nondebug_insn_use (use
);
1108 gcc_checking_assert (use
->check_integrity () && before
->check_integrity ());
1111 // Add USE to USE->def ()'s list of uses. inserting USE immediately after
1112 // AFTER. USE is not currently in the list.
1114 // This routine should not be used for inserting phi uses.
1116 function_info::insert_use_after (use_info
*use
, use_info
*after
)
1118 set_info
*def
= use
->def ();
1119 gcc_checking_assert (after
->is_in_any_insn ()
1120 && !use
->has_use_links ()
1121 && use
->is_in_any_insn ());
1123 use
->set_prev_use (after
);
1124 use
->copy_next_from (after
);
1126 after
->set_next_use (use
);
1128 if (use_info
*next
= use
->next_use ())
1130 // The last node doesn't change, but we might need to update its
1131 // last_nondebug_insn_use record.
1132 if (use
->is_in_nondebug_insn () && next
->is_in_debug_insn_or_phi ())
1133 def
->last_use ()->set_last_nondebug_insn_use (use
);
1134 next
->set_prev_use (use
);
1138 // USE is now the last node.
1139 if (use
->is_in_nondebug_insn ())
1140 use
->set_last_nondebug_insn_use (use
);
1141 def
->first_use ()->set_last_use (use
);
1144 gcc_checking_assert (use
->check_integrity () && after
->check_integrity ());
1147 // If USE has a known definition, add USE to that definition's list of uses.
1148 // Also update the associated splay tree, if any.
1150 function_info::add_use (use_info
*use
)
1152 gcc_checking_assert (!use
->has_use_links ()
1154 && !use
->m_has_been_superceded
);
1156 set_info
*def
= use
->def ();
1160 use_info
*first
= def
->first_use ();
1163 // This is the only use of the definition.
1164 use
->set_last_use (use
);
1165 if (use
->is_in_nondebug_insn ())
1166 use
->set_last_nondebug_insn_use (use
);
1168 def
->set_first_use (use
);
1170 gcc_checking_assert (use
->check_integrity ());
1174 if (use
->is_in_phi ())
1176 // Add USE at the end of the list, as the new first phi.
1177 use_info
*last
= first
->last_use ();
1179 use
->set_prev_use (last
);
1180 use
->copy_next_from (last
);
1182 last
->set_next_use (use
);
1183 first
->set_last_use (use
);
1185 gcc_checking_assert (use
->check_integrity ());
1189 // If there is currently no splay tree for this definition, see if can
1190 // get away with a pure list-based update.
1191 insn_info
*insn
= use
->insn ();
1192 auto quick_path
= [&]()
1194 // Check if USE should come before all current uses.
1195 if (first
->is_in_phi () || compare_use_insns (insn
, first
->insn ()) < 0)
1197 insert_use_before (use
, first
);
1201 // Check if USE should come after all current uses in the same
1202 // subsequence (i.e. the list of nondebug insn uses or the list
1203 // of debug insn uses).
1204 use_info
*last
= first
->last_use ();
1205 if (use
->is_in_debug_insn ())
1207 if (last
->is_in_phi ())
1211 last
= last
->last_nondebug_insn_use ();
1213 if (compare_use_insns (insn
, last
->insn ()) > 0)
1215 insert_use_after (use
, last
);
1221 if (!def
->m_use_tree
&& quick_path ())
1224 // Search the splay tree for an insertion point. COMPARISON is less
1225 // than zero if USE should come before NEIGHBOR, or greater than zero
1226 // if USE should come after NEIGHBOR.
1227 need_use_splay_tree (def
);
1228 int comparison
= lookup_use (def
->m_use_tree
, insn
);
1229 gcc_checking_assert (comparison
!= 0);
1230 splay_tree_node
<use_info
*> *neighbor
= def
->m_use_tree
.root ();
1232 // If USE comes before NEIGHBOR, insert USE to NEIGHBOR's left,
1233 // otherwise insert USE to NEIGHBOR's right.
1234 auto *use_node
= allocate
<splay_tree_node
<use_info
*>> (use
);
1235 def
->m_use_tree
.insert_child (neighbor
, comparison
> 0, use_node
);
1237 insert_use_after (use
, neighbor
->value ());
1239 insert_use_before (use
, neighbor
->value ());
1242 // If USE has a known definition, remove USE from that definition's list
1243 // of uses. Also remove if it from the associated splay tree, if any.
1245 function_info::remove_use (use_info
*use
)
1247 set_info
*def
= use
->def ();
1251 // Remove USE from the splay tree.
1252 if (def
->m_use_tree
&& use
->is_in_any_insn ())
1254 int comparison
= lookup_use (def
->m_use_tree
, use
->insn ());
1255 gcc_checking_assert (comparison
== 0);
1256 def
->m_use_tree
.remove_root ();
1259 use_info
*prev
= use
->prev_use ();
1260 use_info
*next
= use
->next_use ();
1262 use_info
*first
= def
->first_use ();
1263 use_info
*last
= first
->last_use ();
1264 if (last
->last_nondebug_insn_use () == use
)
1265 last
->set_last_nondebug_insn_use (prev
);
1268 next
->copy_prev_from (use
);
1270 first
->set_last_use (prev
);
1273 prev
->copy_next_from (use
);
1275 def
->set_first_use (next
);
1277 use
->clear_use_links ();
1278 gcc_checking_assert ((!prev
|| prev
->check_integrity ())
1279 && (!next
|| next
->check_integrity ()));
1282 // Allocate a temporary clobber_info for register REGNO in insn INSN,
1283 // including it in the region of the obstack governed by WATERMARK.
1284 // Return a new def_array that contains OLD_DEFS and the new clobber.
1286 // OLD_DEFS is known not to define REGNO.
1288 function_info::insert_temp_clobber (obstack_watermark
&watermark
,
1289 insn_info
*insn
, unsigned int regno
,
1292 gcc_checking_assert (watermark
== &m_temp_obstack
);
1293 auto *clobber
= allocate_temp
<clobber_info
> (insn
, regno
);
1294 clobber
->m_is_temp
= true;
1295 return insert_access (watermark
, clobber
, old_defs
);
1298 // A subroutine of make_uses_available. Try to make USE's definition
1299 // available at the head of BB. WILL_BE_DEBUG_USE is true if the
1300 // definition will be used only in debug instructions.
1304 // - If the use would have the same def () as USE, return USE.
1306 // - If BB already has a degenerate phi for the same definition,
1307 // return a temporary use of that phi.
1309 // - Otherwise, the use would need a new degenerate phi. Allocate a
1310 // temporary phi and return a temporary use of it.
1312 // Return null on failure.
1314 function_info::make_use_available (use_info
*use
, bb_info
*bb
,
1315 bool will_be_debug_use
)
1317 set_info
*def
= use
->def ();
1321 if (is_single_dominating_def (def
))
1324 // FIXME: Deliberately limited for fwprop compatibility testing.
1325 basic_block cfg_bb
= bb
->cfg_bb ();
1326 bb_info
*use_bb
= use
->bb ();
1327 if (single_pred_p (cfg_bb
)
1328 && single_pred (cfg_bb
) == use_bb
->cfg_bb ()
1329 && remains_available_on_exit (def
, use_bb
))
1331 if (def
->ebb () == bb
->ebb () || will_be_debug_use
)
1334 resource_info resource
= use
->resource ();
1335 set_info
*ultimate_def
= look_through_degenerate_phi (def
);
1337 // See if there is already a (degenerate) phi for DEF.
1338 insn_info
*phi_insn
= bb
->ebb ()->phi_insn ();
1340 def_lookup dl
= find_def (resource
, phi_insn
);
1341 if (set_info
*set
= dl
.matching_set ())
1343 // There is an existing phi.
1344 phi
= as_a
<phi_info
*> (set
);
1345 gcc_checking_assert (phi
->input_value (0) == ultimate_def
);
1349 // Create a temporary placeholder phi. This will become
1350 // permanent if the change is later committed.
1351 phi
= allocate_temp
<phi_info
> (phi_insn
, resource
, 0);
1352 auto *input
= allocate_temp
<use_info
> (phi
, resource
, ultimate_def
);
1353 input
->m_is_temp
= true;
1354 phi
->m_is_temp
= true;
1355 phi
->make_degenerate (input
);
1356 if (def_info
*prev
= dl
.prev_def (phi_insn
))
1357 phi
->set_prev_def (prev
);
1358 if (def_info
*next
= dl
.next_def (phi_insn
))
1359 phi
->set_next_def (next
);
1362 // Create a temporary use of the phi at the head of the first
1363 // block, since we know for sure that it's available there.
1364 insn_info
*use_insn
= bb
->ebb ()->first_bb ()->head_insn ();
1365 auto *new_use
= allocate_temp
<use_info
> (use_insn
, resource
, phi
);
1366 new_use
->m_is_temp
= true;
1372 // See the comment above the declaration.
1374 function_info::make_uses_available (obstack_watermark
&watermark
,
1375 use_array uses
, bb_info
*bb
,
1376 bool will_be_debug_uses
)
1378 unsigned int num_uses
= uses
.size ();
1382 auto **new_uses
= XOBNEWVEC (watermark
, access_info
*, num_uses
);
1383 for (unsigned int i
= 0; i
< num_uses
; ++i
)
1385 use_info
*use
= make_use_available (uses
[i
], bb
, will_be_debug_uses
);
1387 return use_array (access_array::invalid ());
1390 return use_array (new_uses
, num_uses
);
1393 // Return true if ACCESS1 can represent ACCESS2 and if ACCESS2 can
1394 // represent ACCESS1.
1396 can_merge_accesses (access_info
*access1
, access_info
*access2
)
1398 if (access1
== access2
)
1401 auto *use1
= dyn_cast
<use_info
*> (access1
);
1402 auto *use2
= dyn_cast
<use_info
*> (access2
);
1403 return use1
&& use2
&& use1
->def () == use2
->def ();
1406 // See the comment above the declaration.
1408 rtl_ssa::merge_access_arrays_base (obstack_watermark
&watermark
,
1409 access_array accesses1
,
1410 access_array accesses2
)
1412 if (accesses1
.empty ())
1414 if (accesses2
.empty ())
1417 auto i1
= accesses1
.begin ();
1418 auto end1
= accesses1
.end ();
1419 auto i2
= accesses2
.begin ();
1420 auto end2
= accesses2
.end ();
1422 access_array_builder
builder (watermark
);
1423 builder
.reserve (accesses1
.size () + accesses2
.size ());
1425 while (i1
!= end1
&& i2
!= end2
)
1427 access_info
*access1
= *i1
;
1428 access_info
*access2
= *i2
;
1430 unsigned int regno1
= access1
->regno ();
1431 unsigned int regno2
= access2
->regno ();
1432 if (regno1
== regno2
)
1434 if (!can_merge_accesses (access1
, access2
))
1435 return access_array::invalid ();
1437 builder
.quick_push (access1
);
1441 else if (regno1
< regno2
)
1443 builder
.quick_push (access1
);
1448 builder
.quick_push (access2
);
1452 for (; i1
!= end1
; ++i1
)
1453 builder
.quick_push (*i1
);
1454 for (; i2
!= end2
; ++i2
)
1455 builder
.quick_push (*i2
);
1457 return builder
.finish ();
1460 // See the comment above the declaration.
1462 rtl_ssa::insert_access_base (obstack_watermark
&watermark
,
1463 access_info
*access1
, access_array accesses2
)
1465 access_array_builder
builder (watermark
);
1466 builder
.reserve (1 + accesses2
.size ());
1468 unsigned int regno1
= access1
->regno ();
1469 auto i2
= accesses2
.begin ();
1470 auto end2
= accesses2
.end ();
1473 access_info
*access2
= *i2
;
1475 unsigned int regno2
= access2
->regno ();
1476 if (regno1
== regno2
)
1478 if (!can_merge_accesses (access1
, access2
))
1479 return access_array::invalid ();
1481 builder
.quick_push (access1
);
1486 else if (regno1
< regno2
)
1488 builder
.quick_push (access1
);
1494 builder
.quick_push (access2
);
1499 builder
.quick_push (access1
);
1500 for (; i2
!= end2
; ++i2
)
1501 builder
.quick_push (*i2
);
1503 return builder
.finish ();
1506 // See the comment above the declaration.
1508 rtl_ssa::remove_note_accesses_base (obstack_watermark
&watermark
,
1509 access_array accesses
)
1511 for (access_info
*access
: accesses
)
1512 if (access
->only_occurs_in_notes ())
1514 access_array_builder
builder (watermark
);
1515 builder
.reserve (accesses
.size ());
1516 for (access_info
*access2
: accesses
)
1517 if (!access2
->only_occurs_in_notes ())
1518 builder
.quick_push (access2
);
1519 return builder
.finish ();
1524 // Print RESOURCE to PP.
1526 rtl_ssa::pp_resource (pretty_printer
*pp
, resource_info resource
)
1528 resource
.print (pp
);
1531 // Print ACCESS to PP. FLAGS is a bitmask of PP_ACCESS_* flags.
1533 rtl_ssa::pp_access (pretty_printer
*pp
, const access_info
*access
,
1537 pp_string (pp
, "<null>");
1538 else if (auto *phi
= dyn_cast
<const phi_info
*> (access
))
1539 phi
->print (pp
, flags
);
1540 else if (auto *set
= dyn_cast
<const set_info
*> (access
))
1541 set
->print (pp
, flags
);
1542 else if (auto *clobber
= dyn_cast
<const clobber_info
*> (access
))
1543 clobber
->print (pp
, flags
);
1544 else if (auto *use
= dyn_cast
<const use_info
*> (access
))
1545 use
->print (pp
, flags
);
1547 pp_string (pp
, "??? Unknown access");
1550 // Print ACCESSES to PP. FLAGS is a bitmask of PP_ACCESS_* flags.
1552 rtl_ssa::pp_accesses (pretty_printer
*pp
, access_array accesses
,
1555 if (accesses
.empty ())
1556 pp_string (pp
, "none");
1559 bool is_first
= true;
1560 for (access_info
*access
: accesses
)
1565 pp_newline_and_indent (pp
, 0);
1566 pp_access (pp
, access
, flags
);
1571 // Print NODE to PP.
1573 rtl_ssa::pp_def_node (pretty_printer
*pp
, const def_node
*node
)
1576 pp_string (pp
, "<null>");
1577 else if (auto *group
= dyn_cast
<const clobber_group
*> (node
))
1579 else if (auto *set
= dyn_cast
<const set_node
*> (node
))
1582 pp_string (pp
, "??? Unknown def node");
1587 rtl_ssa::pp_def_mux (pretty_printer
*pp
, def_mux mux
)
1589 if (auto *node
= mux
.dyn_cast
<def_node
*> ())
1590 pp_def_node (pp
, node
);
1592 pp_access (pp
, mux
.as_a
<def_info
*> ());
1597 rtl_ssa::pp_def_lookup (pretty_printer
*pp
, def_lookup dl
)
1599 pp_string (pp
, "comparison result of ");
1600 pp_decimal_int (pp
, dl
.comparison
);
1601 pp_string (pp
, " for ");
1602 pp_newline_and_indent (pp
, 0);
1603 pp_def_mux (pp
, dl
.mux
);
1606 // Dump RESOURCE to FILE.
1608 dump (FILE *file
, resource_info resource
)
1610 dump_using (file
, pp_resource
, resource
);
1613 // Dump ACCESS to FILE. FLAGS is a bitmask of PP_ACCESS_* flags.
1615 dump (FILE *file
, const access_info
*access
, unsigned int flags
)
1617 dump_using (file
, pp_access
, access
, flags
);
1620 // Dump ACCESSES to FILE. FLAGS is a bitmask of PP_ACCESS_* flags.
1622 dump (FILE *file
, access_array accesses
, unsigned int flags
)
1624 dump_using (file
, pp_accesses
, accesses
, flags
);
1627 // Print NODE to FILE.
1629 dump (FILE *file
, const def_node
*node
)
1631 dump_using (file
, pp_def_node
, node
);
1634 // Print MUX to FILE.
1636 dump (FILE *file
, def_mux mux
)
1638 dump_using (file
, pp_def_mux
, mux
);
1641 // Print RESULT to FILE.
1643 dump (FILE *file
, def_lookup result
)
1645 dump_using (file
, pp_def_lookup
, result
);
1648 // Debug interfaces to the dump routines above.
1649 void debug (const resource_info
&x
) { dump (stderr
, x
); }
1650 void debug (const access_info
*x
) { dump (stderr
, x
); }
1651 void debug (const access_array
&x
) { dump (stderr
, x
); }
1652 void debug (const def_node
*x
) { dump (stderr
, x
); }
1653 void debug (const def_mux
&x
) { dump (stderr
, x
); }
1654 void debug (const def_lookup
&x
) { dump (stderr
, x
); }