Mercurial > hg > CbC > CbC_gcc
comparison gcc/ipa-ref.c @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | f6334be47118 |
children | 84e7813d76e9 |
comparison
equal
deleted
inserted
replaced
68:561a7518be6b | 111:04ced10e8804 |
---|---|
1 /* Interprocedural reference lists. | 1 /* Interprocedural reference lists. |
2 Copyright (C) 2010 | 2 Copyright (C) 2010-2017 Free Software Foundation, Inc. |
3 Free Software Foundation, Inc. | |
4 Contributed by Jan Hubicka | 3 Contributed by Jan Hubicka |
5 | 4 |
6 This file is part of GCC. | 5 This file is part of GCC. |
7 | 6 |
8 GCC is free software; you can redistribute it and/or modify it under | 7 GCC is free software; you can redistribute it and/or modify it under |
20 <http://www.gnu.org/licenses/>. */ | 19 <http://www.gnu.org/licenses/>. */ |
21 | 20 |
22 #include "config.h" | 21 #include "config.h" |
23 #include "system.h" | 22 #include "system.h" |
24 #include "coretypes.h" | 23 #include "coretypes.h" |
24 #include "target.h" | |
25 #include "tree.h" | 25 #include "tree.h" |
26 #include "ggc.h" | |
27 #include "target.h" | |
28 #include "cgraph.h" | 26 #include "cgraph.h" |
29 | 27 |
30 static const char *ipa_ref_use_name[] = {"read","write","addr"}; | 28 /* Remove reference. */ |
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 * | |
37 ipa_record_reference (struct cgraph_node *refering_node, | |
38 struct varpool_node *refering_varpool_node, | |
39 struct cgraph_node *refered_node, | |
40 struct varpool_node *refered_varpool_node, | |
41 enum ipa_ref_use use_type, gimple stmt) | |
42 { | |
43 struct ipa_ref *ref; | |
44 struct ipa_ref_list *list, *list2; | |
45 VEC(ipa_ref_t,gc) *old_references; | |
46 gcc_assert ((!refering_node) ^ (!refering_varpool_node)); | |
47 gcc_assert ((!refered_node) ^ (!refered_varpool_node)); | |
48 gcc_assert (!stmt || refering_node); | |
49 | |
50 list = (refering_node ? &refering_node->ref_list | |
51 : &refering_varpool_node->ref_list); | |
52 old_references = list->references; | |
53 VEC_safe_grow (ipa_ref_t, gc, list->references, | |
54 VEC_length (ipa_ref_t, list->references) + 1); | |
55 ref = VEC_last (ipa_ref_t, list->references); | |
56 | |
57 list2 = (refered_node ? &refered_node->ref_list | |
58 : &refered_varpool_node->ref_list); | |
59 VEC_safe_push (ipa_ref_ptr, heap, list2->refering, ref); | |
60 ref->refered_index = VEC_length (ipa_ref_ptr, list2->refering) - 1; | |
61 if (refering_node) | |
62 { | |
63 ref->refering.cgraph_node = refering_node; | |
64 ref->refering_type = IPA_REF_CGRAPH; | |
65 } | |
66 else | |
67 { | |
68 ref->refering.varpool_node = refering_varpool_node; | |
69 ref->refering_type = IPA_REF_VARPOOL; | |
70 gcc_assert (use_type == IPA_REF_ADDR); | |
71 } | |
72 if (refered_node) | |
73 { | |
74 ref->refered.cgraph_node = refered_node; | |
75 ref->refered_type = IPA_REF_CGRAPH; | |
76 gcc_assert (use_type == IPA_REF_ADDR); | |
77 } | |
78 else | |
79 { | |
80 varpool_mark_needed_node (refered_varpool_node); | |
81 ref->refered.varpool_node = refered_varpool_node; | |
82 ref->refered_type = IPA_REF_VARPOOL; | |
83 } | |
84 ref->stmt = stmt; | |
85 ref->use = use_type; | |
86 | |
87 /* If vector was moved in memory, update pointers. */ | |
88 if (old_references != list->references) | |
89 { | |
90 int i; | |
91 for (i = 0; ipa_ref_list_reference_iterate (list, i, ref); i++) | |
92 VEC_replace (ipa_ref_ptr, | |
93 ipa_ref_refered_ref_list (ref)->refering, | |
94 ref->refered_index, ref); | |
95 } | |
96 return ref; | |
97 } | |
98 | |
99 /* Remove reference REF. */ | |
100 | 29 |
101 void | 30 void |
102 ipa_remove_reference (struct ipa_ref *ref) | 31 ipa_ref::remove_reference () |
103 { | 32 { |
104 struct ipa_ref_list *list = ipa_ref_refered_ref_list (ref); | 33 struct ipa_ref_list *list = referred_ref_list (); |
105 struct ipa_ref_list *list2 = ipa_ref_refering_ref_list (ref); | 34 struct ipa_ref_list *list2 = referring_ref_list (); |
106 VEC(ipa_ref_t,gc) *old_references = list2->references; | 35 vec<ipa_ref_t, va_gc> *old_references = list2->references; |
107 struct ipa_ref *last; | 36 struct ipa_ref *last; |
108 | 37 |
109 gcc_assert (VEC_index (ipa_ref_ptr, list->refering, ref->refered_index) == ref); | 38 gcc_assert (list->referring[referred_index] == this); |
110 last = VEC_last (ipa_ref_ptr, list->refering); | 39 |
111 if (ref != last) | 40 last = list->referring.last (); |
41 if (this != last) | |
112 { | 42 { |
113 VEC_replace (ipa_ref_ptr, list->refering, | 43 if (use == IPA_REF_ALIAS) |
114 ref->refered_index, | 44 { |
115 VEC_last (ipa_ref_ptr, list->refering)); | 45 /* If deleted item is IPA_REF_ALIAS, we have to move last |
116 VEC_index (ipa_ref_ptr, list->refering, | 46 item of IPA_REF_LIST type to the deleted position. After that |
117 ref->refered_index)->refered_index = ref->refered_index; | 47 we replace last node with deletion slot. */ |
48 struct ipa_ref *last_alias = list->last_alias (); | |
49 | |
50 if (last_alias && referred_index < last_alias->referred_index | |
51 && last_alias != last) | |
52 { | |
53 unsigned last_alias_index = last_alias->referred_index; | |
54 | |
55 list->referring[referred_index] = last_alias; | |
56 list->referring[referred_index]->referred_index = referred_index; | |
57 | |
58 /* New position for replacement is previous index | |
59 of the last_alias. */ | |
60 referred_index = last_alias_index; | |
61 } | |
62 } | |
63 | |
64 list->referring[referred_index] = list->referring.last (); | |
65 list->referring[referred_index]->referred_index= referred_index; | |
118 } | 66 } |
119 VEC_pop (ipa_ref_ptr, list->refering); | 67 list->referring.pop (); |
120 | 68 |
121 last = VEC_last (ipa_ref_t, list2->references); | 69 last = &list2->references->last (); |
70 | |
71 struct ipa_ref *ref = this; | |
72 | |
122 if (ref != last) | 73 if (ref != last) |
123 { | 74 { |
124 *ref = *last; | 75 *ref = *last; |
125 VEC_replace (ipa_ref_ptr, | 76 ref->referred_ref_list ()->referring[referred_index] = ref; |
126 ipa_ref_refered_ref_list (ref)->refering, | |
127 ref->refered_index, ref); | |
128 } | 77 } |
129 VEC_pop (ipa_ref_t, list2->references); | 78 list2->references->pop (); |
130 gcc_assert (list2->references == old_references); | 79 gcc_assert (list2->references == old_references); |
131 } | 80 } |
132 | 81 |
133 /* Remove all references in ref list LIST. */ | 82 /* Return true when execution of reference can lead to return from |
83 function. */ | |
134 | 84 |
135 void | 85 bool |
136 ipa_remove_all_references (struct ipa_ref_list *list) | 86 ipa_ref::cannot_lead_to_return () |
137 { | 87 { |
138 while (VEC_length (ipa_ref_t, list->references)) | 88 return dyn_cast <cgraph_node *> (referring)->cannot_return_p (); |
139 ipa_remove_reference (VEC_last (ipa_ref_t, list->references)); | |
140 VEC_free (ipa_ref_t, gc, list->references); | |
141 list->references = NULL; | |
142 } | 89 } |
143 | 90 |
144 /* Remove all references in ref list LIST. */ | 91 /* Return reference list this reference is in. */ |
145 | 92 |
146 void | 93 struct ipa_ref_list * |
147 ipa_remove_all_refering (struct ipa_ref_list *list) | 94 ipa_ref::referring_ref_list (void) |
148 { | 95 { |
149 while (VEC_length (ipa_ref_ptr, list->refering)) | 96 return &referring->ref_list; |
150 ipa_remove_reference (VEC_last (ipa_ref_ptr, list->refering)); | |
151 VEC_free (ipa_ref_ptr, heap, list->refering); | |
152 list->refering = NULL; | |
153 } | 97 } |
154 | 98 |
155 /* Dump references in LIST to FILE. */ | 99 /* Return reference list this reference is in. */ |
156 | 100 |
157 void | 101 struct ipa_ref_list * |
158 ipa_dump_references (FILE * file, struct ipa_ref_list *list) | 102 ipa_ref::referred_ref_list (void) |
159 { | 103 { |
160 struct ipa_ref *ref; | 104 return &referred->ref_list; |
161 int i; | |
162 for (i = 0; ipa_ref_list_reference_iterate (list, i, ref); i++) | |
163 { | |
164 if (ref->refered_type == IPA_REF_CGRAPH) | |
165 { | |
166 fprintf (file, " fn:%s/%i (%s)", cgraph_node_name (ipa_ref_node (ref)), | |
167 ipa_ref_node (ref)->uid, | |
168 ipa_ref_use_name [ref->use]); | |
169 } | |
170 else | |
171 fprintf (file, " var:%s (%s)", | |
172 varpool_node_name (ipa_ref_varpool_node (ref)), | |
173 ipa_ref_use_name [ref->use]); | |
174 } | |
175 fprintf (file, "\n"); | |
176 } | 105 } |
177 | |
178 /* Dump refering in LIST to FILE. */ | |
179 | |
180 void | |
181 ipa_dump_refering (FILE * file, struct ipa_ref_list *list) | |
182 { | |
183 struct ipa_ref *ref; | |
184 int i; | |
185 for (i = 0; ipa_ref_list_refering_iterate (list, i, ref); i++) | |
186 { | |
187 if (ref->refering_type == IPA_REF_CGRAPH) | |
188 fprintf (file, " fn:%s/%i (%s)", | |
189 cgraph_node_name (ipa_ref_refering_node (ref)), | |
190 ipa_ref_refering_node (ref)->uid, | |
191 ipa_ref_use_name [ref->use]); | |
192 else | |
193 fprintf (file, " var:%s (%s)", | |
194 varpool_node_name (ipa_ref_refering_varpool_node (ref)), | |
195 ipa_ref_use_name [ref->use]); | |
196 } | |
197 fprintf (file, "\n"); | |
198 } | |
199 | |
200 /* Clone all references from SRC to DEST_NODE or DEST_VARPOOL_NODE. */ | |
201 | |
202 void | |
203 ipa_clone_references (struct cgraph_node *dest_node, | |
204 struct varpool_node *dest_varpool_node, | |
205 struct ipa_ref_list *src) | |
206 { | |
207 struct ipa_ref *ref; | |
208 int i; | |
209 for (i = 0; ipa_ref_list_reference_iterate (src, i, ref); i++) | |
210 ipa_record_reference (dest_node, dest_varpool_node, | |
211 ref->refered_type == IPA_REF_CGRAPH | |
212 ? ipa_ref_node (ref) : NULL, | |
213 ref->refered_type == IPA_REF_VARPOOL | |
214 ? ipa_ref_varpool_node (ref) : NULL, | |
215 ref->use, ref->stmt); | |
216 } | |
217 | |
218 /* Clone all refering from SRC to DEST_NODE or DEST_VARPOOL_NODE. */ | |
219 | |
220 void | |
221 ipa_clone_refering (struct cgraph_node *dest_node, | |
222 struct varpool_node *dest_varpool_node, | |
223 struct ipa_ref_list *src) | |
224 { | |
225 struct ipa_ref *ref; | |
226 int i; | |
227 for (i = 0; ipa_ref_list_refering_iterate (src, i, ref); i++) | |
228 ipa_record_reference ( | |
229 ref->refering_type == IPA_REF_CGRAPH | |
230 ? ipa_ref_refering_node (ref) : NULL, | |
231 ref->refering_type == IPA_REF_VARPOOL | |
232 ? ipa_ref_refering_varpool_node (ref) : NULL, | |
233 dest_node, dest_varpool_node, | |
234 ref->use, ref->stmt); | |
235 } | |
236 | |
237 /* Return true when execution of REF can load to return from | |
238 function. */ | |
239 bool | |
240 ipa_ref_cannot_lead_to_return (struct ipa_ref *ref) | |
241 { | |
242 return cgraph_node_cannot_return (ipa_ref_refering_node (ref)); | |
243 } |