OSDN Git Service

* parser.c (cp_parser_class_specifier): Set class location to that
[pf3gnuchains/gcc-fork.git] / gcc / ipa-ref.c
1 /* Interprocedural reference lists.
2    Copyright (C) 2010
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
30 static const char *ipa_ref_use_name[] = {"read","write","addr"};
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
101 void
102 ipa_remove_reference (struct ipa_ref *ref)
103 {
104   struct ipa_ref_list *list = ipa_ref_refered_ref_list (ref);
105   struct ipa_ref_list *list2 = ipa_ref_refering_ref_list (ref);
106   VEC(ipa_ref_t,gc) *old_references = list2->references;
107   struct ipa_ref *last;
108
109   gcc_assert (VEC_index (ipa_ref_ptr, list->refering, ref->refered_index) == ref);
110   last = VEC_last (ipa_ref_ptr, list->refering);
111   if (ref != last)
112     {
113       VEC_replace (ipa_ref_ptr, list->refering,
114                    ref->refered_index,
115                    VEC_last (ipa_ref_ptr, list->refering));
116       VEC_index (ipa_ref_ptr, list->refering,
117                  ref->refered_index)->refered_index = ref->refered_index;
118     }
119   VEC_pop (ipa_ref_ptr, list->refering);
120
121   last = VEC_last (ipa_ref_t, list2->references);
122   if (ref != last)
123     {
124       *ref = *last;
125       VEC_replace (ipa_ref_ptr,
126                    ipa_ref_refered_ref_list (ref)->refering,
127                    ref->refered_index, ref);
128     }
129   VEC_pop (ipa_ref_t, list2->references);
130   gcc_assert (list2->references == old_references);
131 }
132
133 /* Remove all references in ref list LIST.  */
134
135 void
136 ipa_remove_all_references (struct ipa_ref_list *list)
137 {
138   while (VEC_length (ipa_ref_t, list->references))
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 }
143
144 /* Remove all references in ref list LIST.  */
145
146 void
147 ipa_remove_all_refering (struct ipa_ref_list *list)
148 {
149   while (VEC_length (ipa_ref_ptr, list->refering))
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 }
154
155 /* Dump references in LIST to FILE.  */
156
157 void
158 ipa_dump_references (FILE * file, struct ipa_ref_list *list)
159 {
160   struct ipa_ref *ref;
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 }
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_VARPOL_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_VARPOL_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 }