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