xref: /dflybsd-src/contrib/gcc-4.7/gcc/cgraph.h (revision 81fc95a5293ee307c688a350a3feb4734aaddbb4)
1e4b17023SJohn Marino /* Callgraph handling code.
2e4b17023SJohn Marino    Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
3e4b17023SJohn Marino    Free Software Foundation, Inc.
4e4b17023SJohn Marino    Contributed by Jan Hubicka
5e4b17023SJohn Marino 
6e4b17023SJohn Marino This file is part of GCC.
7e4b17023SJohn Marino 
8e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under
9e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free
10e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later
11e4b17023SJohn Marino version.
12e4b17023SJohn Marino 
13e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or
15e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16e4b17023SJohn Marino for more details.
17e4b17023SJohn Marino 
18e4b17023SJohn Marino You should have received a copy of the GNU General Public License
19e4b17023SJohn Marino along with GCC; see the file COPYING3.  If not see
20e4b17023SJohn Marino <http://www.gnu.org/licenses/>.  */
21e4b17023SJohn Marino 
22e4b17023SJohn Marino #ifndef GCC_CGRAPH_H
23e4b17023SJohn Marino #define GCC_CGRAPH_H
24e4b17023SJohn Marino 
25e4b17023SJohn Marino #include "plugin-api.h"
26e4b17023SJohn Marino #include "vec.h"
27e4b17023SJohn Marino #include "tree.h"
28e4b17023SJohn Marino #include "basic-block.h"
29e4b17023SJohn Marino #include "function.h"
30e4b17023SJohn Marino #include "ipa-ref.h"	/* FIXME: inappropriate dependency of cgraph on IPA.  */
31e4b17023SJohn Marino 
32e4b17023SJohn Marino enum availability
33e4b17023SJohn Marino {
34e4b17023SJohn Marino   /* Not yet set by cgraph_function_body_availability.  */
35e4b17023SJohn Marino   AVAIL_UNSET,
36e4b17023SJohn Marino   /* Function body/variable initializer is unknown.  */
37e4b17023SJohn Marino   AVAIL_NOT_AVAILABLE,
38e4b17023SJohn Marino   /* Function body/variable initializer is known but might be replaced
39e4b17023SJohn Marino      by a different one from other compilation unit and thus needs to
40e4b17023SJohn Marino      be dealt with a care.  Like AVAIL_NOT_AVAILABLE it can have
41e4b17023SJohn Marino      arbitrary side effects on escaping variables and functions, while
42e4b17023SJohn Marino      like AVAILABLE it might access static variables.  */
43e4b17023SJohn Marino   AVAIL_OVERWRITABLE,
44e4b17023SJohn Marino   /* Function body/variable initializer is known and will be used in final
45e4b17023SJohn Marino      program.  */
46e4b17023SJohn Marino   AVAIL_AVAILABLE,
47e4b17023SJohn Marino   /* Function body/variable initializer is known and all it's uses are explicitly
48e4b17023SJohn Marino      visible within current unit (ie it's address is never taken and it is not
49e4b17023SJohn Marino      exported to other units).
50e4b17023SJohn Marino      Currently used only for functions.  */
51e4b17023SJohn Marino   AVAIL_LOCAL
52e4b17023SJohn Marino };
53e4b17023SJohn Marino 
54e4b17023SJohn Marino /* This is the information that is put into the cgraph local structure
55e4b17023SJohn Marino    to recover a function.  */
56e4b17023SJohn Marino struct lto_file_decl_data;
57e4b17023SJohn Marino 
58e4b17023SJohn Marino extern const char * const cgraph_availability_names[];
59e4b17023SJohn Marino extern const char * const ld_plugin_symbol_resolution_names[];
60e4b17023SJohn Marino 
61e4b17023SJohn Marino /* Information about thunk, used only for same body aliases.  */
62e4b17023SJohn Marino 
63e4b17023SJohn Marino struct GTY(()) cgraph_thunk_info {
64e4b17023SJohn Marino   /* Information about the thunk.  */
65e4b17023SJohn Marino   HOST_WIDE_INT fixed_offset;
66e4b17023SJohn Marino   HOST_WIDE_INT virtual_value;
67e4b17023SJohn Marino   tree alias;
68e4b17023SJohn Marino   bool this_adjusting;
69e4b17023SJohn Marino   bool virtual_offset_p;
70e4b17023SJohn Marino   /* Set to true when alias node is thunk.  */
71e4b17023SJohn Marino   bool thunk_p;
72e4b17023SJohn Marino };
73e4b17023SJohn Marino 
74e4b17023SJohn Marino /* Information about the function collected locally.
75e4b17023SJohn Marino    Available after function is analyzed.  */
76e4b17023SJohn Marino 
77e4b17023SJohn Marino struct GTY(()) cgraph_local_info {
78e4b17023SJohn Marino   /* File stream where this node is being written to.  */
79e4b17023SJohn Marino   struct lto_file_decl_data * lto_file_data;
80e4b17023SJohn Marino 
81e4b17023SJohn Marino   /* Set when function function is visible in current compilation unit only
82e4b17023SJohn Marino      and its address is never taken.  */
83e4b17023SJohn Marino   unsigned local : 1;
84e4b17023SJohn Marino 
85e4b17023SJohn Marino   /* Set when function is visible by other units.  */
86e4b17023SJohn Marino   unsigned externally_visible : 1;
87e4b17023SJohn Marino 
88e4b17023SJohn Marino   /* Set once it has been finalized so we consider it to be output.  */
89e4b17023SJohn Marino   unsigned finalized : 1;
90e4b17023SJohn Marino 
91e4b17023SJohn Marino   /* False when there is something makes versioning impossible.  */
92e4b17023SJohn Marino   unsigned versionable : 1;
93e4b17023SJohn Marino 
94e4b17023SJohn Marino   /* False when function calling convention and signature can not be changed.
95e4b17023SJohn Marino      This is the case when __builtin_apply_args is used.  */
96e4b17023SJohn Marino   unsigned can_change_signature : 1;
97e4b17023SJohn Marino 
98e4b17023SJohn Marino   /* True when the function has been originally extern inline, but it is
99e4b17023SJohn Marino      redefined now.  */
100e4b17023SJohn Marino   unsigned redefined_extern_inline : 1;
101e4b17023SJohn Marino 
102e4b17023SJohn Marino   /* True if the function may enter serial irrevocable mode.  */
103e4b17023SJohn Marino   unsigned tm_may_enter_irr : 1;
104e4b17023SJohn Marino };
105e4b17023SJohn Marino 
106e4b17023SJohn Marino /* Information about the function that needs to be computed globally
107e4b17023SJohn Marino    once compilation is finished.  Available only with -funit-at-a-time.  */
108e4b17023SJohn Marino 
109e4b17023SJohn Marino struct GTY(()) cgraph_global_info {
110e4b17023SJohn Marino   /* For inline clones this points to the function they will be
111e4b17023SJohn Marino      inlined into.  */
112e4b17023SJohn Marino   struct cgraph_node *inlined_to;
113e4b17023SJohn Marino };
114e4b17023SJohn Marino 
115e4b17023SJohn Marino /* Information about the function that is propagated by the RTL backend.
116e4b17023SJohn Marino    Available only for functions that has been already assembled.  */
117e4b17023SJohn Marino 
118e4b17023SJohn Marino struct GTY(()) cgraph_rtl_info {
119e4b17023SJohn Marino    unsigned int preferred_incoming_stack_boundary;
120e4b17023SJohn Marino };
121e4b17023SJohn Marino 
122e4b17023SJohn Marino /* Represent which DECL tree (or reference to such tree)
123e4b17023SJohn Marino    will be replaced by another tree while versioning.  */
124e4b17023SJohn Marino struct GTY(()) ipa_replace_map
125e4b17023SJohn Marino {
126e4b17023SJohn Marino   /* The tree that will be replaced.  */
127e4b17023SJohn Marino   tree old_tree;
128e4b17023SJohn Marino   /* The new (replacing) tree.  */
129e4b17023SJohn Marino   tree new_tree;
130e4b17023SJohn Marino   /* Parameter number to replace, when old_tree is NULL.  */
131e4b17023SJohn Marino   int parm_num;
132e4b17023SJohn Marino   /* True when a substitution should be done, false otherwise.  */
133e4b17023SJohn Marino   bool replace_p;
134e4b17023SJohn Marino   /* True when we replace a reference to old_tree.  */
135e4b17023SJohn Marino   bool ref_p;
136e4b17023SJohn Marino };
137e4b17023SJohn Marino typedef struct ipa_replace_map *ipa_replace_map_p;
138e4b17023SJohn Marino DEF_VEC_P(ipa_replace_map_p);
139e4b17023SJohn Marino DEF_VEC_ALLOC_P(ipa_replace_map_p,gc);
140e4b17023SJohn Marino 
141e4b17023SJohn Marino struct GTY(()) cgraph_clone_info
142e4b17023SJohn Marino {
143e4b17023SJohn Marino   VEC(ipa_replace_map_p,gc)* tree_map;
144e4b17023SJohn Marino   bitmap args_to_skip;
145e4b17023SJohn Marino   bitmap combined_args_to_skip;
146e4b17023SJohn Marino };
147e4b17023SJohn Marino 
148e4b17023SJohn Marino 
149e4b17023SJohn Marino /* The cgraph data structure.
150e4b17023SJohn Marino    Each function decl has assigned cgraph_node listing callees and callers.  */
151e4b17023SJohn Marino 
152e4b17023SJohn Marino struct GTY((chain_next ("%h.next"), chain_prev ("%h.previous"))) cgraph_node {
153e4b17023SJohn Marino   tree decl;
154e4b17023SJohn Marino   struct cgraph_edge *callees;
155e4b17023SJohn Marino   struct cgraph_edge *callers;
156e4b17023SJohn Marino   struct cgraph_node *next;
157e4b17023SJohn Marino   struct cgraph_node *previous;
158e4b17023SJohn Marino   /* List of edges representing indirect calls with a yet undetermined
159e4b17023SJohn Marino      callee.  */
160e4b17023SJohn Marino   struct cgraph_edge *indirect_calls;
161e4b17023SJohn Marino   /* For nested functions points to function the node is nested in.  */
162e4b17023SJohn Marino   struct cgraph_node *origin;
163e4b17023SJohn Marino   /* Points to first nested function, if any.  */
164e4b17023SJohn Marino   struct cgraph_node *nested;
165e4b17023SJohn Marino   /* Pointer to the next function with same origin, if any.  */
166e4b17023SJohn Marino   struct cgraph_node *next_nested;
167e4b17023SJohn Marino   /* Pointer to the next function in cgraph_nodes_queue.  */
168e4b17023SJohn Marino   struct cgraph_node *next_needed;
169e4b17023SJohn Marino   /* Pointer to the next clone.  */
170e4b17023SJohn Marino   struct cgraph_node *next_sibling_clone;
171e4b17023SJohn Marino   struct cgraph_node *prev_sibling_clone;
172e4b17023SJohn Marino   struct cgraph_node *clones;
173e4b17023SJohn Marino   struct cgraph_node *clone_of;
174e4b17023SJohn Marino   /* Circular list of nodes in the same comdat group if non-NULL.  */
175e4b17023SJohn Marino   struct cgraph_node *same_comdat_group;
176e4b17023SJohn Marino   /* For functions with many calls sites it holds map from call expression
177e4b17023SJohn Marino      to the edge to speed up cgraph_edge function.  */
178e4b17023SJohn Marino   htab_t GTY((param_is (struct cgraph_edge))) call_site_hash;
179e4b17023SJohn Marino   /* Declaration node used to be clone of. */
180e4b17023SJohn Marino   tree former_clone_of;
181e4b17023SJohn Marino 
182e4b17023SJohn Marino   PTR GTY ((skip)) aux;
183e4b17023SJohn Marino 
184e4b17023SJohn Marino   /* Interprocedural passes scheduled to have their transform functions
185e4b17023SJohn Marino      applied next time we execute local pass on them.  We maintain it
186e4b17023SJohn Marino      per-function in order to allow IPA passes to introduce new functions.  */
187e4b17023SJohn Marino   VEC(ipa_opt_pass,heap) * GTY((skip)) ipa_transforms_to_apply;
188e4b17023SJohn Marino 
189e4b17023SJohn Marino   struct ipa_ref_list ref_list;
190e4b17023SJohn Marino   struct cgraph_local_info local;
191e4b17023SJohn Marino   struct cgraph_global_info global;
192e4b17023SJohn Marino   struct cgraph_rtl_info rtl;
193e4b17023SJohn Marino   struct cgraph_clone_info clone;
194e4b17023SJohn Marino   struct cgraph_thunk_info thunk;
195e4b17023SJohn Marino 
196e4b17023SJohn Marino   /* Expected number of executions: calculated in profile.c.  */
197e4b17023SJohn Marino   gcov_type count;
198e4b17023SJohn Marino   /* How to scale counts at materialization time; used to merge
199e4b17023SJohn Marino      LTO units with different number of profile runs.  */
200e4b17023SJohn Marino   int count_materialization_scale;
201e4b17023SJohn Marino   /* Unique id of the node.  */
202e4b17023SJohn Marino   int uid;
203e4b17023SJohn Marino   /* Ordering of all cgraph nodes.  */
204e4b17023SJohn Marino   int order;
205e4b17023SJohn Marino 
206e4b17023SJohn Marino   enum ld_plugin_symbol_resolution resolution;
207e4b17023SJohn Marino 
208e4b17023SJohn Marino   /* Set when function must be output for some reason.  The primary
209e4b17023SJohn Marino      use of this flag is to mark functions needed to be output for
210e4b17023SJohn Marino      non-standard reason.  Functions that are externally visible
211e4b17023SJohn Marino      or reachable from functions needed to be output are marked
212e4b17023SJohn Marino      by specialized flags.  */
213e4b17023SJohn Marino   unsigned needed : 1;
214e4b17023SJohn Marino   /* Set when function has address taken.
215e4b17023SJohn Marino      In current implementation it imply needed flag. */
216e4b17023SJohn Marino   unsigned address_taken : 1;
217e4b17023SJohn Marino   /* Set when decl is an abstract function pointed to by the
218e4b17023SJohn Marino      ABSTRACT_DECL_ORIGIN of a reachable function.  */
219e4b17023SJohn Marino   unsigned abstract_and_needed : 1;
220e4b17023SJohn Marino   /* Set when function is reachable by call from other function
221e4b17023SJohn Marino      that is either reachable or needed.
222e4b17023SJohn Marino      This flag is computed at original cgraph construction and then
223e4b17023SJohn Marino      updated in cgraph_remove_unreachable_nodes.  Note that after
224e4b17023SJohn Marino      cgraph_remove_unreachable_nodes cgraph still can contain unreachable
225e4b17023SJohn Marino      nodes when they are needed for virtual clone instantiation.  */
226e4b17023SJohn Marino   unsigned reachable : 1;
227e4b17023SJohn Marino   /* Set when function is reachable by call from other LTRANS partition.  */
228e4b17023SJohn Marino   unsigned reachable_from_other_partition : 1;
229e4b17023SJohn Marino   /* Set once the function is lowered (i.e. its CFG is built).  */
230e4b17023SJohn Marino   unsigned lowered : 1;
231e4b17023SJohn Marino   /* Set once the function has been instantiated and its callee
232e4b17023SJohn Marino      lists created.  */
233e4b17023SJohn Marino   unsigned analyzed : 1;
234e4b17023SJohn Marino   /* Set when function is available in the other LTRANS partition.
235e4b17023SJohn Marino      During WPA output it is used to mark nodes that are present in
236e4b17023SJohn Marino      multiple partitions.  */
237e4b17023SJohn Marino   unsigned in_other_partition : 1;
238e4b17023SJohn Marino   /* Set when function is scheduled to be processed by local passes.  */
239e4b17023SJohn Marino   unsigned process : 1;
240e4b17023SJohn Marino   /* Set for aliases once they got through assemble_alias.  */
241e4b17023SJohn Marino   unsigned alias : 1;
242e4b17023SJohn Marino   /* Set for aliases created as C++ same body aliases.  */
243e4b17023SJohn Marino   unsigned same_body_alias : 1;
244e4b17023SJohn Marino   /* How commonly executed the node is.  Initialized during branch
245e4b17023SJohn Marino      probabilities pass.  */
246e4b17023SJohn Marino   ENUM_BITFIELD (node_frequency) frequency : 2;
247e4b17023SJohn Marino   /* True when function can only be called at startup (from static ctor).  */
248e4b17023SJohn Marino   unsigned only_called_at_startup : 1;
249e4b17023SJohn Marino   /* True when function can only be called at startup (from static dtor).  */
250e4b17023SJohn Marino   unsigned only_called_at_exit : 1;
251e4b17023SJohn Marino   /* True when function is the transactional clone of a function which
252e4b17023SJohn Marino      is called only from inside transactions.  */
253e4b17023SJohn Marino   /* ?? We should be able to remove this.  We have enough bits in
254e4b17023SJohn Marino      cgraph to calculate it.  */
255e4b17023SJohn Marino   unsigned tm_clone : 1;
256e4b17023SJohn Marino };
257e4b17023SJohn Marino 
258e4b17023SJohn Marino typedef struct cgraph_node *cgraph_node_ptr;
259e4b17023SJohn Marino 
260e4b17023SJohn Marino DEF_VEC_P(cgraph_node_ptr);
261e4b17023SJohn Marino DEF_VEC_ALLOC_P(cgraph_node_ptr,heap);
262e4b17023SJohn Marino DEF_VEC_ALLOC_P(cgraph_node_ptr,gc);
263e4b17023SJohn Marino 
264e4b17023SJohn Marino /* A cgraph node set is a collection of cgraph nodes.  A cgraph node
265e4b17023SJohn Marino    can appear in multiple sets.  */
266e4b17023SJohn Marino struct cgraph_node_set_def
267e4b17023SJohn Marino {
268e4b17023SJohn Marino   struct pointer_map_t *map;
269e4b17023SJohn Marino   VEC(cgraph_node_ptr, heap) *nodes;
270e4b17023SJohn Marino };
271e4b17023SJohn Marino 
272e4b17023SJohn Marino typedef struct varpool_node *varpool_node_ptr;
273e4b17023SJohn Marino 
274e4b17023SJohn Marino DEF_VEC_P(varpool_node_ptr);
275e4b17023SJohn Marino DEF_VEC_ALLOC_P(varpool_node_ptr,heap);
276e4b17023SJohn Marino DEF_VEC_ALLOC_P(varpool_node_ptr,gc);
277e4b17023SJohn Marino 
278e4b17023SJohn Marino /* A varpool node set is a collection of varpool nodes.  A varpool node
279e4b17023SJohn Marino    can appear in multiple sets.  */
280e4b17023SJohn Marino struct varpool_node_set_def
281e4b17023SJohn Marino {
282e4b17023SJohn Marino   struct pointer_map_t * map;
283e4b17023SJohn Marino   VEC(varpool_node_ptr, heap) *nodes;
284e4b17023SJohn Marino };
285e4b17023SJohn Marino 
286e4b17023SJohn Marino typedef struct cgraph_node_set_def *cgraph_node_set;
287e4b17023SJohn Marino 
288e4b17023SJohn Marino DEF_VEC_P(cgraph_node_set);
289e4b17023SJohn Marino DEF_VEC_ALLOC_P(cgraph_node_set,gc);
290e4b17023SJohn Marino DEF_VEC_ALLOC_P(cgraph_node_set,heap);
291e4b17023SJohn Marino 
292e4b17023SJohn Marino typedef struct varpool_node_set_def *varpool_node_set;
293e4b17023SJohn Marino 
294e4b17023SJohn Marino DEF_VEC_P(varpool_node_set);
295e4b17023SJohn Marino DEF_VEC_ALLOC_P(varpool_node_set,gc);
296e4b17023SJohn Marino DEF_VEC_ALLOC_P(varpool_node_set,heap);
297e4b17023SJohn Marino 
298e4b17023SJohn Marino /* Iterator structure for cgraph node sets.  */
299e4b17023SJohn Marino typedef struct
300e4b17023SJohn Marino {
301e4b17023SJohn Marino   cgraph_node_set set;
302e4b17023SJohn Marino   unsigned index;
303e4b17023SJohn Marino } cgraph_node_set_iterator;
304e4b17023SJohn Marino 
305e4b17023SJohn Marino /* Iterator structure for varpool node sets.  */
306e4b17023SJohn Marino typedef struct
307e4b17023SJohn Marino {
308e4b17023SJohn Marino   varpool_node_set set;
309e4b17023SJohn Marino   unsigned index;
310e4b17023SJohn Marino } varpool_node_set_iterator;
311e4b17023SJohn Marino 
312e4b17023SJohn Marino #define DEFCIFCODE(code, string)	CIF_ ## code,
313e4b17023SJohn Marino /* Reasons for inlining failures.  */
314e4b17023SJohn Marino typedef enum cgraph_inline_failed_enum {
315e4b17023SJohn Marino #include "cif-code.def"
316e4b17023SJohn Marino   CIF_N_REASONS
317e4b17023SJohn Marino } cgraph_inline_failed_t;
318e4b17023SJohn Marino 
319e4b17023SJohn Marino /* Structure containing additional information about an indirect call.  */
320e4b17023SJohn Marino 
321e4b17023SJohn Marino struct GTY(()) cgraph_indirect_call_info
322e4b17023SJohn Marino {
323e4b17023SJohn Marino   /* Offset accumulated from ancestor jump functions of inlined call graph
324e4b17023SJohn Marino      edges.  */
325e4b17023SJohn Marino   HOST_WIDE_INT anc_offset;
326e4b17023SJohn Marino   /* OBJ_TYPE_REF_TOKEN of a polymorphic call (if polymorphic is set).  */
327e4b17023SJohn Marino   HOST_WIDE_INT otr_token;
328e4b17023SJohn Marino   /* Type of the object from OBJ_TYPE_REF_OBJECT. */
329e4b17023SJohn Marino   tree otr_type;
330e4b17023SJohn Marino   /* Index of the parameter that is called.  */
331e4b17023SJohn Marino   int param_index;
332e4b17023SJohn Marino   /* ECF flags determined from the caller.  */
333e4b17023SJohn Marino   int ecf_flags;
334e4b17023SJohn Marino 
335e4b17023SJohn Marino   /* Set when the call is a virtual call with the parameter being the
336e4b17023SJohn Marino      associated object pointer rather than a simple direct call.  */
337e4b17023SJohn Marino   unsigned polymorphic : 1;
338e4b17023SJohn Marino };
339e4b17023SJohn Marino 
340e4b17023SJohn Marino struct GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_caller"))) cgraph_edge {
341e4b17023SJohn Marino   /* Expected number of executions: calculated in profile.c.  */
342e4b17023SJohn Marino   gcov_type count;
343e4b17023SJohn Marino   struct cgraph_node *caller;
344e4b17023SJohn Marino   struct cgraph_node *callee;
345e4b17023SJohn Marino   struct cgraph_edge *prev_caller;
346e4b17023SJohn Marino   struct cgraph_edge *next_caller;
347e4b17023SJohn Marino   struct cgraph_edge *prev_callee;
348e4b17023SJohn Marino   struct cgraph_edge *next_callee;
349e4b17023SJohn Marino   gimple call_stmt;
350e4b17023SJohn Marino   /* Additional information about an indirect call.  Not cleared when an edge
351e4b17023SJohn Marino      becomes direct.  */
352e4b17023SJohn Marino   struct cgraph_indirect_call_info *indirect_info;
353e4b17023SJohn Marino   PTR GTY ((skip (""))) aux;
354e4b17023SJohn Marino   /* When equal to CIF_OK, inline this call.  Otherwise, points to the
355e4b17023SJohn Marino      explanation why function was not inlined.  */
356e4b17023SJohn Marino   cgraph_inline_failed_t inline_failed;
357e4b17023SJohn Marino   /* The stmt_uid of call_stmt.  This is used by LTO to recover the call_stmt
358e4b17023SJohn Marino      when the function is serialized in.  */
359e4b17023SJohn Marino   unsigned int lto_stmt_uid;
360e4b17023SJohn Marino   /* Expected frequency of executions within the function.
361e4b17023SJohn Marino      When set to CGRAPH_FREQ_BASE, the edge is expected to be called once
362e4b17023SJohn Marino      per function call.  The range is 0 to CGRAPH_FREQ_MAX.  */
363e4b17023SJohn Marino   int frequency;
364e4b17023SJohn Marino   /* Unique id of the edge.  */
365e4b17023SJohn Marino   int uid;
366e4b17023SJohn Marino   /* Whether this edge was made direct by indirect inlining.  */
367e4b17023SJohn Marino   unsigned int indirect_inlining_edge : 1;
368e4b17023SJohn Marino   /* Whether this edge describes an indirect call with an undetermined
369e4b17023SJohn Marino      callee.  */
370e4b17023SJohn Marino   unsigned int indirect_unknown_callee : 1;
371e4b17023SJohn Marino   /* Whether this edge is still a dangling  */
372e4b17023SJohn Marino   /* True if the corresponding CALL stmt cannot be inlined.  */
373e4b17023SJohn Marino   unsigned int call_stmt_cannot_inline_p : 1;
374e4b17023SJohn Marino   /* Can this call throw externally?  */
375e4b17023SJohn Marino   unsigned int can_throw_external : 1;
376e4b17023SJohn Marino };
377e4b17023SJohn Marino 
378e4b17023SJohn Marino #define CGRAPH_FREQ_BASE 1000
379e4b17023SJohn Marino #define CGRAPH_FREQ_MAX 100000
380e4b17023SJohn Marino 
381e4b17023SJohn Marino typedef struct cgraph_edge *cgraph_edge_p;
382e4b17023SJohn Marino 
383e4b17023SJohn Marino DEF_VEC_P(cgraph_edge_p);
384e4b17023SJohn Marino DEF_VEC_ALLOC_P(cgraph_edge_p,heap);
385e4b17023SJohn Marino 
386e4b17023SJohn Marino /* The varpool data structure.
387e4b17023SJohn Marino    Each static variable decl has assigned varpool_node.  */
388e4b17023SJohn Marino 
389e4b17023SJohn Marino struct GTY((chain_next ("%h.next"), chain_prev ("%h.prev"))) varpool_node {
390e4b17023SJohn Marino   tree decl;
391e4b17023SJohn Marino   /* For aliases points to declaration DECL is alias of.  */
392e4b17023SJohn Marino   tree alias_of;
393e4b17023SJohn Marino   /* Pointer to the next function in varpool_nodes.  */
394e4b17023SJohn Marino   struct varpool_node *next, *prev;
395e4b17023SJohn Marino   /* Pointer to the next function in varpool_nodes_queue.  */
396e4b17023SJohn Marino   struct varpool_node *next_needed, *prev_needed;
397e4b17023SJohn Marino   /* Circular list of nodes in the same comdat group if non-NULL.  */
398e4b17023SJohn Marino   struct varpool_node *same_comdat_group;
399e4b17023SJohn Marino   struct ipa_ref_list ref_list;
400e4b17023SJohn Marino   /* File stream where this node is being written to.  */
401e4b17023SJohn Marino   struct lto_file_decl_data * lto_file_data;
402e4b17023SJohn Marino   PTR GTY ((skip)) aux;
403e4b17023SJohn Marino   /* Ordering of all cgraph nodes.  */
404e4b17023SJohn Marino   int order;
405e4b17023SJohn Marino   enum ld_plugin_symbol_resolution resolution;
406e4b17023SJohn Marino 
407e4b17023SJohn Marino   /* Set when function must be output - it is externally visible
408e4b17023SJohn Marino      or its address is taken.  */
409e4b17023SJohn Marino   unsigned needed : 1;
410e4b17023SJohn Marino   /* Needed variables might become dead by optimization.  This flag
411e4b17023SJohn Marino      forces the variable to be output even if it appears dead otherwise.  */
412e4b17023SJohn Marino   unsigned force_output : 1;
413e4b17023SJohn Marino   /* Set once the variable has been instantiated and its callee
414e4b17023SJohn Marino      lists created.  */
415e4b17023SJohn Marino   unsigned analyzed : 1;
416e4b17023SJohn Marino   /* Set once it has been finalized so we consider it to be output.  */
417e4b17023SJohn Marino   unsigned finalized : 1;
418e4b17023SJohn Marino   /* Set when variable is scheduled to be assembled.  */
419e4b17023SJohn Marino   unsigned output : 1;
420e4b17023SJohn Marino   /* Set when function is visible by other units.  */
421e4b17023SJohn Marino   unsigned externally_visible : 1;
422e4b17023SJohn Marino   /* Set for aliases once they got through assemble_alias.  Also set for
423e4b17023SJohn Marino      extra name aliases in varpool_extra_name_alias.  */
424e4b17023SJohn Marino   unsigned alias : 1;
425e4b17023SJohn Marino   unsigned extra_name_alias : 1;
426e4b17023SJohn Marino   /* Set when variable is used from other LTRANS partition.  */
427e4b17023SJohn Marino   unsigned used_from_other_partition : 1;
428e4b17023SJohn Marino   /* Set when variable is available in the other LTRANS partition.
429e4b17023SJohn Marino      During WPA output it is used to mark nodes that are present in
430e4b17023SJohn Marino      multiple partitions.  */
431e4b17023SJohn Marino   unsigned in_other_partition : 1;
432e4b17023SJohn Marino };
433e4b17023SJohn Marino 
434e4b17023SJohn Marino /* Every top level asm statement is put into a cgraph_asm_node.  */
435e4b17023SJohn Marino 
436e4b17023SJohn Marino struct GTY(()) cgraph_asm_node {
437e4b17023SJohn Marino   /* Next asm node.  */
438e4b17023SJohn Marino   struct cgraph_asm_node *next;
439e4b17023SJohn Marino   /* String for this asm node.  */
440e4b17023SJohn Marino   tree asm_str;
441e4b17023SJohn Marino   /* Ordering of all cgraph nodes.  */
442e4b17023SJohn Marino   int order;
443e4b17023SJohn Marino };
444e4b17023SJohn Marino 
445e4b17023SJohn Marino extern GTY(()) struct cgraph_node *cgraph_nodes;
446e4b17023SJohn Marino extern GTY(()) int cgraph_n_nodes;
447e4b17023SJohn Marino extern GTY(()) int cgraph_max_uid;
448e4b17023SJohn Marino extern GTY(()) int cgraph_edge_max_uid;
449e4b17023SJohn Marino extern bool cgraph_global_info_ready;
450e4b17023SJohn Marino enum cgraph_state
451e4b17023SJohn Marino {
452e4b17023SJohn Marino   /* Callgraph is being constructed.  It is safe to add new functions.  */
453e4b17023SJohn Marino   CGRAPH_STATE_CONSTRUCTION,
454e4b17023SJohn Marino   /* Callgraph is built and IPA passes are being run.  */
455e4b17023SJohn Marino   CGRAPH_STATE_IPA,
456e4b17023SJohn Marino   /* Callgraph is built and all functions are transformed to SSA form.  */
457e4b17023SJohn Marino   CGRAPH_STATE_IPA_SSA,
458e4b17023SJohn Marino   /* Functions are now ordered and being passed to RTL expanders.  */
459e4b17023SJohn Marino   CGRAPH_STATE_EXPANSION,
460e4b17023SJohn Marino   /* All cgraph expansion is done.  */
461e4b17023SJohn Marino   CGRAPH_STATE_FINISHED
462e4b17023SJohn Marino };
463e4b17023SJohn Marino extern enum cgraph_state cgraph_state;
464e4b17023SJohn Marino extern bool cgraph_function_flags_ready;
465e4b17023SJohn Marino extern GTY(()) struct cgraph_node *cgraph_nodes_queue;
466e4b17023SJohn Marino extern GTY(()) struct cgraph_node *cgraph_new_nodes;
467e4b17023SJohn Marino 
468e4b17023SJohn Marino extern GTY(()) struct cgraph_asm_node *cgraph_asm_nodes;
469e4b17023SJohn Marino extern GTY(()) int cgraph_order;
470e4b17023SJohn Marino extern bool same_body_aliases_done;
471e4b17023SJohn Marino 
472e4b17023SJohn Marino /* In cgraph.c  */
473e4b17023SJohn Marino void dump_cgraph (FILE *);
474e4b17023SJohn Marino void debug_cgraph (void);
475e4b17023SJohn Marino void dump_cgraph_node (FILE *, struct cgraph_node *);
476e4b17023SJohn Marino void debug_cgraph_node (struct cgraph_node *);
477e4b17023SJohn Marino void cgraph_insert_node_to_hashtable (struct cgraph_node *node);
478e4b17023SJohn Marino void cgraph_remove_edge (struct cgraph_edge *);
479e4b17023SJohn Marino void cgraph_remove_node (struct cgraph_node *);
480e4b17023SJohn Marino void cgraph_add_to_same_comdat_group (struct cgraph_node *, struct cgraph_node *);
481e4b17023SJohn Marino void cgraph_remove_node_and_inline_clones (struct cgraph_node *);
482e4b17023SJohn Marino void cgraph_release_function_body (struct cgraph_node *);
483e4b17023SJohn Marino void cgraph_node_remove_callees (struct cgraph_node *node);
484e4b17023SJohn Marino struct cgraph_edge *cgraph_create_edge (struct cgraph_node *,
485e4b17023SJohn Marino 					struct cgraph_node *,
486e4b17023SJohn Marino 					gimple, gcov_type, int);
487e4b17023SJohn Marino struct cgraph_edge *cgraph_create_indirect_edge (struct cgraph_node *, gimple,
488e4b17023SJohn Marino 						 int, gcov_type, int);
489e4b17023SJohn Marino struct cgraph_indirect_call_info *cgraph_allocate_init_indirect_info (void);
490e4b17023SJohn Marino struct cgraph_node * cgraph_get_node (const_tree);
491e4b17023SJohn Marino struct cgraph_node * cgraph_create_node (tree);
492e4b17023SJohn Marino struct cgraph_node * cgraph_get_create_node (tree);
493e4b17023SJohn Marino struct cgraph_node * cgraph_same_body_alias (struct cgraph_node *, tree, tree);
494e4b17023SJohn Marino struct cgraph_node * cgraph_add_thunk (struct cgraph_node *, tree, tree, bool, HOST_WIDE_INT,
495e4b17023SJohn Marino 				       HOST_WIDE_INT, tree, tree);
496e4b17023SJohn Marino struct cgraph_node *cgraph_node_for_asm (tree);
497e4b17023SJohn Marino struct cgraph_edge *cgraph_edge (struct cgraph_node *, gimple);
498e4b17023SJohn Marino void cgraph_set_call_stmt (struct cgraph_edge *, gimple);
499e4b17023SJohn Marino void cgraph_set_call_stmt_including_clones (struct cgraph_node *, gimple, gimple);
500e4b17023SJohn Marino void cgraph_create_edge_including_clones (struct cgraph_node *,
501e4b17023SJohn Marino 					  struct cgraph_node *,
502e4b17023SJohn Marino 					  gimple, gimple, gcov_type, int,
503e4b17023SJohn Marino 					  cgraph_inline_failed_t);
504e4b17023SJohn Marino void cgraph_update_edges_for_call_stmt (gimple, tree, gimple);
505e4b17023SJohn Marino struct cgraph_local_info *cgraph_local_info (tree);
506e4b17023SJohn Marino struct cgraph_global_info *cgraph_global_info (tree);
507e4b17023SJohn Marino struct cgraph_rtl_info *cgraph_rtl_info (tree);
508e4b17023SJohn Marino const char * cgraph_node_name (struct cgraph_node *);
509e4b17023SJohn Marino struct cgraph_edge * cgraph_clone_edge (struct cgraph_edge *,
510e4b17023SJohn Marino 					struct cgraph_node *, gimple,
511e4b17023SJohn Marino 					unsigned, gcov_type, int, bool);
512e4b17023SJohn Marino struct cgraph_node * cgraph_clone_node (struct cgraph_node *, tree, gcov_type,
513e4b17023SJohn Marino 					int, bool, VEC(cgraph_edge_p,heap) *,
514e4b17023SJohn Marino 					bool);
515e4b17023SJohn Marino struct cgraph_node *cgraph_create_function_alias (tree, tree);
516e4b17023SJohn Marino void cgraph_call_node_duplication_hooks (struct cgraph_node *node1,
517e4b17023SJohn Marino 					 struct cgraph_node *node2);
518e4b17023SJohn Marino 
519e4b17023SJohn Marino void cgraph_redirect_edge_callee (struct cgraph_edge *, struct cgraph_node *);
520e4b17023SJohn Marino void cgraph_make_edge_direct (struct cgraph_edge *, struct cgraph_node *);
521e4b17023SJohn Marino bool cgraph_only_called_directly_p (struct cgraph_node *);
522e4b17023SJohn Marino 
523e4b17023SJohn Marino struct cgraph_asm_node *cgraph_add_asm_node (tree);
524e4b17023SJohn Marino 
525e4b17023SJohn Marino bool cgraph_function_possibly_inlined_p (tree);
526e4b17023SJohn Marino void cgraph_unnest_node (struct cgraph_node *);
527e4b17023SJohn Marino 
528e4b17023SJohn Marino enum availability cgraph_function_body_availability (struct cgraph_node *);
529e4b17023SJohn Marino void cgraph_add_new_function (tree, bool);
530e4b17023SJohn Marino const char* cgraph_inline_failed_string (cgraph_inline_failed_t);
531e4b17023SJohn Marino struct cgraph_node * cgraph_create_virtual_clone (struct cgraph_node *old_node,
532e4b17023SJohn Marino 			                          VEC(cgraph_edge_p,heap)*,
533e4b17023SJohn Marino 			                          VEC(ipa_replace_map_p,gc)* tree_map,
534e4b17023SJohn Marino 			                          bitmap args_to_skip,
535e4b17023SJohn Marino 						  const char *clone_name);
536e4b17023SJohn Marino 
537e4b17023SJohn Marino void cgraph_set_nothrow_flag (struct cgraph_node *, bool);
538e4b17023SJohn Marino void cgraph_set_const_flag (struct cgraph_node *, bool, bool);
539e4b17023SJohn Marino void cgraph_set_pure_flag (struct cgraph_node *, bool, bool);
540e4b17023SJohn Marino tree clone_function_name (tree decl, const char *);
541e4b17023SJohn Marino bool cgraph_node_cannot_return (struct cgraph_node *);
542e4b17023SJohn Marino bool cgraph_edge_cannot_lead_to_return (struct cgraph_edge *);
543e4b17023SJohn Marino bool cgraph_will_be_removed_from_program_if_no_direct_calls
544e4b17023SJohn Marino   (struct cgraph_node *node);
545e4b17023SJohn Marino bool cgraph_can_remove_if_no_direct_calls_and_refs_p
546e4b17023SJohn Marino   (struct cgraph_node *node);
547e4b17023SJohn Marino bool cgraph_can_remove_if_no_direct_calls_p (struct cgraph_node *node);
548e4b17023SJohn Marino bool resolution_used_from_other_file_p (enum ld_plugin_symbol_resolution);
549e4b17023SJohn Marino bool cgraph_used_from_object_file_p (struct cgraph_node *);
550e4b17023SJohn Marino bool varpool_used_from_object_file_p (struct varpool_node *);
551e4b17023SJohn Marino bool cgraph_for_node_thunks_and_aliases (struct cgraph_node *,
552e4b17023SJohn Marino 			                 bool (*) (struct cgraph_node *, void *),
553e4b17023SJohn Marino 			                 void *,
554e4b17023SJohn Marino 					 bool);
555e4b17023SJohn Marino bool cgraph_for_node_and_aliases (struct cgraph_node *,
556e4b17023SJohn Marino 		                  bool (*) (struct cgraph_node *, void *),
557e4b17023SJohn Marino 			          void *, bool);
558e4b17023SJohn Marino VEC (cgraph_edge_p, heap) * collect_callers_of_node (struct cgraph_node *node);
559e4b17023SJohn Marino 
560e4b17023SJohn Marino 
561e4b17023SJohn Marino /* In cgraphunit.c  */
562e4b17023SJohn Marino extern FILE *cgraph_dump_file;
563e4b17023SJohn Marino void cgraph_finalize_function (tree, bool);
564e4b17023SJohn Marino void cgraph_mark_if_needed (tree);
565e4b17023SJohn Marino void cgraph_analyze_function (struct cgraph_node *);
566e4b17023SJohn Marino void cgraph_finalize_compilation_unit (void);
567e4b17023SJohn Marino void cgraph_optimize (void);
568e4b17023SJohn Marino void cgraph_mark_needed_node (struct cgraph_node *);
569e4b17023SJohn Marino void cgraph_mark_address_taken_node (struct cgraph_node *);
570e4b17023SJohn Marino void cgraph_mark_reachable_node (struct cgraph_node *);
571e4b17023SJohn Marino bool cgraph_inline_p (struct cgraph_edge *, cgraph_inline_failed_t *reason);
572e4b17023SJohn Marino bool cgraph_preserve_function_body_p (struct cgraph_node *);
573e4b17023SJohn Marino void verify_cgraph (void);
574e4b17023SJohn Marino void verify_cgraph_node (struct cgraph_node *);
575e4b17023SJohn Marino void cgraph_build_static_cdtor (char which, tree body, int priority);
576e4b17023SJohn Marino void cgraph_reset_static_var_maps (void);
577e4b17023SJohn Marino void init_cgraph (void);
578e4b17023SJohn Marino struct cgraph_node * cgraph_copy_node_for_versioning (struct cgraph_node *,
579e4b17023SJohn Marino 		tree, VEC(cgraph_edge_p,heap)*, bitmap);
580e4b17023SJohn Marino struct cgraph_node *cgraph_function_versioning (struct cgraph_node *,
581e4b17023SJohn Marino 						VEC(cgraph_edge_p,heap)*,
582e4b17023SJohn Marino 						VEC(ipa_replace_map_p,gc)*,
583e4b17023SJohn Marino 						bitmap, bool, bitmap,
584e4b17023SJohn Marino 						basic_block, const char *);
585e4b17023SJohn Marino void tree_function_versioning (tree, tree, VEC (ipa_replace_map_p,gc)*,
586e4b17023SJohn Marino 			       bool, bitmap, bool, bitmap, basic_block);
587e4b17023SJohn Marino void record_references_in_initializer (tree, bool);
588e4b17023SJohn Marino bool cgraph_process_new_functions (void);
589e4b17023SJohn Marino void cgraph_process_same_body_aliases (void);
590e4b17023SJohn Marino 
591e4b17023SJohn Marino bool cgraph_decide_is_function_needed (struct cgraph_node *, tree);
592e4b17023SJohn Marino 
593e4b17023SJohn Marino typedef void (*cgraph_edge_hook)(struct cgraph_edge *, void *);
594e4b17023SJohn Marino typedef void (*cgraph_node_hook)(struct cgraph_node *, void *);
595e4b17023SJohn Marino typedef void (*cgraph_2edge_hook)(struct cgraph_edge *, struct cgraph_edge *,
596e4b17023SJohn Marino 				  void *);
597e4b17023SJohn Marino typedef void (*cgraph_2node_hook)(struct cgraph_node *, struct cgraph_node *,
598e4b17023SJohn Marino 				  void *);
599e4b17023SJohn Marino struct cgraph_edge_hook_list;
600e4b17023SJohn Marino struct cgraph_node_hook_list;
601e4b17023SJohn Marino struct cgraph_2edge_hook_list;
602e4b17023SJohn Marino struct cgraph_2node_hook_list;
603e4b17023SJohn Marino struct cgraph_edge_hook_list *cgraph_add_edge_removal_hook (cgraph_edge_hook, void *);
604e4b17023SJohn Marino void cgraph_remove_edge_removal_hook (struct cgraph_edge_hook_list *);
605e4b17023SJohn Marino struct cgraph_node_hook_list *cgraph_add_node_removal_hook (cgraph_node_hook,
606e4b17023SJohn Marino 							    void *);
607e4b17023SJohn Marino void cgraph_remove_node_removal_hook (struct cgraph_node_hook_list *);
608e4b17023SJohn Marino struct cgraph_node_hook_list *cgraph_add_function_insertion_hook (cgraph_node_hook,
609e4b17023SJohn Marino 							          void *);
610e4b17023SJohn Marino void cgraph_remove_function_insertion_hook (struct cgraph_node_hook_list *);
611e4b17023SJohn Marino void cgraph_call_function_insertion_hooks (struct cgraph_node *node);
612e4b17023SJohn Marino struct cgraph_2edge_hook_list *cgraph_add_edge_duplication_hook (cgraph_2edge_hook, void *);
613e4b17023SJohn Marino void cgraph_remove_edge_duplication_hook (struct cgraph_2edge_hook_list *);
614e4b17023SJohn Marino struct cgraph_2node_hook_list *cgraph_add_node_duplication_hook (cgraph_2node_hook, void *);
615e4b17023SJohn Marino void cgraph_remove_node_duplication_hook (struct cgraph_2node_hook_list *);
616e4b17023SJohn Marino void cgraph_materialize_all_clones (void);
617e4b17023SJohn Marino gimple cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *);
618e4b17023SJohn Marino bool cgraph_propagate_frequency (struct cgraph_node *node);
619e4b17023SJohn Marino /* In cgraphbuild.c  */
620e4b17023SJohn Marino unsigned int rebuild_cgraph_edges (void);
621e4b17023SJohn Marino void cgraph_rebuild_references (void);
622e4b17023SJohn Marino void reset_inline_failed (struct cgraph_node *);
623e4b17023SJohn Marino int compute_call_stmt_bb_frequency (tree, basic_block bb);
624e4b17023SJohn Marino 
625e4b17023SJohn Marino /* In ipa.c  */
626e4b17023SJohn Marino bool cgraph_remove_unreachable_nodes (bool, FILE *);
627e4b17023SJohn Marino cgraph_node_set cgraph_node_set_new (void);
628e4b17023SJohn Marino cgraph_node_set_iterator cgraph_node_set_find (cgraph_node_set,
629e4b17023SJohn Marino 					       struct cgraph_node *);
630e4b17023SJohn Marino void cgraph_node_set_add (cgraph_node_set, struct cgraph_node *);
631e4b17023SJohn Marino void cgraph_node_set_remove (cgraph_node_set, struct cgraph_node *);
632e4b17023SJohn Marino void dump_cgraph_node_set (FILE *, cgraph_node_set);
633e4b17023SJohn Marino void debug_cgraph_node_set (cgraph_node_set);
634e4b17023SJohn Marino void free_cgraph_node_set (cgraph_node_set);
635e4b17023SJohn Marino 
636e4b17023SJohn Marino varpool_node_set varpool_node_set_new (void);
637e4b17023SJohn Marino varpool_node_set_iterator varpool_node_set_find (varpool_node_set,
638e4b17023SJohn Marino 					       struct varpool_node *);
639e4b17023SJohn Marino void varpool_node_set_add (varpool_node_set, struct varpool_node *);
640e4b17023SJohn Marino void varpool_node_set_remove (varpool_node_set, struct varpool_node *);
641e4b17023SJohn Marino void dump_varpool_node_set (FILE *, varpool_node_set);
642e4b17023SJohn Marino void debug_varpool_node_set (varpool_node_set);
643e4b17023SJohn Marino void free_varpool_node_set (varpool_node_set);
644e4b17023SJohn Marino void ipa_discover_readonly_nonaddressable_vars (void);
645e4b17023SJohn Marino bool cgraph_comdat_can_be_unshared_p (struct cgraph_node *);
646e4b17023SJohn Marino bool varpool_externally_visible_p (struct varpool_node *, bool);
647e4b17023SJohn Marino 
648e4b17023SJohn Marino /* In predict.c  */
649e4b17023SJohn Marino bool cgraph_maybe_hot_edge_p (struct cgraph_edge *e);
650e4b17023SJohn Marino bool cgraph_optimize_for_size_p (struct cgraph_node *);
651e4b17023SJohn Marino 
652e4b17023SJohn Marino /* In varpool.c  */
653e4b17023SJohn Marino extern GTY(()) struct varpool_node *varpool_nodes_queue;
654e4b17023SJohn Marino extern GTY(()) struct varpool_node *varpool_nodes;
655e4b17023SJohn Marino 
656e4b17023SJohn Marino struct varpool_node *varpool_node (tree);
657e4b17023SJohn Marino struct varpool_node *varpool_node_for_asm (tree asmname);
658e4b17023SJohn Marino void varpool_mark_needed_node (struct varpool_node *);
659e4b17023SJohn Marino void debug_varpool (void);
660e4b17023SJohn Marino void dump_varpool (FILE *);
661e4b17023SJohn Marino void dump_varpool_node (FILE *, struct varpool_node *);
662e4b17023SJohn Marino 
663e4b17023SJohn Marino void varpool_finalize_decl (tree);
664e4b17023SJohn Marino bool decide_is_variable_needed (struct varpool_node *, tree);
665e4b17023SJohn Marino enum availability cgraph_variable_initializer_availability (struct varpool_node *);
666e4b17023SJohn Marino void cgraph_make_decl_local (tree);
667e4b17023SJohn Marino void cgraph_make_node_local (struct cgraph_node *);
668e4b17023SJohn Marino bool cgraph_node_can_be_local_p (struct cgraph_node *);
669e4b17023SJohn Marino 
670e4b17023SJohn Marino 
671e4b17023SJohn Marino struct varpool_node * varpool_get_node (const_tree decl);
672e4b17023SJohn Marino void varpool_remove_node (struct varpool_node *node);
673e4b17023SJohn Marino void varpool_finalize_named_section_flags (struct varpool_node *node);
674e4b17023SJohn Marino bool varpool_assemble_pending_decls (void);
675e4b17023SJohn Marino bool varpool_assemble_decl (struct varpool_node *node);
676e4b17023SJohn Marino bool varpool_analyze_pending_decls (void);
677e4b17023SJohn Marino void varpool_remove_unreferenced_decls (void);
678e4b17023SJohn Marino void varpool_empty_needed_queue (void);
679e4b17023SJohn Marino struct varpool_node * varpool_extra_name_alias (tree, tree);
680e4b17023SJohn Marino struct varpool_node * varpool_create_variable_alias (tree, tree);
681e4b17023SJohn Marino const char * varpool_node_name (struct varpool_node *node);
682e4b17023SJohn Marino void varpool_reset_queue (void);
683e4b17023SJohn Marino bool const_value_known_p (tree);
684e4b17023SJohn Marino bool varpool_for_node_and_aliases (struct varpool_node *,
685e4b17023SJohn Marino 		                   bool (*) (struct varpool_node *, void *),
686e4b17023SJohn Marino 			           void *, bool);
687e4b17023SJohn Marino void varpool_add_new_variable (tree);
688e4b17023SJohn Marino 
689e4b17023SJohn Marino /* Walk all reachable static variables.  */
690e4b17023SJohn Marino #define FOR_EACH_STATIC_VARIABLE(node) \
691e4b17023SJohn Marino    for ((node) = varpool_nodes_queue; (node); (node) = (node)->next_needed)
692e4b17023SJohn Marino 
693e4b17023SJohn Marino /* Return first reachable static variable with initializer.  */
694e4b17023SJohn Marino static inline struct varpool_node *
varpool_first_static_initializer(void)695e4b17023SJohn Marino varpool_first_static_initializer (void)
696e4b17023SJohn Marino {
697e4b17023SJohn Marino   struct varpool_node *node;
698e4b17023SJohn Marino   for (node = varpool_nodes_queue; node; node = node->next_needed)
699e4b17023SJohn Marino     {
700e4b17023SJohn Marino       gcc_checking_assert (TREE_CODE (node->decl) == VAR_DECL);
701e4b17023SJohn Marino       if (DECL_INITIAL (node->decl))
702e4b17023SJohn Marino 	return node;
703e4b17023SJohn Marino     }
704e4b17023SJohn Marino   return NULL;
705e4b17023SJohn Marino }
706e4b17023SJohn Marino 
707e4b17023SJohn Marino /* Return next reachable static variable with initializer after NODE.  */
708e4b17023SJohn Marino static inline struct varpool_node *
varpool_next_static_initializer(struct varpool_node * node)709e4b17023SJohn Marino varpool_next_static_initializer (struct varpool_node *node)
710e4b17023SJohn Marino {
711e4b17023SJohn Marino   for (node = node->next_needed; node; node = node->next_needed)
712e4b17023SJohn Marino     {
713e4b17023SJohn Marino       gcc_checking_assert (TREE_CODE (node->decl) == VAR_DECL);
714e4b17023SJohn Marino       if (DECL_INITIAL (node->decl))
715e4b17023SJohn Marino 	return node;
716e4b17023SJohn Marino     }
717e4b17023SJohn Marino   return NULL;
718e4b17023SJohn Marino }
719e4b17023SJohn Marino 
720e4b17023SJohn Marino /* Walk all static variables with initializer set.  */
721e4b17023SJohn Marino #define FOR_EACH_STATIC_INITIALIZER(node) \
722e4b17023SJohn Marino    for ((node) = varpool_first_static_initializer (); (node); \
723e4b17023SJohn Marino         (node) = varpool_next_static_initializer (node))
724e4b17023SJohn Marino 
725e4b17023SJohn Marino /* Return first function with body defined.  */
726e4b17023SJohn Marino static inline struct cgraph_node *
cgraph_first_defined_function(void)727e4b17023SJohn Marino cgraph_first_defined_function (void)
728e4b17023SJohn Marino {
729e4b17023SJohn Marino   struct cgraph_node *node;
730e4b17023SJohn Marino   for (node = cgraph_nodes; node; node = node->next)
731e4b17023SJohn Marino     {
732e4b17023SJohn Marino       if (node->analyzed)
733e4b17023SJohn Marino 	return node;
734e4b17023SJohn Marino     }
735e4b17023SJohn Marino   return NULL;
736e4b17023SJohn Marino }
737e4b17023SJohn Marino 
738e4b17023SJohn Marino /* Return next function with body defined after NODE.  */
739e4b17023SJohn Marino static inline struct cgraph_node *
cgraph_next_defined_function(struct cgraph_node * node)740e4b17023SJohn Marino cgraph_next_defined_function (struct cgraph_node *node)
741e4b17023SJohn Marino {
742e4b17023SJohn Marino   for (node = node->next; node; node = node->next)
743e4b17023SJohn Marino     {
744e4b17023SJohn Marino       if (node->analyzed)
745e4b17023SJohn Marino 	return node;
746e4b17023SJohn Marino     }
747e4b17023SJohn Marino   return NULL;
748e4b17023SJohn Marino }
749e4b17023SJohn Marino 
750e4b17023SJohn Marino /* Walk all functions with body defined.  */
751e4b17023SJohn Marino #define FOR_EACH_DEFINED_FUNCTION(node) \
752e4b17023SJohn Marino    for ((node) = cgraph_first_defined_function (); (node); \
753e4b17023SJohn Marino         (node) = cgraph_next_defined_function (node))
754e4b17023SJohn Marino 
755e4b17023SJohn Marino 
756e4b17023SJohn Marino /* Return true when NODE is a function with Gimple body defined
757e4b17023SJohn Marino    in current unit.  Functions can also be define externally or they
758e4b17023SJohn Marino    can be thunks with no Gimple representation.
759e4b17023SJohn Marino 
760e4b17023SJohn Marino    Note that at WPA stage, the function body may not be present in memory.  */
761e4b17023SJohn Marino 
762e4b17023SJohn Marino static inline bool
cgraph_function_with_gimple_body_p(struct cgraph_node * node)763e4b17023SJohn Marino cgraph_function_with_gimple_body_p (struct cgraph_node *node)
764e4b17023SJohn Marino {
765e4b17023SJohn Marino   return node->analyzed && !node->thunk.thunk_p && !node->alias;
766e4b17023SJohn Marino }
767e4b17023SJohn Marino 
768e4b17023SJohn Marino /* Return first function with body defined.  */
769e4b17023SJohn Marino static inline struct cgraph_node *
cgraph_first_function_with_gimple_body(void)770e4b17023SJohn Marino cgraph_first_function_with_gimple_body (void)
771e4b17023SJohn Marino {
772e4b17023SJohn Marino   struct cgraph_node *node;
773e4b17023SJohn Marino   for (node = cgraph_nodes; node; node = node->next)
774e4b17023SJohn Marino     {
775e4b17023SJohn Marino       if (cgraph_function_with_gimple_body_p (node))
776e4b17023SJohn Marino 	return node;
777e4b17023SJohn Marino     }
778e4b17023SJohn Marino   return NULL;
779e4b17023SJohn Marino }
780e4b17023SJohn Marino 
781e4b17023SJohn Marino /* Return next reachable static variable with initializer after NODE.  */
782e4b17023SJohn Marino static inline struct cgraph_node *
cgraph_next_function_with_gimple_body(struct cgraph_node * node)783e4b17023SJohn Marino cgraph_next_function_with_gimple_body (struct cgraph_node *node)
784e4b17023SJohn Marino {
785e4b17023SJohn Marino   for (node = node->next; node; node = node->next)
786e4b17023SJohn Marino     {
787e4b17023SJohn Marino       if (cgraph_function_with_gimple_body_p (node))
788e4b17023SJohn Marino 	return node;
789e4b17023SJohn Marino     }
790e4b17023SJohn Marino   return NULL;
791e4b17023SJohn Marino }
792e4b17023SJohn Marino 
793e4b17023SJohn Marino /* Walk all functions with body defined.  */
794e4b17023SJohn Marino #define FOR_EACH_FUNCTION_WITH_GIMPLE_BODY(node) \
795e4b17023SJohn Marino    for ((node) = cgraph_first_function_with_gimple_body (); (node); \
796e4b17023SJohn Marino         (node) = cgraph_next_function_with_gimple_body (node))
797e4b17023SJohn Marino 
798e4b17023SJohn Marino /* Create a new static variable of type TYPE.  */
799e4b17023SJohn Marino tree add_new_static_var (tree type);
800e4b17023SJohn Marino 
801e4b17023SJohn Marino /* Return true if iterator CSI points to nothing.  */
802e4b17023SJohn Marino static inline bool
csi_end_p(cgraph_node_set_iterator csi)803e4b17023SJohn Marino csi_end_p (cgraph_node_set_iterator csi)
804e4b17023SJohn Marino {
805e4b17023SJohn Marino   return csi.index >= VEC_length (cgraph_node_ptr, csi.set->nodes);
806e4b17023SJohn Marino }
807e4b17023SJohn Marino 
808e4b17023SJohn Marino /* Advance iterator CSI.  */
809e4b17023SJohn Marino static inline void
csi_next(cgraph_node_set_iterator * csi)810e4b17023SJohn Marino csi_next (cgraph_node_set_iterator *csi)
811e4b17023SJohn Marino {
812e4b17023SJohn Marino   csi->index++;
813e4b17023SJohn Marino }
814e4b17023SJohn Marino 
815e4b17023SJohn Marino /* Return the node pointed to by CSI.  */
816e4b17023SJohn Marino static inline struct cgraph_node *
csi_node(cgraph_node_set_iterator csi)817e4b17023SJohn Marino csi_node (cgraph_node_set_iterator csi)
818e4b17023SJohn Marino {
819e4b17023SJohn Marino   return VEC_index (cgraph_node_ptr, csi.set->nodes, csi.index);
820e4b17023SJohn Marino }
821e4b17023SJohn Marino 
822e4b17023SJohn Marino /* Return an iterator to the first node in SET.  */
823e4b17023SJohn Marino static inline cgraph_node_set_iterator
csi_start(cgraph_node_set set)824e4b17023SJohn Marino csi_start (cgraph_node_set set)
825e4b17023SJohn Marino {
826e4b17023SJohn Marino   cgraph_node_set_iterator csi;
827e4b17023SJohn Marino 
828e4b17023SJohn Marino   csi.set = set;
829e4b17023SJohn Marino   csi.index = 0;
830e4b17023SJohn Marino   return csi;
831e4b17023SJohn Marino }
832e4b17023SJohn Marino 
833e4b17023SJohn Marino /* Return true if SET contains NODE.  */
834e4b17023SJohn Marino static inline bool
cgraph_node_in_set_p(struct cgraph_node * node,cgraph_node_set set)835e4b17023SJohn Marino cgraph_node_in_set_p (struct cgraph_node *node, cgraph_node_set set)
836e4b17023SJohn Marino {
837e4b17023SJohn Marino   cgraph_node_set_iterator csi;
838e4b17023SJohn Marino   csi = cgraph_node_set_find (set, node);
839e4b17023SJohn Marino   return !csi_end_p (csi);
840e4b17023SJohn Marino }
841e4b17023SJohn Marino 
842e4b17023SJohn Marino /* Return number of nodes in SET.  */
843e4b17023SJohn Marino static inline size_t
cgraph_node_set_size(cgraph_node_set set)844e4b17023SJohn Marino cgraph_node_set_size (cgraph_node_set set)
845e4b17023SJohn Marino {
846e4b17023SJohn Marino   return VEC_length (cgraph_node_ptr, set->nodes);
847e4b17023SJohn Marino }
848e4b17023SJohn Marino 
849e4b17023SJohn Marino /* Return true if iterator VSI points to nothing.  */
850e4b17023SJohn Marino static inline bool
vsi_end_p(varpool_node_set_iterator vsi)851e4b17023SJohn Marino vsi_end_p (varpool_node_set_iterator vsi)
852e4b17023SJohn Marino {
853e4b17023SJohn Marino   return vsi.index >= VEC_length (varpool_node_ptr, vsi.set->nodes);
854e4b17023SJohn Marino }
855e4b17023SJohn Marino 
856e4b17023SJohn Marino /* Advance iterator VSI.  */
857e4b17023SJohn Marino static inline void
vsi_next(varpool_node_set_iterator * vsi)858e4b17023SJohn Marino vsi_next (varpool_node_set_iterator *vsi)
859e4b17023SJohn Marino {
860e4b17023SJohn Marino   vsi->index++;
861e4b17023SJohn Marino }
862e4b17023SJohn Marino 
863e4b17023SJohn Marino /* Return the node pointed to by VSI.  */
864e4b17023SJohn Marino static inline struct varpool_node *
vsi_node(varpool_node_set_iterator vsi)865e4b17023SJohn Marino vsi_node (varpool_node_set_iterator vsi)
866e4b17023SJohn Marino {
867e4b17023SJohn Marino   return VEC_index (varpool_node_ptr, vsi.set->nodes, vsi.index);
868e4b17023SJohn Marino }
869e4b17023SJohn Marino 
870e4b17023SJohn Marino /* Return an iterator to the first node in SET.  */
871e4b17023SJohn Marino static inline varpool_node_set_iterator
vsi_start(varpool_node_set set)872e4b17023SJohn Marino vsi_start (varpool_node_set set)
873e4b17023SJohn Marino {
874e4b17023SJohn Marino   varpool_node_set_iterator vsi;
875e4b17023SJohn Marino 
876e4b17023SJohn Marino   vsi.set = set;
877e4b17023SJohn Marino   vsi.index = 0;
878e4b17023SJohn Marino   return vsi;
879e4b17023SJohn Marino }
880e4b17023SJohn Marino 
881e4b17023SJohn Marino /* Return true if SET contains NODE.  */
882e4b17023SJohn Marino static inline bool
varpool_node_in_set_p(struct varpool_node * node,varpool_node_set set)883e4b17023SJohn Marino varpool_node_in_set_p (struct varpool_node *node, varpool_node_set set)
884e4b17023SJohn Marino {
885e4b17023SJohn Marino   varpool_node_set_iterator vsi;
886e4b17023SJohn Marino   vsi = varpool_node_set_find (set, node);
887e4b17023SJohn Marino   return !vsi_end_p (vsi);
888e4b17023SJohn Marino }
889e4b17023SJohn Marino 
890e4b17023SJohn Marino /* Return number of nodes in SET.  */
891e4b17023SJohn Marino static inline size_t
varpool_node_set_size(varpool_node_set set)892e4b17023SJohn Marino varpool_node_set_size (varpool_node_set set)
893e4b17023SJohn Marino {
894e4b17023SJohn Marino   return VEC_length (varpool_node_ptr, set->nodes);
895e4b17023SJohn Marino }
896e4b17023SJohn Marino 
897e4b17023SJohn Marino /* Uniquize all constants that appear in memory.
898e4b17023SJohn Marino    Each constant in memory thus far output is recorded
899e4b17023SJohn Marino    in `const_desc_table'.  */
900e4b17023SJohn Marino 
901e4b17023SJohn Marino struct GTY(()) constant_descriptor_tree {
902e4b17023SJohn Marino   /* A MEM for the constant.  */
903e4b17023SJohn Marino   rtx rtl;
904e4b17023SJohn Marino 
905e4b17023SJohn Marino   /* The value of the constant.  */
906e4b17023SJohn Marino   tree value;
907e4b17023SJohn Marino 
908e4b17023SJohn Marino   /* Hash of value.  Computing the hash from value each time
909e4b17023SJohn Marino      hashfn is called can't work properly, as that means recursive
910e4b17023SJohn Marino      use of the hash table during hash table expansion.  */
911e4b17023SJohn Marino   hashval_t hash;
912e4b17023SJohn Marino };
913e4b17023SJohn Marino 
914e4b17023SJohn Marino /* Return true if set is nonempty.  */
915e4b17023SJohn Marino static inline bool
cgraph_node_set_nonempty_p(cgraph_node_set set)916e4b17023SJohn Marino cgraph_node_set_nonempty_p (cgraph_node_set set)
917e4b17023SJohn Marino {
918e4b17023SJohn Marino   return !VEC_empty (cgraph_node_ptr, set->nodes);
919e4b17023SJohn Marino }
920e4b17023SJohn Marino 
921e4b17023SJohn Marino /* Return true if set is nonempty.  */
922e4b17023SJohn Marino static inline bool
varpool_node_set_nonempty_p(varpool_node_set set)923e4b17023SJohn Marino varpool_node_set_nonempty_p (varpool_node_set set)
924e4b17023SJohn Marino {
925e4b17023SJohn Marino   return !VEC_empty (varpool_node_ptr, set->nodes);
926e4b17023SJohn Marino }
927e4b17023SJohn Marino 
928e4b17023SJohn Marino /* Return true when function NODE is only called directly or it has alias.
929e4b17023SJohn Marino    i.e. it is not externally visible, address was not taken and
930e4b17023SJohn Marino    it is not used in any other non-standard way.  */
931e4b17023SJohn Marino 
932e4b17023SJohn Marino static inline bool
cgraph_only_called_directly_or_aliased_p(struct cgraph_node * node)933e4b17023SJohn Marino cgraph_only_called_directly_or_aliased_p (struct cgraph_node *node)
934e4b17023SJohn Marino {
935e4b17023SJohn Marino   gcc_assert (!node->global.inlined_to);
936e4b17023SJohn Marino   return (!node->needed && !node->address_taken
937e4b17023SJohn Marino 	  && !node->reachable_from_other_partition
938*5ce9237cSJohn Marino 	  && !DECL_VIRTUAL_P (node->decl)
939e4b17023SJohn Marino 	  && !DECL_STATIC_CONSTRUCTOR (node->decl)
940e4b17023SJohn Marino 	  && !DECL_STATIC_DESTRUCTOR (node->decl)
941e4b17023SJohn Marino 	  && !node->local.externally_visible);
942e4b17023SJohn Marino }
943e4b17023SJohn Marino 
944e4b17023SJohn Marino /* Return true when function NODE can be removed from callgraph
945e4b17023SJohn Marino    if all direct calls are eliminated.  */
946e4b17023SJohn Marino 
947e4b17023SJohn Marino static inline bool
varpool_can_remove_if_no_refs(struct varpool_node * node)948e4b17023SJohn Marino varpool_can_remove_if_no_refs (struct varpool_node *node)
949e4b17023SJohn Marino {
950e4b17023SJohn Marino   if (DECL_EXTERNAL (node->decl))
951e4b17023SJohn Marino     return true;
952e4b17023SJohn Marino   return (!node->force_output && !node->used_from_other_partition
953e4b17023SJohn Marino 	  && ((DECL_COMDAT (node->decl)
954e4b17023SJohn Marino 	       && !varpool_used_from_object_file_p (node))
955e4b17023SJohn Marino 	      || (flag_toplevel_reorder && !node->externally_visible)
956e4b17023SJohn Marino 	      || DECL_HAS_VALUE_EXPR_P (node->decl)));
957e4b17023SJohn Marino }
958e4b17023SJohn Marino 
959e4b17023SJohn Marino /* Return true when all references to VNODE must be visible in ipa_ref_list.
960e4b17023SJohn Marino    i.e. if the variable is not externally visible or not used in some magic
961e4b17023SJohn Marino    way (asm statement or such).
962e4b17023SJohn Marino    The magic uses are all summarized in force_output flag.  */
963e4b17023SJohn Marino 
964e4b17023SJohn Marino static inline bool
varpool_all_refs_explicit_p(struct varpool_node * vnode)965e4b17023SJohn Marino varpool_all_refs_explicit_p (struct varpool_node *vnode)
966e4b17023SJohn Marino {
967e4b17023SJohn Marino   return (vnode->analyzed
968e4b17023SJohn Marino 	  && !vnode->externally_visible
969e4b17023SJohn Marino 	  && !vnode->used_from_other_partition
970e4b17023SJohn Marino 	  && !vnode->force_output);
971e4b17023SJohn Marino }
972e4b17023SJohn Marino 
973e4b17023SJohn Marino /* Constant pool accessor function.  */
974e4b17023SJohn Marino htab_t constant_pool_htab (void);
975e4b17023SJohn Marino 
976e4b17023SJohn Marino /* FIXME: inappropriate dependency of cgraph on IPA.  */
977e4b17023SJohn Marino #include "ipa-ref-inline.h"
978e4b17023SJohn Marino 
979e4b17023SJohn Marino /* Return node that alias N is aliasing.  */
980e4b17023SJohn Marino 
981e4b17023SJohn Marino static inline struct cgraph_node *
cgraph_alias_aliased_node(struct cgraph_node * n)982e4b17023SJohn Marino cgraph_alias_aliased_node (struct cgraph_node *n)
983e4b17023SJohn Marino {
984e4b17023SJohn Marino   struct ipa_ref *ref;
985e4b17023SJohn Marino 
986e4b17023SJohn Marino   ipa_ref_list_reference_iterate (&n->ref_list, 0, ref);
987e4b17023SJohn Marino   gcc_checking_assert (ref->use == IPA_REF_ALIAS);
988e4b17023SJohn Marino   if (ref->refered_type == IPA_REF_CGRAPH)
989e4b17023SJohn Marino     return ipa_ref_node (ref);
990e4b17023SJohn Marino   return NULL;
991e4b17023SJohn Marino }
992e4b17023SJohn Marino 
993e4b17023SJohn Marino /* Return node that alias N is aliasing.  */
994e4b17023SJohn Marino 
995e4b17023SJohn Marino static inline struct varpool_node *
varpool_alias_aliased_node(struct varpool_node * n)996e4b17023SJohn Marino varpool_alias_aliased_node (struct varpool_node *n)
997e4b17023SJohn Marino {
998e4b17023SJohn Marino   struct ipa_ref *ref;
999e4b17023SJohn Marino 
1000e4b17023SJohn Marino   ipa_ref_list_reference_iterate (&n->ref_list, 0, ref);
1001e4b17023SJohn Marino   gcc_checking_assert (ref->use == IPA_REF_ALIAS);
1002e4b17023SJohn Marino   if (ref->refered_type == IPA_REF_VARPOOL)
1003e4b17023SJohn Marino     return ipa_ref_varpool_node (ref);
1004e4b17023SJohn Marino   return NULL;
1005e4b17023SJohn Marino }
1006e4b17023SJohn Marino 
1007e4b17023SJohn Marino /* Given NODE, walk the alias chain to return the function NODE is alias of.
1008e4b17023SJohn Marino    Walk through thunk, too.
1009e4b17023SJohn Marino    When AVAILABILITY is non-NULL, get minimal availablity in the chain.  */
1010e4b17023SJohn Marino 
1011e4b17023SJohn Marino static inline struct cgraph_node *
cgraph_function_node(struct cgraph_node * node,enum availability * availability)1012e4b17023SJohn Marino cgraph_function_node (struct cgraph_node *node, enum availability *availability)
1013e4b17023SJohn Marino {
1014e4b17023SJohn Marino   if (availability)
1015e4b17023SJohn Marino     *availability = cgraph_function_body_availability (node);
1016e4b17023SJohn Marino   while (node)
1017e4b17023SJohn Marino     {
1018e4b17023SJohn Marino       if (node->alias && node->analyzed)
1019e4b17023SJohn Marino 	node = cgraph_alias_aliased_node (node);
1020e4b17023SJohn Marino       else if (node->thunk.thunk_p)
1021e4b17023SJohn Marino 	node = node->callees->callee;
1022e4b17023SJohn Marino       else
1023e4b17023SJohn Marino 	return node;
1024e4b17023SJohn Marino       if (node && availability)
1025e4b17023SJohn Marino 	{
1026e4b17023SJohn Marino 	  enum availability a;
1027e4b17023SJohn Marino 	  a = cgraph_function_body_availability (node);
1028e4b17023SJohn Marino 	  if (a < *availability)
1029e4b17023SJohn Marino 	    *availability = a;
1030e4b17023SJohn Marino 	}
1031e4b17023SJohn Marino     }
1032e4b17023SJohn Marino   if (availability)
1033e4b17023SJohn Marino     *availability = AVAIL_NOT_AVAILABLE;
1034e4b17023SJohn Marino   return NULL;
1035e4b17023SJohn Marino }
1036e4b17023SJohn Marino 
1037e4b17023SJohn Marino /* Given NODE, walk the alias chain to return the function NODE is alias of.
1038e4b17023SJohn Marino    Do not walk through thunks.
1039e4b17023SJohn Marino    When AVAILABILITY is non-NULL, get minimal availablity in the chain.  */
1040e4b17023SJohn Marino 
1041e4b17023SJohn Marino static inline struct cgraph_node *
cgraph_function_or_thunk_node(struct cgraph_node * node,enum availability * availability)1042e4b17023SJohn Marino cgraph_function_or_thunk_node (struct cgraph_node *node, enum availability *availability)
1043e4b17023SJohn Marino {
1044e4b17023SJohn Marino   if (availability)
1045e4b17023SJohn Marino     *availability = cgraph_function_body_availability (node);
1046e4b17023SJohn Marino   while (node)
1047e4b17023SJohn Marino     {
1048e4b17023SJohn Marino       if (node->alias && node->analyzed)
1049e4b17023SJohn Marino 	node = cgraph_alias_aliased_node (node);
1050e4b17023SJohn Marino       else
1051e4b17023SJohn Marino 	return node;
1052e4b17023SJohn Marino       if (node && availability)
1053e4b17023SJohn Marino 	{
1054e4b17023SJohn Marino 	  enum availability a;
1055e4b17023SJohn Marino 	  a = cgraph_function_body_availability (node);
1056e4b17023SJohn Marino 	  if (a < *availability)
1057e4b17023SJohn Marino 	    *availability = a;
1058e4b17023SJohn Marino 	}
1059e4b17023SJohn Marino     }
1060e4b17023SJohn Marino   if (availability)
1061e4b17023SJohn Marino     *availability = AVAIL_NOT_AVAILABLE;
1062e4b17023SJohn Marino   return NULL;
1063e4b17023SJohn Marino }
1064e4b17023SJohn Marino 
1065e4b17023SJohn Marino /* Given NODE, walk the alias chain to return the function NODE is alias of.
1066e4b17023SJohn Marino    Do not walk through thunks.
1067e4b17023SJohn Marino    When AVAILABILITY is non-NULL, get minimal availablity in the chain.  */
1068e4b17023SJohn Marino 
1069e4b17023SJohn Marino static inline struct varpool_node *
varpool_variable_node(struct varpool_node * node,enum availability * availability)1070e4b17023SJohn Marino varpool_variable_node (struct varpool_node *node, enum availability *availability)
1071e4b17023SJohn Marino {
1072e4b17023SJohn Marino   if (availability)
1073e4b17023SJohn Marino     *availability = cgraph_variable_initializer_availability (node);
1074e4b17023SJohn Marino   while (node)
1075e4b17023SJohn Marino     {
1076e4b17023SJohn Marino       if (node->alias && node->analyzed)
1077e4b17023SJohn Marino 	node = varpool_alias_aliased_node (node);
1078e4b17023SJohn Marino       else
1079e4b17023SJohn Marino 	return node;
1080e4b17023SJohn Marino       if (node && availability)
1081e4b17023SJohn Marino 	{
1082e4b17023SJohn Marino 	  enum availability a;
1083e4b17023SJohn Marino 	  a = cgraph_variable_initializer_availability (node);
1084e4b17023SJohn Marino 	  if (a < *availability)
1085e4b17023SJohn Marino 	    *availability = a;
1086e4b17023SJohn Marino 	}
1087e4b17023SJohn Marino     }
1088e4b17023SJohn Marino   if (availability)
1089e4b17023SJohn Marino     *availability = AVAIL_NOT_AVAILABLE;
1090e4b17023SJohn Marino   return NULL;
1091e4b17023SJohn Marino }
1092e4b17023SJohn Marino 
1093e4b17023SJohn Marino /* Return true when the edge E represents a direct recursion.  */
1094e4b17023SJohn Marino static inline bool
cgraph_edge_recursive_p(struct cgraph_edge * e)1095e4b17023SJohn Marino cgraph_edge_recursive_p (struct cgraph_edge *e)
1096e4b17023SJohn Marino {
1097e4b17023SJohn Marino   struct cgraph_node *callee = cgraph_function_or_thunk_node (e->callee, NULL);
1098e4b17023SJohn Marino   if (e->caller->global.inlined_to)
1099e4b17023SJohn Marino     return e->caller->global.inlined_to->decl == callee->decl;
1100e4b17023SJohn Marino   else
1101e4b17023SJohn Marino     return e->caller->decl == callee->decl;
1102e4b17023SJohn Marino }
1103e4b17023SJohn Marino 
1104e4b17023SJohn Marino /* Return true if the TM_CLONE bit is set for a given FNDECL.  */
1105e4b17023SJohn Marino static inline bool
decl_is_tm_clone(const_tree fndecl)1106e4b17023SJohn Marino decl_is_tm_clone (const_tree fndecl)
1107e4b17023SJohn Marino {
1108e4b17023SJohn Marino   struct cgraph_node *n = cgraph_get_node (fndecl);
1109e4b17023SJohn Marino   if (n)
1110e4b17023SJohn Marino     return n->tm_clone;
1111e4b17023SJohn Marino   return false;
1112e4b17023SJohn Marino }
1113e4b17023SJohn Marino #endif  /* GCC_CGRAPH_H  */
1114