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 ipa_ref_t
*old_references
;
45 gcc_checking_assert (!stmt
|| is_a
<cgraph_node
> (referring_node
));
46 gcc_checking_assert (use_type
!= IPA_REF_ALIAS
|| !stmt
);
48 list
= &referring_node
->symbol
.ref_list
;
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 ();
53 list2
= &referred_node
->symbol
.ref_list
;
54 list2
->referring
.safe_push (ref
);
55 ref
->referred_index
= list2
->referring
.length () - 1;
56 ref
->referring
= referring_node
;
57 ref
->referred
= referred_node
;
61 /* If vector was moved in memory, update pointers. */
62 if (old_references
!= list
->references
->address ())
65 for (i
= 0; ipa_ref_list_reference_iterate (list
, i
, ref
); i
++)
66 ipa_ref_referred_ref_list (ref
)->referring
[ref
->referred_index
] = ref
;
71 /* Remove reference REF. */
74 ipa_remove_reference (struct ipa_ref
*ref
)
76 struct ipa_ref_list
*list
= ipa_ref_referred_ref_list (ref
);
77 struct ipa_ref_list
*list2
= ipa_ref_referring_ref_list (ref
);
78 vec
<ipa_ref_t
, va_gc
> *old_references
= list2
->references
;
81 gcc_assert (list
->referring
[ref
->referred_index
] == ref
);
82 last
= list
->referring
.last ();
85 list
->referring
[ref
->referred_index
] = list
->referring
.last ();
86 list
->referring
[ref
->referred_index
]->referred_index
87 = ref
->referred_index
;
89 list
->referring
.pop ();
91 last
= &list2
->references
->last ();
95 ipa_ref_referred_ref_list (ref
)->referring
[ref
->referred_index
] = ref
;
97 list2
->references
->pop ();
98 gcc_assert (list2
->references
== old_references
);
101 /* Remove all references in ref list LIST. */
104 ipa_remove_all_references (struct ipa_ref_list
*list
)
106 while (vec_safe_length (list
->references
))
107 ipa_remove_reference (&list
->references
->last ());
108 vec_free (list
->references
);
111 /* Remove all references in ref list LIST. */
114 ipa_remove_all_referring (struct ipa_ref_list
*list
)
116 while (list
->referring
.length ())
117 ipa_remove_reference (list
->referring
.last ());
118 list
->referring
.release ();
121 /* Dump references in LIST to FILE. */
124 ipa_dump_references (FILE * file
, struct ipa_ref_list
*list
)
128 for (i
= 0; ipa_ref_list_reference_iterate (list
, i
, ref
); i
++)
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
]);
135 fprintf (file
, "\n");
138 /* Dump referring in LIST to FILE. */
141 ipa_dump_referring (FILE * file
, struct ipa_ref_list
*list
)
145 for (i
= 0; ipa_ref_list_referring_iterate (list
, i
, ref
); i
++)
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
]);
152 fprintf (file
, "\n");
155 /* Clone all references from SRC to DEST_NODE or DEST_VARPOOL_NODE. */
158 ipa_clone_references (symtab_node dest_node
,
159 struct ipa_ref_list
*src
)
163 for (i
= 0; ipa_ref_list_reference_iterate (src
, i
, ref
); i
++)
164 ipa_record_reference (dest_node
,
166 ref
->use
, ref
->stmt
);
169 /* Clone all referring from SRC to DEST_NODE or DEST_VARPOOL_NODE. */
172 ipa_clone_referring (symtab_node dest_node
,
173 struct ipa_ref_list
*src
)
177 for (i
= 0; ipa_ref_list_referring_iterate (src
, i
, ref
); i
++)
178 ipa_record_reference (ref
->referring
,
180 ref
->use
, ref
->stmt
);
183 /* Return true when execution of REF can lead to return from
186 ipa_ref_cannot_lead_to_return (struct ipa_ref
*ref
)
188 return cgraph_node_cannot_return (ipa_ref_referring_node (ref
));
191 /* Return true if list contains an alias. */
193 ipa_ref_has_aliases_p (struct ipa_ref_list
*ref_list
)
197 for (i
= 0; ipa_ref_list_referring_iterate (ref_list
, i
, ref
); i
++)
198 if (ref
->use
== IPA_REF_ALIAS
)