1 /* Interprocedural reference lists.
2 Copyright (C) 2010, 2011, 2012
3 Free Software Foundation, Inc.
4 Contributed by Jan Hubicka
6 This file is part of GCC.
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
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
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/>. */
24 #include "coretypes.h"
30 static const char *ipa_ref_use_name
[] = {"read","write","addr","alias"};
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). */
37 ipa_record_reference (symtab_node referring_node
,
38 symtab_node referred_node
,
39 enum ipa_ref_use use_type
, gimple stmt
)
42 struct ipa_ref_list
*list
, *list2
;
43 VEC(ipa_ref_t
,gc
) *old_references
;
45 gcc_checking_assert (!stmt
|| symtab_function_p (referring_node
));
46 gcc_checking_assert (use_type
!= IPA_REF_ALIAS
|| !stmt
);
48 list
= &referring_node
->symbol
.ref_list
;
49 old_references
= list
->references
;
50 VEC_safe_grow (ipa_ref_t
, gc
, list
->references
,
51 VEC_length (ipa_ref_t
, list
->references
) + 1);
52 ref
= &VEC_last (ipa_ref_t
, list
->references
);
54 list2
= &referred_node
->symbol
.ref_list
;
55 VEC_safe_push (ipa_ref_ptr
, heap
, list2
->referring
, ref
);
56 ref
->referred_index
= VEC_length (ipa_ref_ptr
, list2
->referring
) - 1;
57 ref
->referring
= referring_node
;
58 ref
->referred
= referred_node
;
62 /* If vector was moved in memory, update pointers. */
63 if (old_references
!= list
->references
)
66 for (i
= 0; ipa_ref_list_reference_iterate (list
, i
, ref
); i
++)
67 VEC_replace (ipa_ref_ptr
,
68 ipa_ref_referred_ref_list (ref
)->referring
,
69 ref
->referred_index
, ref
);
74 /* Remove reference REF. */
77 ipa_remove_reference (struct ipa_ref
*ref
)
79 struct ipa_ref_list
*list
= ipa_ref_referred_ref_list (ref
);
80 struct ipa_ref_list
*list2
= ipa_ref_referring_ref_list (ref
);
81 VEC(ipa_ref_t
,gc
) *old_references
= list2
->references
;
84 gcc_assert (VEC_index (ipa_ref_ptr
, list
->referring
, ref
->referred_index
) == ref
);
85 last
= VEC_last (ipa_ref_ptr
, list
->referring
);
88 VEC_replace (ipa_ref_ptr
, list
->referring
,
90 VEC_last (ipa_ref_ptr
, list
->referring
));
91 VEC_index (ipa_ref_ptr
, list
->referring
,
92 ref
->referred_index
)->referred_index
= ref
->referred_index
;
94 VEC_pop (ipa_ref_ptr
, list
->referring
);
96 last
= &VEC_last (ipa_ref_t
, list2
->references
);
100 VEC_replace (ipa_ref_ptr
,
101 ipa_ref_referred_ref_list (ref
)->referring
,
102 ref
->referred_index
, ref
);
104 VEC_pop (ipa_ref_t
, list2
->references
);
105 gcc_assert (list2
->references
== old_references
);
108 /* Remove all references in ref list LIST. */
111 ipa_remove_all_references (struct ipa_ref_list
*list
)
113 while (VEC_length (ipa_ref_t
, list
->references
))
114 ipa_remove_reference (&VEC_last (ipa_ref_t
, list
->references
));
115 VEC_free (ipa_ref_t
, gc
, list
->references
);
116 list
->references
= NULL
;
119 /* Remove all references in ref list LIST. */
122 ipa_remove_all_referring (struct ipa_ref_list
*list
)
124 while (VEC_length (ipa_ref_ptr
, list
->referring
))
125 ipa_remove_reference (VEC_last (ipa_ref_ptr
, list
->referring
));
126 VEC_free (ipa_ref_ptr
, heap
, list
->referring
);
127 list
->referring
= NULL
;
130 /* Dump references in LIST to FILE. */
133 ipa_dump_references (FILE * file
, struct ipa_ref_list
*list
)
137 for (i
= 0; ipa_ref_list_reference_iterate (list
, i
, ref
); i
++)
139 fprintf (file
, "%s/%i (%s)",
140 symtab_node_asm_name (ref
->referred
),
141 ref
->referred
->symbol
.order
,
142 ipa_ref_use_name
[ref
->use
]);
144 fprintf (file
, "\n");
147 /* Dump referring in LIST to FILE. */
150 ipa_dump_referring (FILE * file
, struct ipa_ref_list
*list
)
154 for (i
= 0; ipa_ref_list_referring_iterate (list
, i
, ref
); i
++)
156 fprintf (file
, "%s/%i (%s)",
157 symtab_node_asm_name (ref
->referring
),
158 ref
->referring
->symbol
.order
,
159 ipa_ref_use_name
[ref
->use
]);
161 fprintf (file
, "\n");
164 /* Clone all references from SRC to DEST_NODE or DEST_VARPOOL_NODE. */
167 ipa_clone_references (symtab_node dest_node
,
168 struct ipa_ref_list
*src
)
172 for (i
= 0; ipa_ref_list_reference_iterate (src
, i
, ref
); i
++)
173 ipa_record_reference (dest_node
,
175 ref
->use
, ref
->stmt
);
178 /* Clone all referring from SRC to DEST_NODE or DEST_VARPOOL_NODE. */
181 ipa_clone_referring (symtab_node dest_node
,
182 struct ipa_ref_list
*src
)
186 for (i
= 0; ipa_ref_list_referring_iterate (src
, i
, ref
); i
++)
187 ipa_record_reference (ref
->referring
,
189 ref
->use
, ref
->stmt
);
192 /* Return true when execution of REF can lead to return from
195 ipa_ref_cannot_lead_to_return (struct ipa_ref
*ref
)
197 return cgraph_node_cannot_return (ipa_ref_referring_node (ref
));
200 /* Return true if list contains an alias. */
202 ipa_ref_has_aliases_p (struct ipa_ref_list
*ref_list
)
206 for (i
= 0; ipa_ref_list_referring_iterate (ref_list
, i
, ref
); i
++)
207 if (ref
->use
== IPA_REF_ALIAS
)