Branch data Line data Source code
1 : : /* Interprocedural reference lists.
2 : : Copyright (C) 2010-2025 Free Software Foundation, Inc.
3 : : Contributed by Jan Hubicka
4 : :
5 : : This file is part of GCC.
6 : :
7 : : GCC is free software; you can redistribute it and/or modify it under
8 : : the terms of the GNU General Public License as published by the Free
9 : : Software Foundation; either version 3, or (at your option) any later
10 : : version.
11 : :
12 : : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 : : WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 : : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 : : for more details.
16 : :
17 : : You should have received a copy of the GNU General Public License
18 : : along with GCC; see the file COPYING3. If not see
19 : : <http://www.gnu.org/licenses/>. */
20 : :
21 : : #include "config.h"
22 : : #include "system.h"
23 : : #include "coretypes.h"
24 : : #include "target.h"
25 : : #include "tree.h"
26 : : #include "cgraph.h"
27 : :
28 : : /* Remove reference. */
29 : :
30 : : void
31 : 35345362 : ipa_ref::remove_reference ()
32 : : {
33 : 35345362 : struct ipa_ref_list *list = referred_ref_list ();
34 : 35345362 : struct ipa_ref_list *list2 = referring_ref_list ();
35 : 35345362 : struct ipa_ref *last;
36 : :
37 : 35345362 : gcc_assert (list->referring[referred_index] == this);
38 : :
39 : 35345362 : last = list->referring.last ();
40 : 35345362 : if (this != last)
41 : : {
42 : 13518268 : if (use == IPA_REF_ALIAS)
43 : : {
44 : : /* If deleted item is IPA_REF_ALIAS, we have to move last
45 : : item of IPA_REF_LIST type to the deleted position. After that
46 : : we replace last node with deletion slot. */
47 : 53705 : struct ipa_ref *last_alias = list->last_alias ();
48 : :
49 : 53705 : if (last_alias && referred_index < last_alias->referred_index
50 : 52289 : && last_alias != last)
51 : : {
52 : 112 : unsigned last_alias_index = last_alias->referred_index;
53 : :
54 : 112 : list->referring[referred_index] = last_alias;
55 : 112 : list->referring[referred_index]->referred_index = referred_index;
56 : :
57 : : /* New position for replacement is previous index
58 : : of the last_alias. */
59 : 112 : referred_index = last_alias_index;
60 : : }
61 : : }
62 : :
63 : 13518268 : list->referring[referred_index] = list->referring.last ();
64 : 13518268 : list->referring[referred_index]->referred_index= referred_index;
65 : : }
66 : 35345362 : list->referring.pop ();
67 : :
68 : 35345362 : last = &list2->references.last ();
69 : :
70 : 35345362 : struct ipa_ref *ref = this;
71 : :
72 : 35345362 : if (ref != last)
73 : : {
74 : 144244 : *ref = *last;
75 : 144244 : ref->referred_ref_list ()->referring[referred_index] = ref;
76 : : }
77 : 35345362 : list2->references.pop ();
78 : 35345362 : }
79 : :
80 : : /* Return true when execution of reference can lead to return from
81 : : function. */
82 : :
83 : : bool
84 : 179723 : ipa_ref::cannot_lead_to_return ()
85 : : {
86 : 359446 : return dyn_cast <cgraph_node *> (referring)->cannot_return_p ();
87 : : }
88 : :
89 : : /* Return reference list this reference is in. */
90 : :
91 : : struct ipa_ref_list *
92 : 35345362 : ipa_ref::referring_ref_list (void)
93 : : {
94 : 35345362 : return &referring->ref_list;
95 : : }
96 : :
97 : : /* Return reference list this reference is in. */
98 : :
99 : : struct ipa_ref_list *
100 : 71000582 : ipa_ref::referred_ref_list (void)
101 : : {
102 : 71000582 : return &referred->ref_list;
103 : : }
|