]>
Commit | Line | Data |
---|---|---|
8d810329 | 1 | /* Interprocedural reference lists. |
04ec15fa | 2 | Copyright (C) 2010, 2011, 2012 |
8d810329 | 3 | Free Software Foundation, Inc. |
4 | Contributed by Jan Hubicka | |
5 | ||
6 | This file is part of GCC. | |
7 | ||
8 | GCC is free software; you can redistribute it and/or modify it under | |
9 | the terms of the GNU General Public License as published by the Free | |
10 | Software Foundation; either version 3, or (at your option) any later | |
11 | version. | |
12 | ||
13 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
14 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 | for more details. | |
17 | ||
18 | You should have received a copy of the GNU General Public License | |
19 | along with GCC; see the file COPYING3. If not see | |
20 | <http://www.gnu.org/licenses/>. */ | |
21 | ||
22 | #include "config.h" | |
23 | #include "system.h" | |
24 | #include "coretypes.h" | |
25 | #include "tree.h" | |
26 | #include "ggc.h" | |
27 | #include "target.h" | |
28 | #include "cgraph.h" | |
29 | ||
c70f46b0 | 30 | static const char *ipa_ref_use_name[] = {"read","write","addr","alias"}; |
8d810329 | 31 | |
32 | /* Return ipa reference from REFERING_NODE or REFERING_VARPOOL_NODE | |
33 | to REFERED_NODE or REFERED_VARPOOL_NODE. USE_TYPE specify type | |
34 | of the use and STMT the statement (if it exists). */ | |
35 | ||
36 | struct ipa_ref * | |
04ec15fa | 37 | ipa_record_reference (symtab_node referring_node, |
38 | symtab_node referred_node, | |
8d810329 | 39 | enum ipa_ref_use use_type, gimple stmt) |
40 | { | |
41 | struct ipa_ref *ref; | |
42 | struct ipa_ref_list *list, *list2; | |
f1f41a6c | 43 | ipa_ref_t *old_references; |
8d810329 | 44 | |
2dc9831f | 45 | gcc_checking_assert (!stmt || is_a <cgraph_node> (referring_node)); |
04ec15fa | 46 | gcc_checking_assert (use_type != IPA_REF_ALIAS || !stmt); |
47 | ||
48 | list = &referring_node->symbol.ref_list; | |
f1f41a6c | 49 | old_references = vec_safe_address (list->references); |
50 | vec_safe_grow (list->references, vec_safe_length (list->references) + 1); | |
51 | ref = &list->references->last (); | |
8d810329 | 52 | |
04ec15fa | 53 | list2 = &referred_node->symbol.ref_list; |
f1f41a6c | 54 | list2->referring.safe_push (ref); |
55 | ref->referred_index = list2->referring.length () - 1; | |
04ec15fa | 56 | ref->referring = referring_node; |
57 | ref->referred = referred_node; | |
8d810329 | 58 | ref->stmt = stmt; |
59 | ref->use = use_type; | |
60 | ||
61 | /* If vector was moved in memory, update pointers. */ | |
f1f41a6c | 62 | if (old_references != list->references->address ()) |
8d810329 | 63 | { |
64 | int i; | |
65 | for (i = 0; ipa_ref_list_reference_iterate (list, i, ref); i++) | |
f1f41a6c | 66 | ipa_ref_referred_ref_list (ref)->referring[ref->referred_index] = ref; |
8d810329 | 67 | } |
68 | return ref; | |
69 | } | |
70 | ||
71 | /* Remove reference REF. */ | |
72 | ||
73 | void | |
74 | ipa_remove_reference (struct ipa_ref *ref) | |
75 | { | |
04ec15fa | 76 | struct ipa_ref_list *list = ipa_ref_referred_ref_list (ref); |
77 | struct ipa_ref_list *list2 = ipa_ref_referring_ref_list (ref); | |
f1f41a6c | 78 | vec<ipa_ref_t, va_gc> *old_references = list2->references; |
8d810329 | 79 | struct ipa_ref *last; |
80 | ||
f1f41a6c | 81 | gcc_assert (list->referring[ref->referred_index] == ref); |
82 | last = list->referring.last (); | |
8d810329 | 83 | if (ref != last) |
84 | { | |
f1f41a6c | 85 | list->referring[ref->referred_index] = list->referring.last (); |
86 | list->referring[ref->referred_index]->referred_index | |
87 | = ref->referred_index; | |
8d810329 | 88 | } |
f1f41a6c | 89 | list->referring.pop (); |
8d810329 | 90 | |
f1f41a6c | 91 | last = &list2->references->last (); |
8d810329 | 92 | if (ref != last) |
93 | { | |
94 | *ref = *last; | |
f1f41a6c | 95 | ipa_ref_referred_ref_list (ref)->referring[ref->referred_index] = ref; |
8d810329 | 96 | } |
f1f41a6c | 97 | list2->references->pop (); |
8d810329 | 98 | gcc_assert (list2->references == old_references); |
99 | } | |
100 | ||
101 | /* Remove all references in ref list LIST. */ | |
102 | ||
103 | void | |
104 | ipa_remove_all_references (struct ipa_ref_list *list) | |
105 | { | |
f1f41a6c | 106 | while (vec_safe_length (list->references)) |
107 | ipa_remove_reference (&list->references->last ()); | |
108 | vec_free (list->references); | |
8d810329 | 109 | } |
110 | ||
111 | /* Remove all references in ref list LIST. */ | |
112 | ||
113 | void | |
04ec15fa | 114 | ipa_remove_all_referring (struct ipa_ref_list *list) |
8d810329 | 115 | { |
f1f41a6c | 116 | while (list->referring.length ()) |
117 | ipa_remove_reference (list->referring.last ()); | |
118 | list->referring.release (); | |
8d810329 | 119 | } |
120 | ||
121 | /* Dump references in LIST to FILE. */ | |
122 | ||
123 | void | |
124 | ipa_dump_references (FILE * file, struct ipa_ref_list *list) | |
125 | { | |
126 | struct ipa_ref *ref; | |
127 | int i; | |
128 | for (i = 0; ipa_ref_list_reference_iterate (list, i, ref); i++) | |
129 | { | |
04ec15fa | 130 | fprintf (file, "%s/%i (%s)", |
131 | symtab_node_asm_name (ref->referred), | |
132 | ref->referred->symbol.order, | |
133 | ipa_ref_use_name [ref->use]); | |
8d810329 | 134 | } |
135 | fprintf (file, "\n"); | |
136 | } | |
137 | ||
04ec15fa | 138 | /* Dump referring in LIST to FILE. */ |
8d810329 | 139 | |
140 | void | |
04ec15fa | 141 | ipa_dump_referring (FILE * file, struct ipa_ref_list *list) |
8d810329 | 142 | { |
143 | struct ipa_ref *ref; | |
144 | int i; | |
04ec15fa | 145 | for (i = 0; ipa_ref_list_referring_iterate (list, i, ref); i++) |
8d810329 | 146 | { |
04ec15fa | 147 | fprintf (file, "%s/%i (%s)", |
148 | symtab_node_asm_name (ref->referring), | |
149 | ref->referring->symbol.order, | |
150 | ipa_ref_use_name [ref->use]); | |
8d810329 | 151 | } |
152 | fprintf (file, "\n"); | |
153 | } | |
154 | ||
0a10fd82 | 155 | /* Clone all references from SRC to DEST_NODE or DEST_VARPOOL_NODE. */ |
8d810329 | 156 | |
157 | void | |
04ec15fa | 158 | ipa_clone_references (symtab_node dest_node, |
8d810329 | 159 | struct ipa_ref_list *src) |
160 | { | |
161 | struct ipa_ref *ref; | |
162 | int i; | |
163 | for (i = 0; ipa_ref_list_reference_iterate (src, i, ref); i++) | |
04ec15fa | 164 | ipa_record_reference (dest_node, |
165 | ref->referred, | |
8d810329 | 166 | ref->use, ref->stmt); |
167 | } | |
168 | ||
04ec15fa | 169 | /* Clone all referring from SRC to DEST_NODE or DEST_VARPOOL_NODE. */ |
8d810329 | 170 | |
171 | void | |
04ec15fa | 172 | ipa_clone_referring (symtab_node dest_node, |
8d810329 | 173 | struct ipa_ref_list *src) |
174 | { | |
175 | struct ipa_ref *ref; | |
176 | int i; | |
04ec15fa | 177 | for (i = 0; ipa_ref_list_referring_iterate (src, i, ref); i++) |
178 | ipa_record_reference (ref->referring, | |
179 | dest_node, | |
8d810329 | 180 | ref->use, ref->stmt); |
181 | } | |
023a28e1 | 182 | |
04ec15fa | 183 | /* Return true when execution of REF can lead to return from |
023a28e1 | 184 | function. */ |
185 | bool | |
186 | ipa_ref_cannot_lead_to_return (struct ipa_ref *ref) | |
187 | { | |
04ec15fa | 188 | return cgraph_node_cannot_return (ipa_ref_referring_node (ref)); |
023a28e1 | 189 | } |
c70f46b0 | 190 | |
191 | /* Return true if list contains an alias. */ | |
192 | bool | |
193 | ipa_ref_has_aliases_p (struct ipa_ref_list *ref_list) | |
194 | { | |
195 | struct ipa_ref *ref; | |
196 | int i; | |
04ec15fa | 197 | for (i = 0; ipa_ref_list_referring_iterate (ref_list, i, ref); i++) |
c70f46b0 | 198 | if (ref->use == IPA_REF_ALIAS) |
199 | return true; | |
200 | return false; | |
201 | } |