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 }