1*e4b17023SJohn Marino /* Callgraph based analysis of static variables.
2*e4b17023SJohn Marino Copyright (C) 2004, 2005, 2007, 2008, 2009, 2010
3*e4b17023SJohn Marino Free Software Foundation, Inc.
4*e4b17023SJohn Marino Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
5*e4b17023SJohn Marino
6*e4b17023SJohn Marino This file is part of GCC.
7*e4b17023SJohn Marino
8*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under
9*e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free
10*e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later
11*e4b17023SJohn Marino version.
12*e4b17023SJohn Marino
13*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14*e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or
15*e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16*e4b17023SJohn Marino for more details.
17*e4b17023SJohn Marino
18*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
19*e4b17023SJohn Marino along with GCC; see the file COPYING3. If not see
20*e4b17023SJohn Marino <http://www.gnu.org/licenses/>. */
21*e4b17023SJohn Marino
22*e4b17023SJohn Marino /* This file gathers information about how variables whose scope is
23*e4b17023SJohn Marino confined to the compilation unit are used.
24*e4b17023SJohn Marino
25*e4b17023SJohn Marino The transitive call site specific clobber effects are computed
26*e4b17023SJohn Marino for the variables whose scope is contained within this compilation
27*e4b17023SJohn Marino unit.
28*e4b17023SJohn Marino
29*e4b17023SJohn Marino First each function and static variable initialization is analyzed
30*e4b17023SJohn Marino to determine which local static variables are either read, written,
31*e4b17023SJohn Marino or have their address taken. Any local static that has its address
32*e4b17023SJohn Marino taken is removed from consideration. Once the local read and
33*e4b17023SJohn Marino writes are determined, a transitive closure of this information is
34*e4b17023SJohn Marino performed over the call graph to determine the worst case set of
35*e4b17023SJohn Marino side effects of each call. In later parts of the compiler, these
36*e4b17023SJohn Marino local and global sets are examined to make the call clobbering less
37*e4b17023SJohn Marino traumatic, promote some statics to registers, and improve aliasing
38*e4b17023SJohn Marino information. */
39*e4b17023SJohn Marino
40*e4b17023SJohn Marino #include "config.h"
41*e4b17023SJohn Marino #include "system.h"
42*e4b17023SJohn Marino #include "coretypes.h"
43*e4b17023SJohn Marino #include "tm.h"
44*e4b17023SJohn Marino #include "tree.h"
45*e4b17023SJohn Marino #include "tree-flow.h"
46*e4b17023SJohn Marino #include "tree-inline.h"
47*e4b17023SJohn Marino #include "tree-pass.h"
48*e4b17023SJohn Marino #include "langhooks.h"
49*e4b17023SJohn Marino #include "pointer-set.h"
50*e4b17023SJohn Marino #include "splay-tree.h"
51*e4b17023SJohn Marino #include "ggc.h"
52*e4b17023SJohn Marino #include "ipa-utils.h"
53*e4b17023SJohn Marino #include "ipa-reference.h"
54*e4b17023SJohn Marino #include "gimple.h"
55*e4b17023SJohn Marino #include "cgraph.h"
56*e4b17023SJohn Marino #include "output.h"
57*e4b17023SJohn Marino #include "flags.h"
58*e4b17023SJohn Marino #include "timevar.h"
59*e4b17023SJohn Marino #include "diagnostic.h"
60*e4b17023SJohn Marino #include "langhooks.h"
61*e4b17023SJohn Marino #include "data-streamer.h"
62*e4b17023SJohn Marino #include "lto-streamer.h"
63*e4b17023SJohn Marino
64*e4b17023SJohn Marino static void remove_node_data (struct cgraph_node *node,
65*e4b17023SJohn Marino void *data ATTRIBUTE_UNUSED);
66*e4b17023SJohn Marino static void duplicate_node_data (struct cgraph_node *src,
67*e4b17023SJohn Marino struct cgraph_node *dst,
68*e4b17023SJohn Marino void *data ATTRIBUTE_UNUSED);
69*e4b17023SJohn Marino
70*e4b17023SJohn Marino /* The static variables defined within the compilation unit that are
71*e4b17023SJohn Marino loaded or stored directly by function that owns this structure. */
72*e4b17023SJohn Marino
73*e4b17023SJohn Marino struct ipa_reference_local_vars_info_d
74*e4b17023SJohn Marino {
75*e4b17023SJohn Marino bitmap statics_read;
76*e4b17023SJohn Marino bitmap statics_written;
77*e4b17023SJohn Marino };
78*e4b17023SJohn Marino
79*e4b17023SJohn Marino /* Statics that are read and written by some set of functions. The
80*e4b17023SJohn Marino local ones are based on the loads and stores local to the function.
81*e4b17023SJohn Marino The global ones are based on the local info as well as the
82*e4b17023SJohn Marino transitive closure of the functions that are called. */
83*e4b17023SJohn Marino
84*e4b17023SJohn Marino struct ipa_reference_global_vars_info_d
85*e4b17023SJohn Marino {
86*e4b17023SJohn Marino bitmap statics_read;
87*e4b17023SJohn Marino bitmap statics_written;
88*e4b17023SJohn Marino };
89*e4b17023SJohn Marino
90*e4b17023SJohn Marino /* Information we save about every function after ipa-reference is completed. */
91*e4b17023SJohn Marino
92*e4b17023SJohn Marino struct ipa_reference_optimization_summary_d
93*e4b17023SJohn Marino {
94*e4b17023SJohn Marino bitmap statics_not_read;
95*e4b17023SJohn Marino bitmap statics_not_written;
96*e4b17023SJohn Marino };
97*e4b17023SJohn Marino
98*e4b17023SJohn Marino typedef struct ipa_reference_local_vars_info_d *ipa_reference_local_vars_info_t;
99*e4b17023SJohn Marino typedef struct ipa_reference_global_vars_info_d *ipa_reference_global_vars_info_t;
100*e4b17023SJohn Marino typedef struct ipa_reference_optimization_summary_d *ipa_reference_optimization_summary_t;
101*e4b17023SJohn Marino
102*e4b17023SJohn Marino struct ipa_reference_vars_info_d
103*e4b17023SJohn Marino {
104*e4b17023SJohn Marino struct ipa_reference_local_vars_info_d local;
105*e4b17023SJohn Marino struct ipa_reference_global_vars_info_d global;
106*e4b17023SJohn Marino };
107*e4b17023SJohn Marino
108*e4b17023SJohn Marino typedef struct ipa_reference_vars_info_d *ipa_reference_vars_info_t;
109*e4b17023SJohn Marino
110*e4b17023SJohn Marino /* This splay tree contains all of the static variables that are
111*e4b17023SJohn Marino being considered by the compilation level alias analysis. */
112*e4b17023SJohn Marino static splay_tree reference_vars_to_consider;
113*e4b17023SJohn Marino
114*e4b17023SJohn Marino /* A bit is set for every module static we are considering. This is
115*e4b17023SJohn Marino ored into the local info when asm code is found that clobbers all
116*e4b17023SJohn Marino memory. */
117*e4b17023SJohn Marino static bitmap all_module_statics;
118*e4b17023SJohn Marino
119*e4b17023SJohn Marino /* Obstack holding bitmaps of local analysis (live from analysis to
120*e4b17023SJohn Marino propagation) */
121*e4b17023SJohn Marino static bitmap_obstack local_info_obstack;
122*e4b17023SJohn Marino /* Obstack holding global analysis live forever. */
123*e4b17023SJohn Marino static bitmap_obstack optimization_summary_obstack;
124*e4b17023SJohn Marino
125*e4b17023SJohn Marino /* Holders of ipa cgraph hooks: */
126*e4b17023SJohn Marino static struct cgraph_2node_hook_list *node_duplication_hook_holder;
127*e4b17023SJohn Marino static struct cgraph_node_hook_list *node_removal_hook_holder;
128*e4b17023SJohn Marino
129*e4b17023SJohn Marino /* Vector where the reference var infos are actually stored. */
130*e4b17023SJohn Marino DEF_VEC_P (ipa_reference_vars_info_t);
131*e4b17023SJohn Marino DEF_VEC_ALLOC_P (ipa_reference_vars_info_t, heap);
132*e4b17023SJohn Marino static VEC (ipa_reference_vars_info_t, heap) *ipa_reference_vars_vector;
133*e4b17023SJohn Marino DEF_VEC_P (ipa_reference_optimization_summary_t);
134*e4b17023SJohn Marino DEF_VEC_ALLOC_P (ipa_reference_optimization_summary_t, heap);
VEC(ipa_reference_optimization_summary_t,heap)135*e4b17023SJohn Marino static VEC (ipa_reference_optimization_summary_t, heap) *ipa_reference_opt_sum_vector;
136*e4b17023SJohn Marino
137*e4b17023SJohn Marino /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
138*e4b17023SJohn Marino static inline ipa_reference_vars_info_t
139*e4b17023SJohn Marino get_reference_vars_info (struct cgraph_node *node)
140*e4b17023SJohn Marino {
141*e4b17023SJohn Marino if (!ipa_reference_vars_vector
142*e4b17023SJohn Marino || VEC_length (ipa_reference_vars_info_t,
143*e4b17023SJohn Marino ipa_reference_vars_vector) <= (unsigned int) node->uid)
144*e4b17023SJohn Marino return NULL;
145*e4b17023SJohn Marino return VEC_index (ipa_reference_vars_info_t, ipa_reference_vars_vector,
146*e4b17023SJohn Marino node->uid);
147*e4b17023SJohn Marino }
148*e4b17023SJohn Marino
149*e4b17023SJohn Marino /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
150*e4b17023SJohn Marino static inline ipa_reference_optimization_summary_t
get_reference_optimization_summary(struct cgraph_node * node)151*e4b17023SJohn Marino get_reference_optimization_summary (struct cgraph_node *node)
152*e4b17023SJohn Marino {
153*e4b17023SJohn Marino if (!ipa_reference_opt_sum_vector
154*e4b17023SJohn Marino || (VEC_length (ipa_reference_optimization_summary_t,
155*e4b17023SJohn Marino ipa_reference_opt_sum_vector)
156*e4b17023SJohn Marino <= (unsigned int) node->uid))
157*e4b17023SJohn Marino return NULL;
158*e4b17023SJohn Marino return VEC_index (ipa_reference_optimization_summary_t, ipa_reference_opt_sum_vector,
159*e4b17023SJohn Marino node->uid);
160*e4b17023SJohn Marino }
161*e4b17023SJohn Marino
162*e4b17023SJohn Marino /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
163*e4b17023SJohn Marino static inline void
set_reference_vars_info(struct cgraph_node * node,ipa_reference_vars_info_t info)164*e4b17023SJohn Marino set_reference_vars_info (struct cgraph_node *node,
165*e4b17023SJohn Marino ipa_reference_vars_info_t info)
166*e4b17023SJohn Marino {
167*e4b17023SJohn Marino if (!ipa_reference_vars_vector
168*e4b17023SJohn Marino || VEC_length (ipa_reference_vars_info_t,
169*e4b17023SJohn Marino ipa_reference_vars_vector) <= (unsigned int) node->uid)
170*e4b17023SJohn Marino VEC_safe_grow_cleared (ipa_reference_vars_info_t, heap,
171*e4b17023SJohn Marino ipa_reference_vars_vector, node->uid + 1);
172*e4b17023SJohn Marino VEC_replace (ipa_reference_vars_info_t, ipa_reference_vars_vector,
173*e4b17023SJohn Marino node->uid, info);
174*e4b17023SJohn Marino }
175*e4b17023SJohn Marino
176*e4b17023SJohn Marino /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
177*e4b17023SJohn Marino static inline void
set_reference_optimization_summary(struct cgraph_node * node,ipa_reference_optimization_summary_t info)178*e4b17023SJohn Marino set_reference_optimization_summary (struct cgraph_node *node,
179*e4b17023SJohn Marino ipa_reference_optimization_summary_t info)
180*e4b17023SJohn Marino {
181*e4b17023SJohn Marino if (!ipa_reference_opt_sum_vector
182*e4b17023SJohn Marino || (VEC_length (ipa_reference_optimization_summary_t,
183*e4b17023SJohn Marino ipa_reference_opt_sum_vector)
184*e4b17023SJohn Marino <= (unsigned int) node->uid))
185*e4b17023SJohn Marino VEC_safe_grow_cleared (ipa_reference_optimization_summary_t,
186*e4b17023SJohn Marino heap, ipa_reference_opt_sum_vector, node->uid + 1);
187*e4b17023SJohn Marino VEC_replace (ipa_reference_optimization_summary_t,
188*e4b17023SJohn Marino ipa_reference_opt_sum_vector, node->uid, info);
189*e4b17023SJohn Marino }
190*e4b17023SJohn Marino
191*e4b17023SJohn Marino /* Return a bitmap indexed by_DECL_UID uid for the static variables
192*e4b17023SJohn Marino that are not read during the execution of the function FN. Returns
193*e4b17023SJohn Marino NULL if no data is available. */
194*e4b17023SJohn Marino
195*e4b17023SJohn Marino bitmap
ipa_reference_get_not_read_global(struct cgraph_node * fn)196*e4b17023SJohn Marino ipa_reference_get_not_read_global (struct cgraph_node *fn)
197*e4b17023SJohn Marino {
198*e4b17023SJohn Marino ipa_reference_optimization_summary_t info;
199*e4b17023SJohn Marino
200*e4b17023SJohn Marino info = get_reference_optimization_summary (cgraph_function_node (fn, NULL));
201*e4b17023SJohn Marino if (info)
202*e4b17023SJohn Marino return info->statics_not_read;
203*e4b17023SJohn Marino else if (flags_from_decl_or_type (fn->decl) & ECF_LEAF)
204*e4b17023SJohn Marino return all_module_statics;
205*e4b17023SJohn Marino else
206*e4b17023SJohn Marino return NULL;
207*e4b17023SJohn Marino }
208*e4b17023SJohn Marino
209*e4b17023SJohn Marino /* Return a bitmap indexed by DECL_UID uid for the static variables
210*e4b17023SJohn Marino that are not written during the execution of the function FN. Note
211*e4b17023SJohn Marino that variables written may or may not be read during the function
212*e4b17023SJohn Marino call. Returns NULL if no data is available. */
213*e4b17023SJohn Marino
214*e4b17023SJohn Marino bitmap
ipa_reference_get_not_written_global(struct cgraph_node * fn)215*e4b17023SJohn Marino ipa_reference_get_not_written_global (struct cgraph_node *fn)
216*e4b17023SJohn Marino {
217*e4b17023SJohn Marino ipa_reference_optimization_summary_t info;
218*e4b17023SJohn Marino
219*e4b17023SJohn Marino info = get_reference_optimization_summary (fn);
220*e4b17023SJohn Marino if (info)
221*e4b17023SJohn Marino return info->statics_not_written;
222*e4b17023SJohn Marino else if (flags_from_decl_or_type (fn->decl) & ECF_LEAF)
223*e4b17023SJohn Marino return all_module_statics;
224*e4b17023SJohn Marino else
225*e4b17023SJohn Marino return NULL;
226*e4b17023SJohn Marino }
227*e4b17023SJohn Marino
228*e4b17023SJohn Marino
229*e4b17023SJohn Marino
230*e4b17023SJohn Marino /* Add VAR to all_module_statics and the two
231*e4b17023SJohn Marino reference_vars_to_consider* sets. */
232*e4b17023SJohn Marino
233*e4b17023SJohn Marino static inline void
add_static_var(tree var)234*e4b17023SJohn Marino add_static_var (tree var)
235*e4b17023SJohn Marino {
236*e4b17023SJohn Marino int uid = DECL_UID (var);
237*e4b17023SJohn Marino gcc_assert (TREE_CODE (var) == VAR_DECL);
238*e4b17023SJohn Marino if (dump_file)
239*e4b17023SJohn Marino splay_tree_insert (reference_vars_to_consider,
240*e4b17023SJohn Marino uid, (splay_tree_value)var);
241*e4b17023SJohn Marino bitmap_set_bit (all_module_statics, uid);
242*e4b17023SJohn Marino }
243*e4b17023SJohn Marino
244*e4b17023SJohn Marino /* Return true if the variable T is the right kind of static variable to
245*e4b17023SJohn Marino perform compilation unit scope escape analysis. */
246*e4b17023SJohn Marino
247*e4b17023SJohn Marino static inline bool
is_proper_for_analysis(tree t)248*e4b17023SJohn Marino is_proper_for_analysis (tree t)
249*e4b17023SJohn Marino {
250*e4b17023SJohn Marino /* We handle only variables whose address is never taken. */
251*e4b17023SJohn Marino if (TREE_ADDRESSABLE (t))
252*e4b17023SJohn Marino return false;
253*e4b17023SJohn Marino
254*e4b17023SJohn Marino /* If the variable has the "used" attribute, treat it as if it had a
255*e4b17023SJohn Marino been touched by the devil. */
256*e4b17023SJohn Marino if (DECL_PRESERVE_P (t))
257*e4b17023SJohn Marino return false;
258*e4b17023SJohn Marino
259*e4b17023SJohn Marino /* Do not want to do anything with volatile except mark any
260*e4b17023SJohn Marino function that uses one to be not const or pure. */
261*e4b17023SJohn Marino if (TREE_THIS_VOLATILE (t))
262*e4b17023SJohn Marino return false;
263*e4b17023SJohn Marino
264*e4b17023SJohn Marino /* We do not need to analyze readonly vars, we already know they do not
265*e4b17023SJohn Marino alias. */
266*e4b17023SJohn Marino if (TREE_READONLY (t))
267*e4b17023SJohn Marino return false;
268*e4b17023SJohn Marino
269*e4b17023SJohn Marino /* We cannot touch decls where the type needs constructing. */
270*e4b17023SJohn Marino if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (t)))
271*e4b17023SJohn Marino return false;
272*e4b17023SJohn Marino
273*e4b17023SJohn Marino /* This is a variable we care about. Check if we have seen it
274*e4b17023SJohn Marino before, and if not add it the set of variables we care about. */
275*e4b17023SJohn Marino if (all_module_statics
276*e4b17023SJohn Marino && !bitmap_bit_p (all_module_statics, DECL_UID (t)))
277*e4b17023SJohn Marino add_static_var (t);
278*e4b17023SJohn Marino
279*e4b17023SJohn Marino return true;
280*e4b17023SJohn Marino }
281*e4b17023SJohn Marino
282*e4b17023SJohn Marino /* Lookup the tree node for the static variable that has UID and
283*e4b17023SJohn Marino convert the name to a string for debugging. */
284*e4b17023SJohn Marino
285*e4b17023SJohn Marino static const char *
get_static_name(int index)286*e4b17023SJohn Marino get_static_name (int index)
287*e4b17023SJohn Marino {
288*e4b17023SJohn Marino splay_tree_node stn =
289*e4b17023SJohn Marino splay_tree_lookup (reference_vars_to_consider, index);
290*e4b17023SJohn Marino if (stn)
291*e4b17023SJohn Marino return lang_hooks.decl_printable_name ((tree)(stn->value), 2);
292*e4b17023SJohn Marino return NULL;
293*e4b17023SJohn Marino }
294*e4b17023SJohn Marino
295*e4b17023SJohn Marino /* Or in all of the bits from every callee of X into X_GLOBAL, the caller's cycle,
296*e4b17023SJohn Marino bit vector. There are several cases to check to avoid the sparse
297*e4b17023SJohn Marino bitmap oring. */
298*e4b17023SJohn Marino
299*e4b17023SJohn Marino static void
propagate_bits(ipa_reference_global_vars_info_t x_global,struct cgraph_node * x)300*e4b17023SJohn Marino propagate_bits (ipa_reference_global_vars_info_t x_global, struct cgraph_node *x)
301*e4b17023SJohn Marino {
302*e4b17023SJohn Marino struct cgraph_edge *e;
303*e4b17023SJohn Marino for (e = x->callees; e; e = e->next_callee)
304*e4b17023SJohn Marino {
305*e4b17023SJohn Marino enum availability avail;
306*e4b17023SJohn Marino struct cgraph_node *y = cgraph_function_node (e->callee, &avail);
307*e4b17023SJohn Marino
308*e4b17023SJohn Marino if (!y)
309*e4b17023SJohn Marino continue;
310*e4b17023SJohn Marino /* Only look into nodes we can propagate something. */
311*e4b17023SJohn Marino if (avail > AVAIL_OVERWRITABLE
312*e4b17023SJohn Marino || (avail == AVAIL_OVERWRITABLE
313*e4b17023SJohn Marino && (flags_from_decl_or_type (y->decl) & ECF_LEAF)))
314*e4b17023SJohn Marino {
315*e4b17023SJohn Marino int flags = flags_from_decl_or_type (y->decl);
316*e4b17023SJohn Marino if (get_reference_vars_info (y))
317*e4b17023SJohn Marino {
318*e4b17023SJohn Marino ipa_reference_vars_info_t y_info
319*e4b17023SJohn Marino = get_reference_vars_info (y);
320*e4b17023SJohn Marino ipa_reference_global_vars_info_t y_global = &y_info->global;
321*e4b17023SJohn Marino
322*e4b17023SJohn Marino /* Calls in current cycle do not have global computed yet. */
323*e4b17023SJohn Marino if (!y_global->statics_read)
324*e4b17023SJohn Marino continue;
325*e4b17023SJohn Marino
326*e4b17023SJohn Marino /* If function is declared const, it reads no memory even if it
327*e4b17023SJohn Marino seems so to local analysis. */
328*e4b17023SJohn Marino if (flags & ECF_CONST)
329*e4b17023SJohn Marino continue;
330*e4b17023SJohn Marino
331*e4b17023SJohn Marino if (x_global->statics_read
332*e4b17023SJohn Marino != all_module_statics)
333*e4b17023SJohn Marino {
334*e4b17023SJohn Marino if (y_global->statics_read
335*e4b17023SJohn Marino == all_module_statics)
336*e4b17023SJohn Marino {
337*e4b17023SJohn Marino BITMAP_FREE (x_global->statics_read);
338*e4b17023SJohn Marino x_global->statics_read
339*e4b17023SJohn Marino = all_module_statics;
340*e4b17023SJohn Marino }
341*e4b17023SJohn Marino /* Skip bitmaps that are pointer equal to node's bitmap
342*e4b17023SJohn Marino (no reason to spin within the cycle). */
343*e4b17023SJohn Marino else if (x_global->statics_read
344*e4b17023SJohn Marino != y_global->statics_read)
345*e4b17023SJohn Marino bitmap_ior_into (x_global->statics_read,
346*e4b17023SJohn Marino y_global->statics_read);
347*e4b17023SJohn Marino }
348*e4b17023SJohn Marino
349*e4b17023SJohn Marino /* If function is declared pure, it has no stores even if it
350*e4b17023SJohn Marino seems so to local analysis; If we can not return from here,
351*e4b17023SJohn Marino we can safely ignore the call. */
352*e4b17023SJohn Marino if ((flags & ECF_PURE)
353*e4b17023SJohn Marino || cgraph_edge_cannot_lead_to_return (e))
354*e4b17023SJohn Marino continue;
355*e4b17023SJohn Marino
356*e4b17023SJohn Marino if (x_global->statics_written
357*e4b17023SJohn Marino != all_module_statics)
358*e4b17023SJohn Marino {
359*e4b17023SJohn Marino if (y_global->statics_written
360*e4b17023SJohn Marino == all_module_statics)
361*e4b17023SJohn Marino {
362*e4b17023SJohn Marino BITMAP_FREE (x_global->statics_written);
363*e4b17023SJohn Marino x_global->statics_written
364*e4b17023SJohn Marino = all_module_statics;
365*e4b17023SJohn Marino }
366*e4b17023SJohn Marino /* Skip bitmaps that are pointer equal to node's bitmap
367*e4b17023SJohn Marino (no reason to spin within the cycle). */
368*e4b17023SJohn Marino else if (x_global->statics_written
369*e4b17023SJohn Marino != y_global->statics_written)
370*e4b17023SJohn Marino bitmap_ior_into (x_global->statics_written,
371*e4b17023SJohn Marino y_global->statics_written);
372*e4b17023SJohn Marino }
373*e4b17023SJohn Marino }
374*e4b17023SJohn Marino else
375*e4b17023SJohn Marino gcc_unreachable ();
376*e4b17023SJohn Marino }
377*e4b17023SJohn Marino }
378*e4b17023SJohn Marino }
379*e4b17023SJohn Marino
380*e4b17023SJohn Marino /* The init routine for analyzing global static variable usage. See
381*e4b17023SJohn Marino comments at top for description. */
382*e4b17023SJohn Marino static void
ipa_init(void)383*e4b17023SJohn Marino ipa_init (void)
384*e4b17023SJohn Marino {
385*e4b17023SJohn Marino static bool init_p = false;
386*e4b17023SJohn Marino
387*e4b17023SJohn Marino if (init_p)
388*e4b17023SJohn Marino return;
389*e4b17023SJohn Marino
390*e4b17023SJohn Marino init_p = true;
391*e4b17023SJohn Marino
392*e4b17023SJohn Marino if (dump_file)
393*e4b17023SJohn Marino reference_vars_to_consider = splay_tree_new (splay_tree_compare_ints, 0, 0);
394*e4b17023SJohn Marino
395*e4b17023SJohn Marino bitmap_obstack_initialize (&local_info_obstack);
396*e4b17023SJohn Marino bitmap_obstack_initialize (&optimization_summary_obstack);
397*e4b17023SJohn Marino all_module_statics = BITMAP_ALLOC (&optimization_summary_obstack);
398*e4b17023SJohn Marino
399*e4b17023SJohn Marino node_removal_hook_holder =
400*e4b17023SJohn Marino cgraph_add_node_removal_hook (&remove_node_data, NULL);
401*e4b17023SJohn Marino node_duplication_hook_holder =
402*e4b17023SJohn Marino cgraph_add_node_duplication_hook (&duplicate_node_data, NULL);
403*e4b17023SJohn Marino }
404*e4b17023SJohn Marino
405*e4b17023SJohn Marino
406*e4b17023SJohn Marino /* Set up the persistent info for FN. */
407*e4b17023SJohn Marino
408*e4b17023SJohn Marino static ipa_reference_local_vars_info_t
init_function_info(struct cgraph_node * fn)409*e4b17023SJohn Marino init_function_info (struct cgraph_node *fn)
410*e4b17023SJohn Marino {
411*e4b17023SJohn Marino ipa_reference_vars_info_t info
412*e4b17023SJohn Marino = XCNEW (struct ipa_reference_vars_info_d);
413*e4b17023SJohn Marino
414*e4b17023SJohn Marino /* Add the info to the tree's annotation. */
415*e4b17023SJohn Marino set_reference_vars_info (fn, info);
416*e4b17023SJohn Marino
417*e4b17023SJohn Marino info->local.statics_read = BITMAP_ALLOC (&local_info_obstack);
418*e4b17023SJohn Marino info->local.statics_written = BITMAP_ALLOC (&local_info_obstack);
419*e4b17023SJohn Marino
420*e4b17023SJohn Marino return &info->local;
421*e4b17023SJohn Marino }
422*e4b17023SJohn Marino
423*e4b17023SJohn Marino
424*e4b17023SJohn Marino /* This is the main routine for finding the reference patterns for
425*e4b17023SJohn Marino global variables within a function FN. */
426*e4b17023SJohn Marino
427*e4b17023SJohn Marino static void
analyze_function(struct cgraph_node * fn)428*e4b17023SJohn Marino analyze_function (struct cgraph_node *fn)
429*e4b17023SJohn Marino {
430*e4b17023SJohn Marino ipa_reference_local_vars_info_t local;
431*e4b17023SJohn Marino struct ipa_ref *ref;
432*e4b17023SJohn Marino int i;
433*e4b17023SJohn Marino tree var;
434*e4b17023SJohn Marino
435*e4b17023SJohn Marino local = init_function_info (fn);
436*e4b17023SJohn Marino for (i = 0; ipa_ref_list_reference_iterate (&fn->ref_list, i, ref); i++)
437*e4b17023SJohn Marino {
438*e4b17023SJohn Marino if (ref->refered_type != IPA_REF_VARPOOL)
439*e4b17023SJohn Marino continue;
440*e4b17023SJohn Marino var = ipa_ref_varpool_node (ref)->decl;
441*e4b17023SJohn Marino if (ipa_ref_varpool_node (ref)->externally_visible
442*e4b17023SJohn Marino || !ipa_ref_varpool_node (ref)->analyzed
443*e4b17023SJohn Marino || !is_proper_for_analysis (var))
444*e4b17023SJohn Marino continue;
445*e4b17023SJohn Marino switch (ref->use)
446*e4b17023SJohn Marino {
447*e4b17023SJohn Marino case IPA_REF_LOAD:
448*e4b17023SJohn Marino bitmap_set_bit (local->statics_read, DECL_UID (var));
449*e4b17023SJohn Marino break;
450*e4b17023SJohn Marino case IPA_REF_STORE:
451*e4b17023SJohn Marino if (ipa_ref_cannot_lead_to_return (ref))
452*e4b17023SJohn Marino break;
453*e4b17023SJohn Marino bitmap_set_bit (local->statics_written, DECL_UID (var));
454*e4b17023SJohn Marino break;
455*e4b17023SJohn Marino case IPA_REF_ADDR:
456*e4b17023SJohn Marino gcc_unreachable ();
457*e4b17023SJohn Marino break;
458*e4b17023SJohn Marino }
459*e4b17023SJohn Marino }
460*e4b17023SJohn Marino
461*e4b17023SJohn Marino if (cgraph_node_cannot_return (fn))
462*e4b17023SJohn Marino bitmap_clear (local->statics_written);
463*e4b17023SJohn Marino }
464*e4b17023SJohn Marino
465*e4b17023SJohn Marino static bitmap
copy_global_bitmap(bitmap src)466*e4b17023SJohn Marino copy_global_bitmap (bitmap src)
467*e4b17023SJohn Marino {
468*e4b17023SJohn Marino bitmap dst;
469*e4b17023SJohn Marino if (!src)
470*e4b17023SJohn Marino return NULL;
471*e4b17023SJohn Marino if (src == all_module_statics)
472*e4b17023SJohn Marino return all_module_statics;
473*e4b17023SJohn Marino dst = BITMAP_ALLOC (&optimization_summary_obstack);
474*e4b17023SJohn Marino bitmap_copy (dst, src);
475*e4b17023SJohn Marino return dst;
476*e4b17023SJohn Marino }
477*e4b17023SJohn Marino
478*e4b17023SJohn Marino
479*e4b17023SJohn Marino /* Called when new clone is inserted to callgraph late. */
480*e4b17023SJohn Marino
481*e4b17023SJohn Marino static void
duplicate_node_data(struct cgraph_node * src,struct cgraph_node * dst,void * data ATTRIBUTE_UNUSED)482*e4b17023SJohn Marino duplicate_node_data (struct cgraph_node *src, struct cgraph_node *dst,
483*e4b17023SJohn Marino void *data ATTRIBUTE_UNUSED)
484*e4b17023SJohn Marino {
485*e4b17023SJohn Marino ipa_reference_optimization_summary_t ginfo;
486*e4b17023SJohn Marino ipa_reference_optimization_summary_t dst_ginfo;
487*e4b17023SJohn Marino
488*e4b17023SJohn Marino ginfo = get_reference_optimization_summary (src);
489*e4b17023SJohn Marino if (!ginfo)
490*e4b17023SJohn Marino return;
491*e4b17023SJohn Marino dst_ginfo = XCNEW (struct ipa_reference_optimization_summary_d);
492*e4b17023SJohn Marino set_reference_optimization_summary (dst, dst_ginfo);
493*e4b17023SJohn Marino dst_ginfo->statics_not_read = copy_global_bitmap (ginfo->statics_not_read);
494*e4b17023SJohn Marino dst_ginfo->statics_not_written = copy_global_bitmap (ginfo->statics_not_written);
495*e4b17023SJohn Marino }
496*e4b17023SJohn Marino
497*e4b17023SJohn Marino /* Called when node is removed. */
498*e4b17023SJohn Marino
499*e4b17023SJohn Marino static void
remove_node_data(struct cgraph_node * node,void * data ATTRIBUTE_UNUSED)500*e4b17023SJohn Marino remove_node_data (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
501*e4b17023SJohn Marino {
502*e4b17023SJohn Marino ipa_reference_optimization_summary_t ginfo;
503*e4b17023SJohn Marino ginfo = get_reference_optimization_summary (node);
504*e4b17023SJohn Marino if (ginfo)
505*e4b17023SJohn Marino {
506*e4b17023SJohn Marino if (ginfo->statics_not_read
507*e4b17023SJohn Marino && ginfo->statics_not_read != all_module_statics)
508*e4b17023SJohn Marino BITMAP_FREE (ginfo->statics_not_read);
509*e4b17023SJohn Marino
510*e4b17023SJohn Marino if (ginfo->statics_not_written
511*e4b17023SJohn Marino && ginfo->statics_not_written != all_module_statics)
512*e4b17023SJohn Marino BITMAP_FREE (ginfo->statics_not_written);
513*e4b17023SJohn Marino free (ginfo);
514*e4b17023SJohn Marino set_reference_optimization_summary (node, NULL);
515*e4b17023SJohn Marino }
516*e4b17023SJohn Marino }
517*e4b17023SJohn Marino
518*e4b17023SJohn Marino /* Analyze each function in the cgraph to see which global or statics
519*e4b17023SJohn Marino are read or written. */
520*e4b17023SJohn Marino
521*e4b17023SJohn Marino static void
generate_summary(void)522*e4b17023SJohn Marino generate_summary (void)
523*e4b17023SJohn Marino {
524*e4b17023SJohn Marino struct cgraph_node *node;
525*e4b17023SJohn Marino unsigned int index;
526*e4b17023SJohn Marino bitmap_iterator bi;
527*e4b17023SJohn Marino bitmap bm_temp;
528*e4b17023SJohn Marino
529*e4b17023SJohn Marino ipa_init ();
530*e4b17023SJohn Marino bm_temp = BITMAP_ALLOC (&local_info_obstack);
531*e4b17023SJohn Marino
532*e4b17023SJohn Marino /* Process all of the functions next. */
533*e4b17023SJohn Marino for (node = cgraph_nodes; node; node = node->next)
534*e4b17023SJohn Marino if (node->analyzed)
535*e4b17023SJohn Marino analyze_function (node);
536*e4b17023SJohn Marino
537*e4b17023SJohn Marino if (dump_file)
538*e4b17023SJohn Marino EXECUTE_IF_SET_IN_BITMAP (all_module_statics, 0, index, bi)
539*e4b17023SJohn Marino {
540*e4b17023SJohn Marino fprintf (dump_file, "\nPromotable global:%s",
541*e4b17023SJohn Marino get_static_name (index));
542*e4b17023SJohn Marino }
543*e4b17023SJohn Marino
544*e4b17023SJohn Marino BITMAP_FREE(bm_temp);
545*e4b17023SJohn Marino
546*e4b17023SJohn Marino if (dump_file)
547*e4b17023SJohn Marino for (node = cgraph_nodes; node; node = node->next)
548*e4b17023SJohn Marino if (cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
549*e4b17023SJohn Marino {
550*e4b17023SJohn Marino ipa_reference_local_vars_info_t l;
551*e4b17023SJohn Marino unsigned int index;
552*e4b17023SJohn Marino bitmap_iterator bi;
553*e4b17023SJohn Marino
554*e4b17023SJohn Marino l = &get_reference_vars_info (node)->local;
555*e4b17023SJohn Marino fprintf (dump_file,
556*e4b17023SJohn Marino "\nFunction name:%s/%i:",
557*e4b17023SJohn Marino cgraph_node_name (node), node->uid);
558*e4b17023SJohn Marino fprintf (dump_file, "\n locals read: ");
559*e4b17023SJohn Marino if (l->statics_read)
560*e4b17023SJohn Marino EXECUTE_IF_SET_IN_BITMAP (l->statics_read,
561*e4b17023SJohn Marino 0, index, bi)
562*e4b17023SJohn Marino {
563*e4b17023SJohn Marino fprintf (dump_file, "%s ",
564*e4b17023SJohn Marino get_static_name (index));
565*e4b17023SJohn Marino }
566*e4b17023SJohn Marino fprintf (dump_file, "\n locals written: ");
567*e4b17023SJohn Marino if (l->statics_written)
568*e4b17023SJohn Marino EXECUTE_IF_SET_IN_BITMAP (l->statics_written,
569*e4b17023SJohn Marino 0, index, bi)
570*e4b17023SJohn Marino {
571*e4b17023SJohn Marino fprintf(dump_file, "%s ",
572*e4b17023SJohn Marino get_static_name (index));
573*e4b17023SJohn Marino }
574*e4b17023SJohn Marino }
575*e4b17023SJohn Marino }
576*e4b17023SJohn Marino
577*e4b17023SJohn Marino /* Set READ_ALL/WRITE_ALL based on decl flags of NODE. */
578*e4b17023SJohn Marino
579*e4b17023SJohn Marino static void
read_write_all_from_decl(struct cgraph_node * node,bool * read_all,bool * write_all)580*e4b17023SJohn Marino read_write_all_from_decl (struct cgraph_node *node, bool * read_all,
581*e4b17023SJohn Marino bool * write_all)
582*e4b17023SJohn Marino {
583*e4b17023SJohn Marino tree decl = node->decl;
584*e4b17023SJohn Marino int flags = flags_from_decl_or_type (decl);
585*e4b17023SJohn Marino if ((flags & ECF_LEAF)
586*e4b17023SJohn Marino && cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
587*e4b17023SJohn Marino ;
588*e4b17023SJohn Marino else if (flags & ECF_CONST)
589*e4b17023SJohn Marino ;
590*e4b17023SJohn Marino else if ((flags & ECF_PURE)
591*e4b17023SJohn Marino || cgraph_node_cannot_return (node))
592*e4b17023SJohn Marino {
593*e4b17023SJohn Marino *read_all = true;
594*e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
595*e4b17023SJohn Marino fprintf (dump_file, " %s/%i -> read all\n",
596*e4b17023SJohn Marino cgraph_node_name (node), node->uid);
597*e4b17023SJohn Marino }
598*e4b17023SJohn Marino else
599*e4b17023SJohn Marino {
600*e4b17023SJohn Marino /* TODO: To be able to produce sane results, we should also handle
601*e4b17023SJohn Marino common builtins, in particular throw. */
602*e4b17023SJohn Marino *read_all = true;
603*e4b17023SJohn Marino *write_all = true;
604*e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
605*e4b17023SJohn Marino fprintf (dump_file, " %s/%i -> read all, write all\n",
606*e4b17023SJohn Marino cgraph_node_name (node), node->uid);
607*e4b17023SJohn Marino }
608*e4b17023SJohn Marino }
609*e4b17023SJohn Marino
610*e4b17023SJohn Marino /* Produce the global information by preforming a transitive closure
611*e4b17023SJohn Marino on the local information that was produced by ipa_analyze_function */
612*e4b17023SJohn Marino
613*e4b17023SJohn Marino static unsigned int
propagate(void)614*e4b17023SJohn Marino propagate (void)
615*e4b17023SJohn Marino {
616*e4b17023SJohn Marino struct cgraph_node *node;
617*e4b17023SJohn Marino struct cgraph_node *w;
618*e4b17023SJohn Marino struct cgraph_node **order =
619*e4b17023SJohn Marino XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
620*e4b17023SJohn Marino int order_pos;
621*e4b17023SJohn Marino int i;
622*e4b17023SJohn Marino
623*e4b17023SJohn Marino if (dump_file)
624*e4b17023SJohn Marino dump_cgraph (dump_file);
625*e4b17023SJohn Marino
626*e4b17023SJohn Marino ipa_discover_readonly_nonaddressable_vars ();
627*e4b17023SJohn Marino generate_summary ();
628*e4b17023SJohn Marino
629*e4b17023SJohn Marino /* Propagate the local information thru the call graph to produce
630*e4b17023SJohn Marino the global information. All the nodes within a cycle will have
631*e4b17023SJohn Marino the same info so we collapse cycles first. Then we can do the
632*e4b17023SJohn Marino propagation in one pass from the leaves to the roots. */
633*e4b17023SJohn Marino order_pos = ipa_reduced_postorder (order, true, true, NULL);
634*e4b17023SJohn Marino if (dump_file)
635*e4b17023SJohn Marino ipa_print_order (dump_file, "reduced", order, order_pos);
636*e4b17023SJohn Marino
637*e4b17023SJohn Marino for (i = 0; i < order_pos; i++ )
638*e4b17023SJohn Marino {
639*e4b17023SJohn Marino ipa_reference_vars_info_t node_info;
640*e4b17023SJohn Marino ipa_reference_global_vars_info_t node_g;
641*e4b17023SJohn Marino ipa_reference_local_vars_info_t node_l;
642*e4b17023SJohn Marino struct cgraph_edge *e, *ie;
643*e4b17023SJohn Marino
644*e4b17023SJohn Marino bool read_all;
645*e4b17023SJohn Marino bool write_all;
646*e4b17023SJohn Marino struct ipa_dfs_info * w_info;
647*e4b17023SJohn Marino
648*e4b17023SJohn Marino node = order[i];
649*e4b17023SJohn Marino if (node->alias)
650*e4b17023SJohn Marino continue;
651*e4b17023SJohn Marino node_info = get_reference_vars_info (node);
652*e4b17023SJohn Marino gcc_assert (node_info);
653*e4b17023SJohn Marino
654*e4b17023SJohn Marino
655*e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
656*e4b17023SJohn Marino fprintf (dump_file, "Starting cycle with %s/%i\n",
657*e4b17023SJohn Marino cgraph_node_name (node), node->uid);
658*e4b17023SJohn Marino
659*e4b17023SJohn Marino node_l = &node_info->local;
660*e4b17023SJohn Marino node_g = &node_info->global;
661*e4b17023SJohn Marino
662*e4b17023SJohn Marino read_all = false;
663*e4b17023SJohn Marino write_all = false;
664*e4b17023SJohn Marino
665*e4b17023SJohn Marino /* When function is overwritable, we can not assume anything. */
666*e4b17023SJohn Marino if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
667*e4b17023SJohn Marino read_write_all_from_decl (node, &read_all, &write_all);
668*e4b17023SJohn Marino
669*e4b17023SJohn Marino for (e = node->callees; e; e = e->next_callee)
670*e4b17023SJohn Marino {
671*e4b17023SJohn Marino enum availability avail;
672*e4b17023SJohn Marino struct cgraph_node *callee = cgraph_function_node (e->callee, &avail);
673*e4b17023SJohn Marino if (!callee || avail <= AVAIL_OVERWRITABLE)
674*e4b17023SJohn Marino read_write_all_from_decl (callee, &read_all, &write_all);
675*e4b17023SJohn Marino }
676*e4b17023SJohn Marino
677*e4b17023SJohn Marino for (ie = node->indirect_calls; ie; ie = ie->next_callee)
678*e4b17023SJohn Marino if (!(ie->indirect_info->ecf_flags & ECF_CONST))
679*e4b17023SJohn Marino {
680*e4b17023SJohn Marino read_all = true;
681*e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
682*e4b17023SJohn Marino fprintf (dump_file, " indirect call -> read all\n");
683*e4b17023SJohn Marino if (!cgraph_edge_cannot_lead_to_return (ie)
684*e4b17023SJohn Marino && !(ie->indirect_info->ecf_flags & ECF_PURE))
685*e4b17023SJohn Marino {
686*e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
687*e4b17023SJohn Marino fprintf (dump_file, " indirect call -> write all\n");
688*e4b17023SJohn Marino write_all = true;
689*e4b17023SJohn Marino }
690*e4b17023SJohn Marino }
691*e4b17023SJohn Marino
692*e4b17023SJohn Marino
693*e4b17023SJohn Marino /* If any node in a cycle is read_all or write_all
694*e4b17023SJohn Marino they all are. */
695*e4b17023SJohn Marino w_info = (struct ipa_dfs_info *) node->aux;
696*e4b17023SJohn Marino w = w_info->next_cycle;
697*e4b17023SJohn Marino while (w && (!read_all || !write_all))
698*e4b17023SJohn Marino {
699*e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
700*e4b17023SJohn Marino fprintf (dump_file, " Visiting %s/%i\n",
701*e4b17023SJohn Marino cgraph_node_name (w), w->uid);
702*e4b17023SJohn Marino /* When function is overwritable, we can not assume anything. */
703*e4b17023SJohn Marino if (cgraph_function_body_availability (w) <= AVAIL_OVERWRITABLE)
704*e4b17023SJohn Marino read_write_all_from_decl (w, &read_all, &write_all);
705*e4b17023SJohn Marino
706*e4b17023SJohn Marino for (e = w->callees; e; e = e->next_callee)
707*e4b17023SJohn Marino {
708*e4b17023SJohn Marino enum availability avail;
709*e4b17023SJohn Marino struct cgraph_node *callee = cgraph_function_node (e->callee, &avail);
710*e4b17023SJohn Marino
711*e4b17023SJohn Marino if (avail <= AVAIL_OVERWRITABLE)
712*e4b17023SJohn Marino read_write_all_from_decl (callee, &read_all, &write_all);
713*e4b17023SJohn Marino }
714*e4b17023SJohn Marino
715*e4b17023SJohn Marino for (ie = w->indirect_calls; ie; ie = ie->next_callee)
716*e4b17023SJohn Marino if (!(ie->indirect_info->ecf_flags & ECF_CONST))
717*e4b17023SJohn Marino {
718*e4b17023SJohn Marino read_all = true;
719*e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
720*e4b17023SJohn Marino fprintf (dump_file, " indirect call -> read all\n");
721*e4b17023SJohn Marino if (!cgraph_edge_cannot_lead_to_return (ie)
722*e4b17023SJohn Marino && !(ie->indirect_info->ecf_flags & ECF_PURE))
723*e4b17023SJohn Marino {
724*e4b17023SJohn Marino write_all = true;
725*e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
726*e4b17023SJohn Marino fprintf (dump_file, " indirect call -> write all\n");
727*e4b17023SJohn Marino }
728*e4b17023SJohn Marino }
729*e4b17023SJohn Marino
730*e4b17023SJohn Marino w_info = (struct ipa_dfs_info *) w->aux;
731*e4b17023SJohn Marino w = w_info->next_cycle;
732*e4b17023SJohn Marino }
733*e4b17023SJohn Marino
734*e4b17023SJohn Marino
735*e4b17023SJohn Marino /* Initialized the bitmaps for the reduced nodes */
736*e4b17023SJohn Marino if (read_all)
737*e4b17023SJohn Marino node_g->statics_read = all_module_statics;
738*e4b17023SJohn Marino else
739*e4b17023SJohn Marino {
740*e4b17023SJohn Marino node_g->statics_read = BITMAP_ALLOC (&local_info_obstack);
741*e4b17023SJohn Marino bitmap_copy (node_g->statics_read,
742*e4b17023SJohn Marino node_l->statics_read);
743*e4b17023SJohn Marino }
744*e4b17023SJohn Marino if (write_all)
745*e4b17023SJohn Marino node_g->statics_written = all_module_statics;
746*e4b17023SJohn Marino else
747*e4b17023SJohn Marino {
748*e4b17023SJohn Marino node_g->statics_written = BITMAP_ALLOC (&local_info_obstack);
749*e4b17023SJohn Marino bitmap_copy (node_g->statics_written,
750*e4b17023SJohn Marino node_l->statics_written);
751*e4b17023SJohn Marino }
752*e4b17023SJohn Marino
753*e4b17023SJohn Marino propagate_bits (node_g, node);
754*e4b17023SJohn Marino w_info = (struct ipa_dfs_info *) node->aux;
755*e4b17023SJohn Marino w = w_info->next_cycle;
756*e4b17023SJohn Marino while (w && (!read_all || !write_all))
757*e4b17023SJohn Marino {
758*e4b17023SJohn Marino ipa_reference_vars_info_t w_ri =
759*e4b17023SJohn Marino get_reference_vars_info (w);
760*e4b17023SJohn Marino ipa_reference_local_vars_info_t w_l = &w_ri->local;
761*e4b17023SJohn Marino int flags = flags_from_decl_or_type (w->decl);
762*e4b17023SJohn Marino
763*e4b17023SJohn Marino /* These global bitmaps are initialized from the local info
764*e4b17023SJohn Marino of all of the nodes in the region. However there is no
765*e4b17023SJohn Marino need to do any work if the bitmaps were set to
766*e4b17023SJohn Marino all_module_statics. */
767*e4b17023SJohn Marino if (!read_all && !(flags & ECF_CONST))
768*e4b17023SJohn Marino bitmap_ior_into (node_g->statics_read,
769*e4b17023SJohn Marino w_l->statics_read);
770*e4b17023SJohn Marino if (!write_all
771*e4b17023SJohn Marino && !(flags & ECF_PURE)
772*e4b17023SJohn Marino && !cgraph_node_cannot_return (w))
773*e4b17023SJohn Marino bitmap_ior_into (node_g->statics_written,
774*e4b17023SJohn Marino w_l->statics_written);
775*e4b17023SJohn Marino propagate_bits (node_g, w);
776*e4b17023SJohn Marino w_info = (struct ipa_dfs_info *) w->aux;
777*e4b17023SJohn Marino w = w_info->next_cycle;
778*e4b17023SJohn Marino }
779*e4b17023SJohn Marino
780*e4b17023SJohn Marino /* All nodes within a cycle have the same global info bitmaps. */
781*e4b17023SJohn Marino node_info->global = *node_g;
782*e4b17023SJohn Marino w_info = (struct ipa_dfs_info *) node->aux;
783*e4b17023SJohn Marino w = w_info->next_cycle;
784*e4b17023SJohn Marino while (w)
785*e4b17023SJohn Marino {
786*e4b17023SJohn Marino ipa_reference_vars_info_t w_ri =
787*e4b17023SJohn Marino get_reference_vars_info (w);
788*e4b17023SJohn Marino
789*e4b17023SJohn Marino w_ri->global = *node_g;
790*e4b17023SJohn Marino
791*e4b17023SJohn Marino w_info = (struct ipa_dfs_info *) w->aux;
792*e4b17023SJohn Marino w = w_info->next_cycle;
793*e4b17023SJohn Marino }
794*e4b17023SJohn Marino }
795*e4b17023SJohn Marino
796*e4b17023SJohn Marino if (dump_file)
797*e4b17023SJohn Marino {
798*e4b17023SJohn Marino for (i = 0; i < order_pos; i++ )
799*e4b17023SJohn Marino {
800*e4b17023SJohn Marino ipa_reference_vars_info_t node_info;
801*e4b17023SJohn Marino ipa_reference_global_vars_info_t node_g;
802*e4b17023SJohn Marino ipa_reference_local_vars_info_t node_l;
803*e4b17023SJohn Marino unsigned int index;
804*e4b17023SJohn Marino bitmap_iterator bi;
805*e4b17023SJohn Marino struct ipa_dfs_info * w_info;
806*e4b17023SJohn Marino
807*e4b17023SJohn Marino node = order[i];
808*e4b17023SJohn Marino if (node->alias)
809*e4b17023SJohn Marino continue;
810*e4b17023SJohn Marino node_info = get_reference_vars_info (node);
811*e4b17023SJohn Marino node_g = &node_info->global;
812*e4b17023SJohn Marino node_l = &node_info->local;
813*e4b17023SJohn Marino fprintf (dump_file,
814*e4b17023SJohn Marino "\nFunction name:%s/%i:",
815*e4b17023SJohn Marino cgraph_node_name (node), node->uid);
816*e4b17023SJohn Marino fprintf (dump_file, "\n locals read: ");
817*e4b17023SJohn Marino if (node_l->statics_read)
818*e4b17023SJohn Marino EXECUTE_IF_SET_IN_BITMAP (node_l->statics_read,
819*e4b17023SJohn Marino 0, index, bi)
820*e4b17023SJohn Marino {
821*e4b17023SJohn Marino fprintf (dump_file, "%s ",
822*e4b17023SJohn Marino get_static_name (index));
823*e4b17023SJohn Marino }
824*e4b17023SJohn Marino fprintf (dump_file, "\n locals written: ");
825*e4b17023SJohn Marino if (node_l->statics_written)
826*e4b17023SJohn Marino EXECUTE_IF_SET_IN_BITMAP (node_l->statics_written,
827*e4b17023SJohn Marino 0, index, bi)
828*e4b17023SJohn Marino {
829*e4b17023SJohn Marino fprintf(dump_file, "%s ",
830*e4b17023SJohn Marino get_static_name (index));
831*e4b17023SJohn Marino }
832*e4b17023SJohn Marino
833*e4b17023SJohn Marino w_info = (struct ipa_dfs_info *) node->aux;
834*e4b17023SJohn Marino w = w_info->next_cycle;
835*e4b17023SJohn Marino while (w)
836*e4b17023SJohn Marino {
837*e4b17023SJohn Marino ipa_reference_vars_info_t w_ri =
838*e4b17023SJohn Marino get_reference_vars_info (w);
839*e4b17023SJohn Marino ipa_reference_local_vars_info_t w_l = &w_ri->local;
840*e4b17023SJohn Marino fprintf (dump_file, "\n next cycle: %s/%i ",
841*e4b17023SJohn Marino cgraph_node_name (w), w->uid);
842*e4b17023SJohn Marino fprintf (dump_file, "\n locals read: ");
843*e4b17023SJohn Marino if (w_l->statics_read)
844*e4b17023SJohn Marino EXECUTE_IF_SET_IN_BITMAP (w_l->statics_read,
845*e4b17023SJohn Marino 0, index, bi)
846*e4b17023SJohn Marino {
847*e4b17023SJohn Marino fprintf (dump_file, "%s ",
848*e4b17023SJohn Marino get_static_name (index));
849*e4b17023SJohn Marino }
850*e4b17023SJohn Marino
851*e4b17023SJohn Marino fprintf (dump_file, "\n locals written: ");
852*e4b17023SJohn Marino if (w_l->statics_written)
853*e4b17023SJohn Marino EXECUTE_IF_SET_IN_BITMAP (w_l->statics_written,
854*e4b17023SJohn Marino 0, index, bi)
855*e4b17023SJohn Marino {
856*e4b17023SJohn Marino fprintf (dump_file, "%s ",
857*e4b17023SJohn Marino get_static_name (index));
858*e4b17023SJohn Marino }
859*e4b17023SJohn Marino
860*e4b17023SJohn Marino w_info = (struct ipa_dfs_info *) w->aux;
861*e4b17023SJohn Marino w = w_info->next_cycle;
862*e4b17023SJohn Marino }
863*e4b17023SJohn Marino fprintf (dump_file, "\n globals read: ");
864*e4b17023SJohn Marino if (node_g->statics_read == all_module_statics)
865*e4b17023SJohn Marino fprintf (dump_file, "ALL");
866*e4b17023SJohn Marino else
867*e4b17023SJohn Marino EXECUTE_IF_SET_IN_BITMAP (node_g->statics_read,
868*e4b17023SJohn Marino 0, index, bi)
869*e4b17023SJohn Marino {
870*e4b17023SJohn Marino fprintf (dump_file, "%s ",
871*e4b17023SJohn Marino get_static_name (index));
872*e4b17023SJohn Marino }
873*e4b17023SJohn Marino fprintf (dump_file, "\n globals written: ");
874*e4b17023SJohn Marino if (node_g->statics_written == all_module_statics)
875*e4b17023SJohn Marino fprintf (dump_file, "ALL");
876*e4b17023SJohn Marino else
877*e4b17023SJohn Marino EXECUTE_IF_SET_IN_BITMAP (node_g->statics_written,
878*e4b17023SJohn Marino 0, index, bi)
879*e4b17023SJohn Marino {
880*e4b17023SJohn Marino fprintf (dump_file, "%s ",
881*e4b17023SJohn Marino get_static_name (index));
882*e4b17023SJohn Marino }
883*e4b17023SJohn Marino }
884*e4b17023SJohn Marino }
885*e4b17023SJohn Marino
886*e4b17023SJohn Marino /* Cleanup. */
887*e4b17023SJohn Marino for (node = cgraph_nodes; node; node = node->next)
888*e4b17023SJohn Marino {
889*e4b17023SJohn Marino ipa_reference_vars_info_t node_info;
890*e4b17023SJohn Marino ipa_reference_global_vars_info_t node_g;
891*e4b17023SJohn Marino ipa_reference_optimization_summary_t opt;
892*e4b17023SJohn Marino
893*e4b17023SJohn Marino if (!node->analyzed || node->alias)
894*e4b17023SJohn Marino continue;
895*e4b17023SJohn Marino
896*e4b17023SJohn Marino node_info = get_reference_vars_info (node);
897*e4b17023SJohn Marino if (cgraph_function_body_availability (node) > AVAIL_OVERWRITABLE
898*e4b17023SJohn Marino || (flags_from_decl_or_type (node->decl) & ECF_LEAF))
899*e4b17023SJohn Marino {
900*e4b17023SJohn Marino node_g = &node_info->global;
901*e4b17023SJohn Marino
902*e4b17023SJohn Marino opt = XCNEW (struct ipa_reference_optimization_summary_d);
903*e4b17023SJohn Marino set_reference_optimization_summary (node, opt);
904*e4b17023SJohn Marino
905*e4b17023SJohn Marino /* Create the complimentary sets. */
906*e4b17023SJohn Marino
907*e4b17023SJohn Marino if (bitmap_empty_p (node_g->statics_read))
908*e4b17023SJohn Marino opt->statics_not_read = all_module_statics;
909*e4b17023SJohn Marino else
910*e4b17023SJohn Marino {
911*e4b17023SJohn Marino opt->statics_not_read
912*e4b17023SJohn Marino = BITMAP_ALLOC (&optimization_summary_obstack);
913*e4b17023SJohn Marino if (node_g->statics_read != all_module_statics)
914*e4b17023SJohn Marino bitmap_and_compl (opt->statics_not_read,
915*e4b17023SJohn Marino all_module_statics,
916*e4b17023SJohn Marino node_g->statics_read);
917*e4b17023SJohn Marino }
918*e4b17023SJohn Marino
919*e4b17023SJohn Marino if (bitmap_empty_p (node_g->statics_written))
920*e4b17023SJohn Marino opt->statics_not_written = all_module_statics;
921*e4b17023SJohn Marino else
922*e4b17023SJohn Marino {
923*e4b17023SJohn Marino opt->statics_not_written
924*e4b17023SJohn Marino = BITMAP_ALLOC (&optimization_summary_obstack);
925*e4b17023SJohn Marino if (node_g->statics_written != all_module_statics)
926*e4b17023SJohn Marino bitmap_and_compl (opt->statics_not_written,
927*e4b17023SJohn Marino all_module_statics,
928*e4b17023SJohn Marino node_g->statics_written);
929*e4b17023SJohn Marino }
930*e4b17023SJohn Marino }
931*e4b17023SJohn Marino free (node_info);
932*e4b17023SJohn Marino }
933*e4b17023SJohn Marino
934*e4b17023SJohn Marino ipa_free_postorder_info ();
935*e4b17023SJohn Marino free (order);
936*e4b17023SJohn Marino
937*e4b17023SJohn Marino bitmap_obstack_release (&local_info_obstack);
938*e4b17023SJohn Marino VEC_free (ipa_reference_vars_info_t, heap, ipa_reference_vars_vector);
939*e4b17023SJohn Marino ipa_reference_vars_vector = NULL;
940*e4b17023SJohn Marino if (dump_file)
941*e4b17023SJohn Marino splay_tree_delete (reference_vars_to_consider);
942*e4b17023SJohn Marino reference_vars_to_consider = NULL;
943*e4b17023SJohn Marino return 0;
944*e4b17023SJohn Marino }
945*e4b17023SJohn Marino
946*e4b17023SJohn Marino /* Return true if we need to write summary of NODE. */
947*e4b17023SJohn Marino
948*e4b17023SJohn Marino static bool
write_node_summary_p(struct cgraph_node * node,cgraph_node_set set,varpool_node_set vset,bitmap ltrans_statics)949*e4b17023SJohn Marino write_node_summary_p (struct cgraph_node *node,
950*e4b17023SJohn Marino cgraph_node_set set,
951*e4b17023SJohn Marino varpool_node_set vset,
952*e4b17023SJohn Marino bitmap ltrans_statics)
953*e4b17023SJohn Marino {
954*e4b17023SJohn Marino ipa_reference_optimization_summary_t info;
955*e4b17023SJohn Marino
956*e4b17023SJohn Marino /* See if we have (non-empty) info. */
957*e4b17023SJohn Marino if (!node->analyzed || node->global.inlined_to)
958*e4b17023SJohn Marino return false;
959*e4b17023SJohn Marino info = get_reference_optimization_summary (node);
960*e4b17023SJohn Marino if (!info || (bitmap_empty_p (info->statics_not_read)
961*e4b17023SJohn Marino && bitmap_empty_p (info->statics_not_written)))
962*e4b17023SJohn Marino return false;
963*e4b17023SJohn Marino
964*e4b17023SJohn Marino /* See if we want to encode it.
965*e4b17023SJohn Marino Encode also referenced functions since constant folding might turn it into
966*e4b17023SJohn Marino a direct call.
967*e4b17023SJohn Marino
968*e4b17023SJohn Marino In future we might also want to include summaries of functions references
969*e4b17023SJohn Marino by initializers of constant variables references in current unit. */
970*e4b17023SJohn Marino if (!reachable_from_this_partition_p (node, set)
971*e4b17023SJohn Marino && !referenced_from_this_partition_p (&node->ref_list, set, vset))
972*e4b17023SJohn Marino return false;
973*e4b17023SJohn Marino
974*e4b17023SJohn Marino /* See if the info has non-empty intersections with vars we want to encode. */
975*e4b17023SJohn Marino if (!bitmap_intersect_p (info->statics_not_read, ltrans_statics)
976*e4b17023SJohn Marino && !bitmap_intersect_p (info->statics_not_written, ltrans_statics))
977*e4b17023SJohn Marino return false;
978*e4b17023SJohn Marino return true;
979*e4b17023SJohn Marino }
980*e4b17023SJohn Marino
981*e4b17023SJohn Marino /* Stream out BITS<RANS_STATICS as list of decls to OB.
982*e4b17023SJohn Marino LTRANS_STATICS_BITCOUNT specify number of bits in LTRANS_STATICS
983*e4b17023SJohn Marino or -1. When it is positive, just output -1 when
984*e4b17023SJohn Marino BITS<RANS_STATICS == BITS<RANS_STATICS. */
985*e4b17023SJohn Marino
986*e4b17023SJohn Marino static void
stream_out_bitmap(struct lto_simple_output_block * ob,bitmap bits,bitmap ltrans_statics,int ltrans_statics_bitcount)987*e4b17023SJohn Marino stream_out_bitmap (struct lto_simple_output_block *ob,
988*e4b17023SJohn Marino bitmap bits, bitmap ltrans_statics,
989*e4b17023SJohn Marino int ltrans_statics_bitcount)
990*e4b17023SJohn Marino {
991*e4b17023SJohn Marino int count = 0;
992*e4b17023SJohn Marino unsigned int index;
993*e4b17023SJohn Marino bitmap_iterator bi;
994*e4b17023SJohn Marino if (bits == all_module_statics)
995*e4b17023SJohn Marino {
996*e4b17023SJohn Marino streamer_write_hwi_stream (ob->main_stream, -1);
997*e4b17023SJohn Marino return;
998*e4b17023SJohn Marino }
999*e4b17023SJohn Marino EXECUTE_IF_AND_IN_BITMAP (bits, ltrans_statics, 0, index, bi)
1000*e4b17023SJohn Marino count ++;
1001*e4b17023SJohn Marino if (count == ltrans_statics_bitcount)
1002*e4b17023SJohn Marino {
1003*e4b17023SJohn Marino streamer_write_hwi_stream (ob->main_stream, -1);
1004*e4b17023SJohn Marino return;
1005*e4b17023SJohn Marino }
1006*e4b17023SJohn Marino streamer_write_hwi_stream (ob->main_stream, count);
1007*e4b17023SJohn Marino if (!count)
1008*e4b17023SJohn Marino return;
1009*e4b17023SJohn Marino EXECUTE_IF_AND_IN_BITMAP (bits, ltrans_statics, 0, index, bi)
1010*e4b17023SJohn Marino {
1011*e4b17023SJohn Marino tree decl = (tree)splay_tree_lookup (reference_vars_to_consider, index)->value;
1012*e4b17023SJohn Marino lto_output_var_decl_index(ob->decl_state, ob->main_stream, decl);
1013*e4b17023SJohn Marino }
1014*e4b17023SJohn Marino }
1015*e4b17023SJohn Marino
1016*e4b17023SJohn Marino /* Serialize the ipa info for lto. */
1017*e4b17023SJohn Marino
1018*e4b17023SJohn Marino static void
ipa_reference_write_optimization_summary(cgraph_node_set set,varpool_node_set vset)1019*e4b17023SJohn Marino ipa_reference_write_optimization_summary (cgraph_node_set set,
1020*e4b17023SJohn Marino varpool_node_set vset)
1021*e4b17023SJohn Marino {
1022*e4b17023SJohn Marino struct cgraph_node *node;
1023*e4b17023SJohn Marino struct lto_simple_output_block *ob
1024*e4b17023SJohn Marino = lto_create_simple_output_block (LTO_section_ipa_reference);
1025*e4b17023SJohn Marino unsigned int count = 0;
1026*e4b17023SJohn Marino int ltrans_statics_bitcount = 0;
1027*e4b17023SJohn Marino lto_cgraph_encoder_t encoder = ob->decl_state->cgraph_node_encoder;
1028*e4b17023SJohn Marino lto_varpool_encoder_t varpool_encoder = ob->decl_state->varpool_node_encoder;
1029*e4b17023SJohn Marino bitmap ltrans_statics = BITMAP_ALLOC (NULL);
1030*e4b17023SJohn Marino int i;
1031*e4b17023SJohn Marino
1032*e4b17023SJohn Marino reference_vars_to_consider = splay_tree_new (splay_tree_compare_ints, 0, 0);
1033*e4b17023SJohn Marino
1034*e4b17023SJohn Marino /* See what variables we are interested in. */
1035*e4b17023SJohn Marino for (i = 0; i < lto_varpool_encoder_size (varpool_encoder); i++)
1036*e4b17023SJohn Marino {
1037*e4b17023SJohn Marino struct varpool_node *vnode = lto_varpool_encoder_deref (varpool_encoder, i);
1038*e4b17023SJohn Marino if (!vnode->externally_visible
1039*e4b17023SJohn Marino && vnode->analyzed
1040*e4b17023SJohn Marino && bitmap_bit_p (all_module_statics, DECL_UID (vnode->decl))
1041*e4b17023SJohn Marino && referenced_from_this_partition_p (&vnode->ref_list, set, vset))
1042*e4b17023SJohn Marino {
1043*e4b17023SJohn Marino tree decl = vnode->decl;
1044*e4b17023SJohn Marino bitmap_set_bit (ltrans_statics, DECL_UID (decl));
1045*e4b17023SJohn Marino splay_tree_insert (reference_vars_to_consider,
1046*e4b17023SJohn Marino DECL_UID (decl), (splay_tree_value)decl);
1047*e4b17023SJohn Marino ltrans_statics_bitcount ++;
1048*e4b17023SJohn Marino }
1049*e4b17023SJohn Marino }
1050*e4b17023SJohn Marino
1051*e4b17023SJohn Marino
1052*e4b17023SJohn Marino if (ltrans_statics_bitcount)
1053*e4b17023SJohn Marino for (i = 0; i < lto_cgraph_encoder_size (encoder); i++)
1054*e4b17023SJohn Marino if (write_node_summary_p (lto_cgraph_encoder_deref (encoder, i),
1055*e4b17023SJohn Marino set, vset, ltrans_statics))
1056*e4b17023SJohn Marino count++;
1057*e4b17023SJohn Marino
1058*e4b17023SJohn Marino streamer_write_uhwi_stream (ob->main_stream, count);
1059*e4b17023SJohn Marino if (count)
1060*e4b17023SJohn Marino stream_out_bitmap (ob, ltrans_statics, ltrans_statics,
1061*e4b17023SJohn Marino -1);
1062*e4b17023SJohn Marino
1063*e4b17023SJohn Marino /* Process all of the functions. */
1064*e4b17023SJohn Marino if (ltrans_statics_bitcount)
1065*e4b17023SJohn Marino for (i = 0; i < lto_cgraph_encoder_size (encoder); i++)
1066*e4b17023SJohn Marino {
1067*e4b17023SJohn Marino node = lto_cgraph_encoder_deref (encoder, i);
1068*e4b17023SJohn Marino if (write_node_summary_p (node, set, vset, ltrans_statics))
1069*e4b17023SJohn Marino {
1070*e4b17023SJohn Marino ipa_reference_optimization_summary_t info;
1071*e4b17023SJohn Marino int node_ref;
1072*e4b17023SJohn Marino
1073*e4b17023SJohn Marino info = get_reference_optimization_summary (node);
1074*e4b17023SJohn Marino node_ref = lto_cgraph_encoder_encode (encoder, node);
1075*e4b17023SJohn Marino streamer_write_uhwi_stream (ob->main_stream, node_ref);
1076*e4b17023SJohn Marino
1077*e4b17023SJohn Marino stream_out_bitmap (ob, info->statics_not_read, ltrans_statics,
1078*e4b17023SJohn Marino ltrans_statics_bitcount);
1079*e4b17023SJohn Marino stream_out_bitmap (ob, info->statics_not_written, ltrans_statics,
1080*e4b17023SJohn Marino ltrans_statics_bitcount);
1081*e4b17023SJohn Marino }
1082*e4b17023SJohn Marino }
1083*e4b17023SJohn Marino BITMAP_FREE (ltrans_statics);
1084*e4b17023SJohn Marino lto_destroy_simple_output_block (ob);
1085*e4b17023SJohn Marino splay_tree_delete (reference_vars_to_consider);
1086*e4b17023SJohn Marino }
1087*e4b17023SJohn Marino
1088*e4b17023SJohn Marino /* Deserialize the ipa info for lto. */
1089*e4b17023SJohn Marino
1090*e4b17023SJohn Marino static void
ipa_reference_read_optimization_summary(void)1091*e4b17023SJohn Marino ipa_reference_read_optimization_summary (void)
1092*e4b17023SJohn Marino {
1093*e4b17023SJohn Marino struct lto_file_decl_data ** file_data_vec
1094*e4b17023SJohn Marino = lto_get_file_decl_data ();
1095*e4b17023SJohn Marino struct lto_file_decl_data * file_data;
1096*e4b17023SJohn Marino unsigned int j = 0;
1097*e4b17023SJohn Marino bitmap_obstack_initialize (&optimization_summary_obstack);
1098*e4b17023SJohn Marino
1099*e4b17023SJohn Marino node_removal_hook_holder =
1100*e4b17023SJohn Marino cgraph_add_node_removal_hook (&remove_node_data, NULL);
1101*e4b17023SJohn Marino node_duplication_hook_holder =
1102*e4b17023SJohn Marino cgraph_add_node_duplication_hook (&duplicate_node_data, NULL);
1103*e4b17023SJohn Marino all_module_statics = BITMAP_ALLOC (&optimization_summary_obstack);
1104*e4b17023SJohn Marino
1105*e4b17023SJohn Marino while ((file_data = file_data_vec[j++]))
1106*e4b17023SJohn Marino {
1107*e4b17023SJohn Marino const char *data;
1108*e4b17023SJohn Marino size_t len;
1109*e4b17023SJohn Marino struct lto_input_block *ib
1110*e4b17023SJohn Marino = lto_create_simple_input_block (file_data,
1111*e4b17023SJohn Marino LTO_section_ipa_reference,
1112*e4b17023SJohn Marino &data, &len);
1113*e4b17023SJohn Marino if (ib)
1114*e4b17023SJohn Marino {
1115*e4b17023SJohn Marino unsigned int i;
1116*e4b17023SJohn Marino unsigned int f_count = streamer_read_uhwi (ib);
1117*e4b17023SJohn Marino int b_count;
1118*e4b17023SJohn Marino if (!f_count)
1119*e4b17023SJohn Marino continue;
1120*e4b17023SJohn Marino b_count = streamer_read_hwi (ib);
1121*e4b17023SJohn Marino if (dump_file)
1122*e4b17023SJohn Marino fprintf (dump_file, "all module statics:");
1123*e4b17023SJohn Marino for (i = 0; i < (unsigned int)b_count; i++)
1124*e4b17023SJohn Marino {
1125*e4b17023SJohn Marino unsigned int var_index = streamer_read_uhwi (ib);
1126*e4b17023SJohn Marino tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1127*e4b17023SJohn Marino var_index);
1128*e4b17023SJohn Marino bitmap_set_bit (all_module_statics, DECL_UID (v_decl));
1129*e4b17023SJohn Marino if (dump_file)
1130*e4b17023SJohn Marino fprintf (dump_file, " %s",
1131*e4b17023SJohn Marino lang_hooks.decl_printable_name (v_decl, 2));
1132*e4b17023SJohn Marino }
1133*e4b17023SJohn Marino
1134*e4b17023SJohn Marino for (i = 0; i < f_count; i++)
1135*e4b17023SJohn Marino {
1136*e4b17023SJohn Marino unsigned int j, index;
1137*e4b17023SJohn Marino struct cgraph_node *node;
1138*e4b17023SJohn Marino ipa_reference_optimization_summary_t info;
1139*e4b17023SJohn Marino int v_count;
1140*e4b17023SJohn Marino lto_cgraph_encoder_t encoder;
1141*e4b17023SJohn Marino
1142*e4b17023SJohn Marino index = streamer_read_uhwi (ib);
1143*e4b17023SJohn Marino encoder = file_data->cgraph_node_encoder;
1144*e4b17023SJohn Marino node = lto_cgraph_encoder_deref (encoder, index);
1145*e4b17023SJohn Marino info = XCNEW (struct ipa_reference_optimization_summary_d);
1146*e4b17023SJohn Marino set_reference_optimization_summary (node, info);
1147*e4b17023SJohn Marino info->statics_not_read = BITMAP_ALLOC (&optimization_summary_obstack);
1148*e4b17023SJohn Marino info->statics_not_written = BITMAP_ALLOC (&optimization_summary_obstack);
1149*e4b17023SJohn Marino if (dump_file)
1150*e4b17023SJohn Marino fprintf (dump_file,
1151*e4b17023SJohn Marino "\nFunction name:%s/%i:\n static not read:",
1152*e4b17023SJohn Marino cgraph_node_name (node), node->uid);
1153*e4b17023SJohn Marino
1154*e4b17023SJohn Marino /* Set the statics not read. */
1155*e4b17023SJohn Marino v_count = streamer_read_hwi (ib);
1156*e4b17023SJohn Marino if (v_count == -1)
1157*e4b17023SJohn Marino {
1158*e4b17023SJohn Marino info->statics_not_read = all_module_statics;
1159*e4b17023SJohn Marino if (dump_file)
1160*e4b17023SJohn Marino fprintf (dump_file, " all module statics");
1161*e4b17023SJohn Marino }
1162*e4b17023SJohn Marino else
1163*e4b17023SJohn Marino for (j = 0; j < (unsigned int)v_count; j++)
1164*e4b17023SJohn Marino {
1165*e4b17023SJohn Marino unsigned int var_index = streamer_read_uhwi (ib);
1166*e4b17023SJohn Marino tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1167*e4b17023SJohn Marino var_index);
1168*e4b17023SJohn Marino bitmap_set_bit (info->statics_not_read, DECL_UID (v_decl));
1169*e4b17023SJohn Marino if (dump_file)
1170*e4b17023SJohn Marino fprintf (dump_file, " %s",
1171*e4b17023SJohn Marino lang_hooks.decl_printable_name (v_decl, 2));
1172*e4b17023SJohn Marino }
1173*e4b17023SJohn Marino
1174*e4b17023SJohn Marino if (dump_file)
1175*e4b17023SJohn Marino fprintf (dump_file,
1176*e4b17023SJohn Marino "\n static not written:");
1177*e4b17023SJohn Marino /* Set the statics not written. */
1178*e4b17023SJohn Marino v_count = streamer_read_hwi (ib);
1179*e4b17023SJohn Marino if (v_count == -1)
1180*e4b17023SJohn Marino {
1181*e4b17023SJohn Marino info->statics_not_written = all_module_statics;
1182*e4b17023SJohn Marino if (dump_file)
1183*e4b17023SJohn Marino fprintf (dump_file, " all module statics");
1184*e4b17023SJohn Marino }
1185*e4b17023SJohn Marino else
1186*e4b17023SJohn Marino for (j = 0; j < (unsigned int)v_count; j++)
1187*e4b17023SJohn Marino {
1188*e4b17023SJohn Marino unsigned int var_index = streamer_read_uhwi (ib);
1189*e4b17023SJohn Marino tree v_decl = lto_file_decl_data_get_var_decl (file_data,
1190*e4b17023SJohn Marino var_index);
1191*e4b17023SJohn Marino bitmap_set_bit (info->statics_not_written, DECL_UID (v_decl));
1192*e4b17023SJohn Marino if (dump_file)
1193*e4b17023SJohn Marino fprintf (dump_file, " %s",
1194*e4b17023SJohn Marino lang_hooks.decl_printable_name (v_decl, 2));
1195*e4b17023SJohn Marino }
1196*e4b17023SJohn Marino if (dump_file)
1197*e4b17023SJohn Marino fprintf (dump_file, "\n");
1198*e4b17023SJohn Marino }
1199*e4b17023SJohn Marino
1200*e4b17023SJohn Marino lto_destroy_simple_input_block (file_data,
1201*e4b17023SJohn Marino LTO_section_ipa_reference,
1202*e4b17023SJohn Marino ib, data, len);
1203*e4b17023SJohn Marino }
1204*e4b17023SJohn Marino else
1205*e4b17023SJohn Marino /* Fatal error here. We do not want to support compiling ltrans units with
1206*e4b17023SJohn Marino different version of compiler or different flags than the WPA unit, so
1207*e4b17023SJohn Marino this should never happen. */
1208*e4b17023SJohn Marino fatal_error ("ipa reference summary is missing in ltrans unit");
1209*e4b17023SJohn Marino }
1210*e4b17023SJohn Marino }
1211*e4b17023SJohn Marino
1212*e4b17023SJohn Marino static bool
gate_reference(void)1213*e4b17023SJohn Marino gate_reference (void)
1214*e4b17023SJohn Marino {
1215*e4b17023SJohn Marino return (flag_ipa_reference
1216*e4b17023SJohn Marino /* Don't bother doing anything if the program has errors. */
1217*e4b17023SJohn Marino && !seen_error ());
1218*e4b17023SJohn Marino }
1219*e4b17023SJohn Marino
1220*e4b17023SJohn Marino struct ipa_opt_pass_d pass_ipa_reference =
1221*e4b17023SJohn Marino {
1222*e4b17023SJohn Marino {
1223*e4b17023SJohn Marino IPA_PASS,
1224*e4b17023SJohn Marino "static-var", /* name */
1225*e4b17023SJohn Marino gate_reference, /* gate */
1226*e4b17023SJohn Marino propagate, /* execute */
1227*e4b17023SJohn Marino NULL, /* sub */
1228*e4b17023SJohn Marino NULL, /* next */
1229*e4b17023SJohn Marino 0, /* static_pass_number */
1230*e4b17023SJohn Marino TV_IPA_REFERENCE, /* tv_id */
1231*e4b17023SJohn Marino 0, /* properties_required */
1232*e4b17023SJohn Marino 0, /* properties_provided */
1233*e4b17023SJohn Marino 0, /* properties_destroyed */
1234*e4b17023SJohn Marino 0, /* todo_flags_start */
1235*e4b17023SJohn Marino 0 /* todo_flags_finish */
1236*e4b17023SJohn Marino },
1237*e4b17023SJohn Marino NULL, /* generate_summary */
1238*e4b17023SJohn Marino NULL, /* write_summary */
1239*e4b17023SJohn Marino NULL, /* read_summary */
1240*e4b17023SJohn Marino ipa_reference_write_optimization_summary,/* write_optimization_summary */
1241*e4b17023SJohn Marino ipa_reference_read_optimization_summary,/* read_optimization_summary */
1242*e4b17023SJohn Marino NULL, /* stmt_fixup */
1243*e4b17023SJohn Marino 0, /* TODOs */
1244*e4b17023SJohn Marino NULL, /* function_transform */
1245*e4b17023SJohn Marino NULL /* variable_transform */
1246*e4b17023SJohn Marino };
1247