Backport from LTO branch:
[gcc.git] / gcc / ipa-reference.c
1 /* Callgraph based analysis of static variables.
2 Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
3 Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
20
21 /* This file gathers information about how variables whose scope is
22 confined to the compilation unit are used.
23
24 There are two categories of information produced by this pass:
25
26 1) The addressable (TREE_ADDRESSABLE) bit and readonly
27 (TREE_READONLY) bit associated with these variables is properly set
28 based on scanning all of the code withing the compilation unit.
29
30 2) The transitive call site specific clobber effects are computed
31 for the variables whose scope is contained within this compilation
32 unit.
33
34 First each function and static variable initialization is analyzed
35 to determine which local static variables are either read, written,
36 or have their address taken. Any local static that has its address
37 taken is removed from consideration. Once the local read and
38 writes are determined, a transitive closure of this information is
39 performed over the call graph to determine the worst case set of
40 side effects of each call. In later parts of the compiler, these
41 local and global sets are examined to make the call clobbering less
42 traumatic, promote some statics to registers, and improve aliasing
43 information.
44
45 Currently must be run after inlining decisions have been made since
46 otherwise, the local sets will not contain information that is
47 consistent with post inlined state. The global sets are not prone
48 to this problem since they are by definition transitive. */
49
50 #include "config.h"
51 #include "system.h"
52 #include "coretypes.h"
53 #include "tm.h"
54 #include "tree.h"
55 #include "tree-flow.h"
56 #include "tree-inline.h"
57 #include "tree-pass.h"
58 #include "langhooks.h"
59 #include "pointer-set.h"
60 #include "ggc.h"
61 #include "ipa-utils.h"
62 #include "ipa-reference.h"
63 #include "c-common.h"
64 #include "gimple.h"
65 #include "cgraph.h"
66 #include "output.h"
67 #include "flags.h"
68 #include "timevar.h"
69 #include "diagnostic.h"
70 #include "langhooks.h"
71
72 /* This splay tree contains all of the static variables that are
73 being considered by the compilation level alias analysis. For
74 module_at_a_time compilation, this is the set of static but not
75 public variables. Any variables that either have their address
76 taken or participate in otherwise unsavory operations are deleted
77 from this list. */
78 static GTY((param1_is(int), param2_is(tree)))
79 splay_tree reference_vars_to_consider;
80
81 /* This bitmap is used to knock out the module static variables whose
82 addresses have been taken and passed around. */
83 static bitmap module_statics_escape;
84
85 /* This bitmap is used to knock out the module static variables that
86 are not readonly. */
87 static bitmap module_statics_written;
88
89 /* A bit is set for every module static we are considering. This is
90 ored into the local info when asm code is found that clobbers all
91 memory. */
92 static bitmap all_module_statics;
93
94 static struct pointer_set_t *visited_nodes;
95
96 static bitmap_obstack ipa_obstack;
97
98 enum initialization_status_t
99 {
100 UNINITIALIZED,
101 RUNNING,
102 FINISHED
103 };
104
105 tree memory_identifier_string;
106
107 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
108 static inline ipa_reference_vars_info_t
109 get_reference_vars_info_from_cgraph (struct cgraph_node * node)
110 {
111 return get_function_ann (node->decl)->reference_vars_info;
112 }
113
114 /* Get a bitmap that contains all of the locally referenced static
115 variables for function FN. */
116 static ipa_reference_local_vars_info_t
117 get_local_reference_vars_info (tree fn)
118 {
119 ipa_reference_vars_info_t info = get_function_ann (fn)->reference_vars_info;
120
121 if (info)
122 return info->local;
123 else
124 /* This phase was not run. */
125 return NULL;
126 }
127
128 /* Get a bitmap that contains all of the globally referenced static
129 variables for function FN. */
130
131 static ipa_reference_global_vars_info_t
132 get_global_reference_vars_info (tree fn)
133 {
134 ipa_reference_vars_info_t info = get_function_ann (fn)->reference_vars_info;
135
136 if (info)
137 return info->global;
138 else
139 /* This phase was not run. */
140 return NULL;
141 }
142
143 /* Return a bitmap indexed by VAR_DECL uid for the static variables
144 that may be read locally by the execution of the function fn.
145 Returns NULL if no data is available. */
146
147 bitmap
148 ipa_reference_get_read_local (tree fn)
149 {
150 ipa_reference_local_vars_info_t l = get_local_reference_vars_info (fn);
151 if (l)
152 return l->statics_read;
153 else
154 return NULL;
155 }
156
157 /* Return a bitmap indexed by VAR_DECL uid for the static variables
158 that may be written locally by the execution of the function fn.
159 Returns NULL if no data is available. */
160
161 bitmap
162 ipa_reference_get_written_local (tree fn)
163 {
164 ipa_reference_local_vars_info_t l = get_local_reference_vars_info (fn);
165 if (l)
166 return l->statics_written;
167 else
168 return NULL;
169 }
170
171 /* Return a bitmap indexed by VAR_DECL uid for the static variables
172 that are read during the execution of the function FN. Returns
173 NULL if no data is available. */
174
175 bitmap
176 ipa_reference_get_read_global (tree fn)
177 {
178 ipa_reference_global_vars_info_t g = get_global_reference_vars_info (fn);
179 if (g)
180 return g->statics_read;
181 else
182 return NULL;
183 }
184
185 /* Return a bitmap indexed by VAR_DECL uid for the static variables
186 that are written during the execution of the function FN. Note
187 that variables written may or may not be read during the function
188 call. Returns NULL if no data is available. */
189
190 bitmap
191 ipa_reference_get_written_global (tree fn)
192 {
193 ipa_reference_global_vars_info_t g = get_global_reference_vars_info (fn);
194 if (g)
195 return g->statics_written;
196 else
197 return NULL;
198 }
199
200 /* Return a bitmap indexed by_DECL_UID uid for the static variables
201 that are not read during the execution of the function FN. Returns
202 NULL if no data is available. */
203
204 bitmap
205 ipa_reference_get_not_read_global (tree fn)
206 {
207 ipa_reference_global_vars_info_t g = get_global_reference_vars_info (fn);
208 if (g)
209 return g->statics_not_read;
210 else
211 return NULL;
212 }
213
214 /* Return a bitmap indexed by DECL_UID uid for the static variables
215 that are not written during the execution of the function FN. Note
216 that variables written may or may not be read during the function
217 call. Returns NULL if no data is available. */
218
219 bitmap
220 ipa_reference_get_not_written_global (tree fn)
221 {
222 ipa_reference_global_vars_info_t g = get_global_reference_vars_info (fn);
223 if (g)
224 return g->statics_not_written;
225 else
226 return NULL;
227 }
228
229 \f
230
231 /* Add VAR to all_module_statics and the two
232 reference_vars_to_consider* sets. */
233
234 static inline void
235 add_static_var (tree var)
236 {
237 int uid = DECL_UID (var);
238 if (!bitmap_bit_p (all_module_statics, uid))
239 {
240 splay_tree_insert (reference_vars_to_consider,
241 uid, (splay_tree_value)var);
242 bitmap_set_bit (all_module_statics, uid);
243 }
244 }
245
246 /* Return true if the variable T is the right kind of static variable to
247 perform compilation unit scope escape analysis. */
248
249 static inline bool
250 has_proper_scope_for_analysis (tree t)
251 {
252 /* If the variable has the "used" attribute, treat it as if it had a
253 been touched by the devil. */
254 if (lookup_attribute ("used", DECL_ATTRIBUTES (t)))
255 return false;
256
257 /* Do not want to do anything with volatile except mark any
258 function that uses one to be not const or pure. */
259 if (TREE_THIS_VOLATILE (t))
260 return false;
261
262 /* Do not care about a local automatic that is not static. */
263 if (!TREE_STATIC (t) && !DECL_EXTERNAL (t))
264 return false;
265
266 if (DECL_EXTERNAL (t) || TREE_PUBLIC (t))
267 return false;
268
269 /* We cannot touch decls where the type needs constructing. */
270 if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (t)))
271 return false;
272
273 /* This is a variable we care about. Check if we have seen it
274 before, and if not add it the set of variables we care about. */
275 if (!bitmap_bit_p (all_module_statics, DECL_UID (t)))
276 add_static_var (t);
277
278 return true;
279 }
280
281 /* If T is a VAR_DECL for a static that we are interested in, add the
282 uid to the bitmap. */
283
284 static void
285 check_operand (ipa_reference_local_vars_info_t local,
286 tree t, bool checking_write)
287 {
288 if (!t) return;
289
290 if ((TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == FUNCTION_DECL)
291 && (has_proper_scope_for_analysis (t)))
292 {
293 if (checking_write)
294 {
295 if (local)
296 bitmap_set_bit (local->statics_written, DECL_UID (t));
297 /* Mark the write so we can tell which statics are
298 readonly. */
299 bitmap_set_bit (module_statics_written, DECL_UID (t));
300 }
301 else if (local)
302 bitmap_set_bit (local->statics_read, DECL_UID (t));
303 }
304 }
305
306 /* Examine tree T for references to static variables. All internal
307 references like array references or indirect references are added
308 to the READ_BM. Direct references are added to either READ_BM or
309 WRITE_BM depending on the value of CHECKING_WRITE. */
310
311 static void
312 check_tree (ipa_reference_local_vars_info_t local, tree t, bool checking_write)
313 {
314 if ((TREE_CODE (t) == EXC_PTR_EXPR) || (TREE_CODE (t) == FILTER_EXPR))
315 return;
316
317 while (TREE_CODE (t) == REALPART_EXPR
318 || TREE_CODE (t) == IMAGPART_EXPR
319 || handled_component_p (t))
320 {
321 if (TREE_CODE (t) == ARRAY_REF)
322 check_operand (local, TREE_OPERAND (t, 1), false);
323 t = TREE_OPERAND (t, 0);
324 }
325
326 /* The bottom of an indirect reference can only be read, not
327 written. So just recurse and whatever we find, check it against
328 the read bitmaps. */
329
330 /* if (INDIRECT_REF_P (t) || TREE_CODE (t) == MEM_REF) */
331 /* FIXME when we have array_ref's of pointers. */
332 if (INDIRECT_REF_P (t))
333 check_tree (local, TREE_OPERAND (t, 0), false);
334
335 if (SSA_VAR_P (t))
336 check_operand (local, t, checking_write);
337 }
338
339 /* Scan tree T to see if there are any addresses taken in within T. */
340
341 static void
342 look_for_address_of (tree t)
343 {
344 if (TREE_CODE (t) == ADDR_EXPR)
345 {
346 tree x = get_base_var (t);
347 if (TREE_CODE (x) == VAR_DECL || TREE_CODE (x) == FUNCTION_DECL)
348 if (has_proper_scope_for_analysis (x))
349 bitmap_set_bit (module_statics_escape, DECL_UID (x));
350 }
351 }
352
353 /* Check to see if T is a read or address of operation on a static var
354 we are interested in analyzing. LOCAL is passed in to get access
355 to its bit vectors. Local is NULL if this is called from a static
356 initializer. */
357
358 static void
359 check_rhs_var (ipa_reference_local_vars_info_t local, tree t)
360 {
361 look_for_address_of (t);
362
363 if (local == NULL)
364 return;
365
366 check_tree(local, t, false);
367 }
368
369 /* Check to see if T is an assignment to a static var we are
370 interested in analyzing. LOCAL is passed in to get access to its bit
371 vectors. */
372
373 static void
374 check_lhs_var (ipa_reference_local_vars_info_t local, tree t)
375 {
376 if (local == NULL)
377 return;
378
379 check_tree(local, t, true);
380 }
381
382 /* This is a scaled down version of get_asm_expr_operands from
383 tree_ssa_operands.c. The version there runs much later and assumes
384 that aliasing information is already available. Here we are just
385 trying to find if the set of inputs and outputs contain references
386 or address of operations to local static variables. FN is the
387 function being analyzed and STMT is the actual asm statement. */
388
389 static void
390 get_asm_stmt_operands (ipa_reference_local_vars_info_t local, gimple stmt)
391 {
392 size_t noutputs = gimple_asm_noutputs (stmt);
393 const char **oconstraints
394 = (const char **) alloca ((noutputs) * sizeof (const char *));
395 size_t i;
396 tree op;
397 const char *constraint;
398 bool allows_mem, allows_reg, is_inout;
399
400 for (i = 0; i < noutputs; i++)
401 {
402 op = gimple_asm_output_op (stmt, i);
403 oconstraints[i] = constraint
404 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
405 parse_output_constraint (&constraint, i, 0, 0,
406 &allows_mem, &allows_reg, &is_inout);
407
408 check_lhs_var (local, TREE_VALUE (op));
409 }
410
411 for (i = 0; i < gimple_asm_ninputs (stmt); i++)
412 {
413 op = gimple_asm_input_op (stmt, i);
414 constraint
415 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
416 parse_input_constraint (&constraint, 0, 0, noutputs, 0,
417 oconstraints, &allows_mem, &allows_reg);
418
419 check_rhs_var (local, TREE_VALUE (op));
420 }
421
422 for (i = 0; i < gimple_asm_nclobbers (stmt); i++)
423 {
424 op = gimple_asm_clobber_op (stmt, i);
425 if (simple_cst_equal(TREE_VALUE (op), memory_identifier_string) == 1)
426 {
427 /* Abandon all hope, ye who enter here. */
428 local->calls_read_all = true;
429 local->calls_write_all = true;
430 }
431 }
432 }
433
434 /* Check the parameters of a function call from CALLER to CALL_EXPR to
435 see if any of them are static vars. Also check to see if this is
436 either an indirect call, a call outside the compilation unit, or
437 has special attributes that effect the clobbers. The caller
438 parameter is the tree node for the caller and the second operand is
439 the tree node for the entire call expression. */
440
441 static void
442 check_call (ipa_reference_local_vars_info_t local, gimple stmt)
443 {
444 int flags = gimple_call_flags (stmt);
445 tree operand;
446 tree callee_t = gimple_call_fndecl (stmt);
447 enum availability avail = AVAIL_NOT_AVAILABLE;
448 size_t i;
449
450 if ((operand = gimple_call_lhs (stmt)) != NULL)
451 check_lhs_var (local, operand);
452
453 for (i = 0; i < gimple_call_num_args (stmt); i++)
454 check_rhs_var (local, gimple_call_arg (stmt, i));
455
456 if (callee_t)
457 {
458 struct cgraph_node* callee = cgraph_node(callee_t);
459 avail = cgraph_function_body_availability (callee);
460 }
461
462 if (avail == AVAIL_NOT_AVAILABLE || avail == AVAIL_OVERWRITABLE)
463 if (local)
464 {
465 if (flags & ECF_PURE)
466 local->calls_read_all = true;
467 else
468 {
469 local->calls_read_all = true;
470 local->calls_write_all = true;
471 }
472 }
473 }
474
475 /* TP is the part of the tree currently under the microscope.
476 WALK_SUBTREES is part of the walk_tree api but is unused here.
477 DATA is cgraph_node of the function being walked. */
478
479 /* FIXME: When this is converted to run over SSA form, this code
480 should be converted to use the operand scanner. */
481
482 static tree
483 scan_stmt_for_static_refs (gimple_stmt_iterator *gsip, bool *handled_ops_p,
484 struct walk_stmt_info *data)
485 {
486 struct cgraph_node *fn = (struct cgraph_node *) data->info;
487 gimple stmt = gsi_stmt (*gsip);
488 ipa_reference_local_vars_info_t local = NULL;
489 if (fn)
490 local = get_reference_vars_info_from_cgraph (fn)->local;
491
492 switch (gimple_code (stmt))
493 {
494 case GIMPLE_ASSIGN:
495 {
496 /* First look on the lhs and see what variable is stored to */
497 tree lhs = gimple_assign_lhs (stmt);
498 tree rhs1 = gimple_assign_rhs1 (stmt);
499 tree rhs2 = gimple_assign_rhs2 (stmt);
500 enum tree_code code = gimple_assign_rhs_code (stmt);
501
502 check_lhs_var (local, lhs);
503
504 /* For the purposes of figuring out what the cast affects */
505
506 /* Next check the operands on the rhs to see if they are ok. */
507 switch (TREE_CODE_CLASS (code))
508 {
509 case tcc_binary:
510 case tcc_comparison:
511 check_rhs_var (local, rhs1);
512 check_rhs_var (local, rhs2);
513 break;
514
515 case tcc_unary:
516 case tcc_reference:
517 case tcc_declaration:
518 check_rhs_var (local, rhs1);
519 break;
520
521 case tcc_expression:
522 switch (code)
523 {
524 case ADDR_EXPR:
525 check_rhs_var (local, rhs1);
526 break;
527 default:
528 break;
529 }
530 break;
531 default:
532 break;
533 }
534 *handled_ops_p = true;
535 }
536 break;
537
538 case GIMPLE_LABEL:
539 if (DECL_NONLOCAL (gimple_label_label (stmt)))
540 {
541 /* Target of long jump. */
542 local->calls_read_all = true;
543 local->calls_write_all = true;
544 }
545 break;
546
547 case GIMPLE_CALL:
548 check_call (local, stmt);
549 *handled_ops_p = true;
550 break;
551
552 case GIMPLE_ASM:
553 get_asm_stmt_operands (local, stmt);
554 *handled_ops_p = true;
555 break;
556
557 default:
558 break;
559 }
560 return NULL;
561 }
562
563 /* Call-back to scan GIMPLE operands for static references. This is supposed
564 to work with scan_stmt_for_static_refs so the real call-back data is stored
565 inside a walk_stmt_info struct. Callers using the walk_tree interface must
566 also wrap the call-back data in a walk_stmt_info struct. */
567
568 static tree
569 scan_op_for_static_refs (tree *tp, int *walk_subtrees, void *data)
570 {
571 struct walk_stmt_info *wi = (struct walk_stmt_info*) data;
572 struct cgraph_node *fn = (struct cgraph_node *) wi->info;
573 tree t = *tp;
574 ipa_reference_local_vars_info_t local = NULL;
575 if (fn)
576 local = get_reference_vars_info_from_cgraph (fn)->local;
577
578 switch (TREE_CODE (t))
579 {
580 case VAR_DECL:
581 if (DECL_INITIAL (t))
582 walk_tree (&DECL_INITIAL (t), scan_op_for_static_refs, data,
583 wi->pset);
584 *walk_subtrees = 0;
585 break;
586
587 case ADDR_EXPR:
588 /* This case is here to find addresses on rhs of constructors in
589 decl_initial of static variables. */
590 check_rhs_var (local, t);
591 *walk_subtrees = 0;
592 break;
593
594 default:
595 break;
596 }
597 return NULL;
598 }
599
600 /* Lookup the tree node for the static variable that has UID. */
601 static tree
602 get_static_decl (int index)
603 {
604 splay_tree_node stn =
605 splay_tree_lookup (reference_vars_to_consider, index);
606 if (stn)
607 return (tree)stn->value;
608 return NULL;
609 }
610
611 /* Lookup the tree node for the static variable that has UID and
612 convert the name to a string for debugging. */
613
614 static const char *
615 get_static_name (int index)
616 {
617 splay_tree_node stn =
618 splay_tree_lookup (reference_vars_to_consider, index);
619 if (stn)
620 return lang_hooks.decl_printable_name ((tree)(stn->value), 2);
621 return NULL;
622 }
623
624 /* Or in all of the bits from every callee into X, the caller's, bit
625 vector. There are several cases to check to avoid the sparse
626 bitmap oring. */
627
628 static void
629 propagate_bits (struct cgraph_node *x)
630 {
631 ipa_reference_vars_info_t x_info = get_reference_vars_info_from_cgraph (x);
632 ipa_reference_global_vars_info_t x_global = x_info->global;
633
634 struct cgraph_edge *e;
635 for (e = x->callees; e; e = e->next_callee)
636 {
637 struct cgraph_node *y = e->callee;
638
639 /* Only look at the master nodes and skip external nodes. */
640 y = cgraph_master_clone (y);
641 if (y)
642 {
643 if (get_reference_vars_info_from_cgraph (y))
644 {
645 ipa_reference_vars_info_t y_info
646 = get_reference_vars_info_from_cgraph (y);
647 ipa_reference_global_vars_info_t y_global = y_info->global;
648
649 if (x_global->statics_read
650 != all_module_statics)
651 {
652 if (y_global->statics_read
653 == all_module_statics)
654 {
655 BITMAP_FREE (x_global->statics_read);
656 x_global->statics_read
657 = all_module_statics;
658 }
659 /* Skip bitmaps that are pointer equal to node's bitmap
660 (no reason to spin within the cycle). */
661 else if (x_global->statics_read
662 != y_global->statics_read)
663 bitmap_ior_into (x_global->statics_read,
664 y_global->statics_read);
665 }
666
667 if (x_global->statics_written
668 != all_module_statics)
669 {
670 if (y_global->statics_written
671 == all_module_statics)
672 {
673 BITMAP_FREE (x_global->statics_written);
674 x_global->statics_written
675 = all_module_statics;
676 }
677 /* Skip bitmaps that are pointer equal to node's bitmap
678 (no reason to spin within the cycle). */
679 else if (x_global->statics_written
680 != y_global->statics_written)
681 bitmap_ior_into (x_global->statics_written,
682 y_global->statics_written);
683 }
684 }
685 else
686 {
687 gcc_unreachable ();
688 }
689 }
690 }
691 }
692
693 /* Look at all of the callees of X to see which ones represent inlined
694 calls. For each of these callees, merge their local info into
695 TARGET and check their children recursively.
696
697 This function goes away when Jan changes the inliner and IPA
698 analysis so that this is not run between the time when inlining
699 decisions are made and when the inlining actually occurs. */
700
701 static void
702 merge_callee_local_info (struct cgraph_node *target,
703 struct cgraph_node *x)
704 {
705 struct cgraph_edge *e;
706 ipa_reference_local_vars_info_t x_l =
707 get_reference_vars_info_from_cgraph (target)->local;
708
709 /* Make the world safe for tail recursion. */
710 struct ipa_dfs_info *node_info = (struct ipa_dfs_info *) x->aux;
711
712 if (node_info->aux)
713 return;
714
715 node_info->aux = x;
716
717 for (e = x->callees; e; e = e->next_callee)
718 {
719 struct cgraph_node *y = e->callee;
720 if (y->global.inlined_to)
721 {
722 ipa_reference_vars_info_t y_info;
723 ipa_reference_local_vars_info_t y_l;
724 struct cgraph_node* orig_y = y;
725
726 y = cgraph_master_clone (y);
727 if (y)
728 {
729 y_info = get_reference_vars_info_from_cgraph (y);
730 y_l = y_info->local;
731 if (x_l != y_l)
732 {
733 bitmap_ior_into (x_l->statics_read,
734 y_l->statics_read);
735 bitmap_ior_into (x_l->statics_written,
736 y_l->statics_written);
737 }
738 x_l->calls_read_all |= y_l->calls_read_all;
739 x_l->calls_write_all |= y_l->calls_write_all;
740 merge_callee_local_info (target, y);
741 }
742 else
743 {
744 fprintf(stderr, "suspect inlining of ");
745 dump_cgraph_node (stderr, orig_y);
746 fprintf(stderr, "\ninto ");
747 dump_cgraph_node (stderr, target);
748 dump_cgraph (stderr);
749 gcc_assert(false);
750 }
751 }
752 }
753
754 node_info->aux = NULL;
755 }
756
757 /* The init routine for analyzing global static variable usage. See
758 comments at top for description. */
759 static void
760 ipa_init (void)
761 {
762 struct cgraph_node *node;
763 memory_identifier_string = build_string(7, "memory");
764
765 reference_vars_to_consider =
766 splay_tree_new_ggc (splay_tree_compare_ints);
767
768 bitmap_obstack_initialize (&ipa_obstack);
769 module_statics_escape = BITMAP_ALLOC (&ipa_obstack);
770 module_statics_written = BITMAP_ALLOC (&ipa_obstack);
771 all_module_statics = BITMAP_ALLOC (&ipa_obstack);
772
773 /* This will add NODE->DECL to the splay trees. */
774 for (node = cgraph_nodes; node; node = node->next)
775 has_proper_scope_for_analysis (node->decl);
776
777 /* There are some shared nodes, in particular the initializers on
778 static declarations. We do not need to scan them more than once
779 since all we would be interested in are the addressof
780 operations. */
781 visited_nodes = pointer_set_create ();
782 }
783
784 /* Check out the rhs of a static or global initialization VNODE to see
785 if any of them contain addressof operations. Note that some of
786 these variables may not even be referenced in the code in this
787 compilation unit but their right hand sides may contain references
788 to variables defined within this unit. */
789
790 static void
791 analyze_variable (struct varpool_node *vnode)
792 {
793 struct walk_stmt_info wi;
794 tree global = vnode->decl;
795
796 memset (&wi, 0, sizeof (wi));
797 wi.pset = visited_nodes;
798 walk_tree (&DECL_INITIAL (global), scan_op_for_static_refs,
799 &wi, wi.pset);
800 }
801
802 /* Set up the persistent info for FN. */
803
804 static ipa_reference_local_vars_info_t
805 init_function_info (struct cgraph_node *fn)
806 {
807 ipa_reference_vars_info_t info
808 = XCNEW (struct ipa_reference_vars_info_d);
809 ipa_reference_local_vars_info_t l
810 = XCNEW (struct ipa_reference_local_vars_info_d);
811 tree decl = fn->decl;
812
813 /* Add the info to the tree's annotation. */
814 get_function_ann (decl)->reference_vars_info = info;
815
816 info->local = l;
817 l->statics_read = BITMAP_ALLOC (&ipa_obstack);
818 l->statics_written = BITMAP_ALLOC (&ipa_obstack);
819
820 return l;
821 }
822
823 /* This is the main routine for finding the reference patterns for
824 global variables within a function FN. */
825
826 static void
827 analyze_function (struct cgraph_node *fn)
828 {
829 ipa_reference_local_vars_info_t l = init_function_info (fn);
830 tree decl = fn->decl;
831 struct walk_stmt_info wi;
832 struct function *this_cfun = DECL_STRUCT_FUNCTION (decl);
833 basic_block this_block;
834
835 if (dump_file)
836 fprintf (dump_file, "\n local analysis of %s\n", cgraph_node_name (fn));
837
838 FOR_EACH_BB_FN (this_block, this_cfun)
839 {
840 gimple_stmt_iterator gsi;
841 gimple phi;
842 tree op;
843 use_operand_p use;
844 ssa_op_iter iter;
845
846 /* Find the addresses taken in phi node arguments. */
847 for (gsi = gsi_start_phis (this_block);
848 !gsi_end_p (gsi);
849 gsi_next (&gsi))
850 {
851 phi = gsi_stmt (gsi);
852 FOR_EACH_PHI_ARG (use, phi, iter, SSA_OP_USE)
853 {
854 op = USE_FROM_PTR (use);
855 if (TREE_CODE (op) == ADDR_EXPR)
856 check_rhs_var (l, op);
857 }
858 }
859
860 memset (&wi, 0, sizeof (wi));
861 wi.info = fn;
862 wi.pset = visited_nodes;
863 for (gsi = gsi_start_bb (this_block); !gsi_end_p (gsi); gsi_next (&gsi))
864 walk_gimple_stmt (&gsi, scan_stmt_for_static_refs,
865 scan_op_for_static_refs, &wi);
866 }
867
868 /* There may be const decls with interesting right hand sides. */
869 if (DECL_STRUCT_FUNCTION (decl))
870 {
871 tree step;
872 for (step = DECL_STRUCT_FUNCTION (decl)->local_decls;
873 step;
874 step = TREE_CHAIN (step))
875 {
876 tree var = TREE_VALUE (step);
877 if (TREE_CODE (var) == VAR_DECL
878 && DECL_INITIAL (var)
879 && !TREE_STATIC (var))
880 {
881 memset (&wi, 0, sizeof (wi));
882 wi.info = fn;
883 wi.pset = visited_nodes;
884 walk_tree (&DECL_INITIAL (var), scan_op_for_static_refs,
885 &wi, wi.pset);
886 }
887 }
888 }
889 }
890
891 /* If FN is avail == AVAIL_OVERWRITABLE, replace the effects bit
892 vectors with worst case bit vectors. We had to analyze it above to
893 find out if it took the address of any statics. However, now that
894 we know that, we can get rid of all of the other side effects. */
895
896 static void
897 clean_function (struct cgraph_node *fn)
898 {
899 ipa_reference_vars_info_t info = get_reference_vars_info_from_cgraph (fn);
900 ipa_reference_local_vars_info_t l = info->local;
901 ipa_reference_global_vars_info_t g = info->global;
902
903 if (l)
904 {
905 if (l->statics_read
906 && l->statics_read != all_module_statics)
907 BITMAP_FREE (l->statics_read);
908 if (l->statics_written
909 &&l->statics_written != all_module_statics)
910 BITMAP_FREE (l->statics_written);
911 free (l);
912 }
913
914 if (g)
915 {
916 if (g->statics_read
917 && g->statics_read != all_module_statics)
918 BITMAP_FREE (g->statics_read);
919
920 if (g->statics_written
921 && g->statics_written != all_module_statics)
922 BITMAP_FREE (g->statics_written);
923
924 if (g->statics_not_read
925 && g->statics_not_read != all_module_statics)
926 BITMAP_FREE (g->statics_not_read);
927
928 if (g->statics_not_written
929 && g->statics_not_written != all_module_statics)
930 BITMAP_FREE (g->statics_not_written);
931 free (g);
932 }
933
934 free (get_function_ann (fn->decl)->reference_vars_info);
935 get_function_ann (fn->decl)->reference_vars_info = NULL;
936 }
937
938
939 /* Analyze each function in the cgraph to see which global or statics
940 are read or written. */
941
942 static void
943 generate_summary (void)
944 {
945 struct cgraph_node *node;
946 struct varpool_node *vnode;
947 unsigned int index;
948 bitmap_iterator bi;
949 bitmap module_statics_readonly;
950 bitmap bm_temp;
951
952 ipa_init ();
953 module_statics_readonly = BITMAP_ALLOC (&ipa_obstack);
954 bm_temp = BITMAP_ALLOC (&ipa_obstack);
955
956 /* Process all of the variables first. */
957 FOR_EACH_STATIC_INITIALIZER (vnode)
958 analyze_variable (vnode);
959
960 /* Process all of the functions next.
961
962 We do not want to process any of the clones so we check that this
963 is a master clone. However, we do need to process any
964 AVAIL_OVERWRITABLE functions (these are never clones) because
965 they may cause a static variable to escape. The code that can
966 overwrite such a function cannot access the statics because it
967 would not be in the same compilation unit. When the analysis is
968 finished, the computed information of these AVAIL_OVERWRITABLE is
969 replaced with worst case info.
970 */
971 for (node = cgraph_nodes; node; node = node->next)
972 if (node->analyzed
973 && (cgraph_is_master_clone (node)
974 || (cgraph_function_body_availability (node)
975 == AVAIL_OVERWRITABLE)))
976 analyze_function (node);
977
978 pointer_set_destroy (visited_nodes);
979 visited_nodes = NULL;
980
981 /* Prune out the variables that were found to behave badly
982 (i.e. have their address taken). */
983 EXECUTE_IF_SET_IN_BITMAP (module_statics_escape, 0, index, bi)
984 {
985 splay_tree_remove (reference_vars_to_consider, index);
986 }
987
988 bitmap_and_compl_into (all_module_statics,
989 module_statics_escape);
990
991 bitmap_and_compl (module_statics_readonly, all_module_statics,
992 module_statics_written);
993
994 /* If the address is not taken, we can unset the addressable bit
995 on this variable. */
996 EXECUTE_IF_SET_IN_BITMAP (all_module_statics, 0, index, bi)
997 {
998 tree var = get_static_decl (index);
999 TREE_ADDRESSABLE (var) = 0;
1000 if (dump_file)
1001 fprintf (dump_file, "Not TREE_ADDRESSABLE var %s\n",
1002 get_static_name (index));
1003 }
1004
1005 /* If the variable is never written, we can set the TREE_READONLY
1006 flag. Additionally if it has a DECL_INITIAL that is made up of
1007 constants we can treat the entire global as a constant. */
1008
1009 bitmap_and_compl (module_statics_readonly, all_module_statics,
1010 module_statics_written);
1011 EXECUTE_IF_SET_IN_BITMAP (module_statics_readonly, 0, index, bi)
1012 {
1013 tree var = get_static_decl (index);
1014
1015 /* Readonly on a function decl is very different from the
1016 variable. */
1017 if (TREE_CODE (var) == FUNCTION_DECL)
1018 continue;
1019
1020 /* Ignore variables in named sections - changing TREE_READONLY
1021 changes the section flags, potentially causing conflicts with
1022 other variables in the same named section. */
1023 if (DECL_SECTION_NAME (var) == NULL_TREE)
1024 {
1025 TREE_READONLY (var) = 1;
1026 if (dump_file)
1027 fprintf (dump_file, "read-only var %s\n",
1028 get_static_name (index));
1029 }
1030 }
1031
1032 BITMAP_FREE(module_statics_escape);
1033 BITMAP_FREE(module_statics_written);
1034
1035 if (dump_file)
1036 EXECUTE_IF_SET_IN_BITMAP (all_module_statics, 0, index, bi)
1037 {
1038 fprintf (dump_file, "\nPromotable global:%s",
1039 get_static_name (index));
1040 }
1041
1042 for (node = cgraph_nodes; node; node = node->next)
1043 if (node->analyzed
1044 && (cgraph_is_master_clone (node)
1045 || (cgraph_function_body_availability (node)
1046 == AVAIL_OVERWRITABLE)))
1047 {
1048 ipa_reference_local_vars_info_t l;
1049 l = get_reference_vars_info_from_cgraph (node)->local;
1050
1051 /* Any variables that are not in all_module_statics are
1052 removed from the local maps. This will include all of the
1053 variables that were found to escape in the function
1054 scanning. */
1055 bitmap_and_into (l->statics_read,
1056 all_module_statics);
1057 bitmap_and_into (l->statics_written,
1058 all_module_statics);
1059 }
1060
1061 BITMAP_FREE(module_statics_readonly);
1062 BITMAP_FREE(bm_temp);
1063
1064 if (dump_file)
1065 for (node = cgraph_nodes; node; node = node->next)
1066 if (node->analyzed
1067 && (cgraph_is_master_clone (node)
1068 || (cgraph_function_body_availability (node)
1069 == AVAIL_OVERWRITABLE)))
1070 {
1071 ipa_reference_local_vars_info_t l;
1072 unsigned int index;
1073 bitmap_iterator bi;
1074
1075 l = get_reference_vars_info_from_cgraph (node)->local;
1076 fprintf (dump_file,
1077 "\nFunction name:%s/%i:",
1078 cgraph_node_name (node), node->uid);
1079 fprintf (dump_file, "\n locals read: ");
1080 EXECUTE_IF_SET_IN_BITMAP (l->statics_read,
1081 0, index, bi)
1082 {
1083 fprintf (dump_file, "%s ",
1084 get_static_name (index));
1085 }
1086 fprintf (dump_file, "\n locals written: ");
1087 EXECUTE_IF_SET_IN_BITMAP (l->statics_written,
1088 0, index, bi)
1089 {
1090 fprintf(dump_file, "%s ",
1091 get_static_name (index));
1092 }
1093 }
1094 }
1095 \f
1096 /* Produce the global information by preforming a transitive closure
1097 on the local information that was produced by ipa_analyze_function
1098 and ipa_analyze_variable. */
1099
1100 static unsigned int
1101 propagate (void)
1102 {
1103 struct cgraph_node *node;
1104 struct cgraph_node *w;
1105 struct cgraph_node **order =
1106 XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
1107 int order_pos = ipa_utils_reduced_inorder (order, false, true);
1108 int i;
1109
1110 if (dump_file)
1111 dump_cgraph (dump_file);
1112
1113 /* Propagate the local information thru the call graph to produce
1114 the global information. All the nodes within a cycle will have
1115 the same info so we collapse cycles first. Then we can do the
1116 propagation in one pass from the leaves to the roots. */
1117 order_pos = ipa_utils_reduced_inorder (order, true, true);
1118 if (dump_file)
1119 ipa_utils_print_order(dump_file, "reduced", order, order_pos);
1120
1121 for (i = 0; i < order_pos; i++ )
1122 {
1123 ipa_reference_vars_info_t node_info;
1124 ipa_reference_global_vars_info_t node_g =
1125 XCNEW (struct ipa_reference_global_vars_info_d);
1126 ipa_reference_local_vars_info_t node_l;
1127
1128 bool read_all;
1129 bool write_all;
1130 struct ipa_dfs_info * w_info;
1131
1132 node = order[i];
1133 node_info = get_reference_vars_info_from_cgraph (node);
1134 if (!node_info)
1135 {
1136 dump_cgraph_node (stderr, node);
1137 dump_cgraph (stderr);
1138 gcc_unreachable ();
1139 }
1140
1141 node_info->global = node_g;
1142 node_l = node_info->local;
1143
1144 read_all = node_l->calls_read_all;
1145 write_all = node_l->calls_write_all;
1146
1147 /* If any node in a cycle is calls_read_all or calls_write_all
1148 they all are. */
1149 w_info = (struct ipa_dfs_info *) node->aux;
1150 w = w_info->next_cycle;
1151 while (w)
1152 {
1153 ipa_reference_local_vars_info_t w_l =
1154 get_reference_vars_info_from_cgraph (w)->local;
1155 read_all |= w_l->calls_read_all;
1156 write_all |= w_l->calls_write_all;
1157
1158 w_info = (struct ipa_dfs_info *) w->aux;
1159 w = w_info->next_cycle;
1160 }
1161
1162 /* Initialized the bitmaps for the reduced nodes */
1163 if (read_all)
1164 node_g->statics_read = all_module_statics;
1165 else
1166 {
1167 node_g->statics_read = BITMAP_ALLOC (&ipa_obstack);
1168 bitmap_copy (node_g->statics_read,
1169 node_l->statics_read);
1170 }
1171
1172 if (write_all)
1173 node_g->statics_written = all_module_statics;
1174 else
1175 {
1176 node_g->statics_written = BITMAP_ALLOC (&ipa_obstack);
1177 bitmap_copy (node_g->statics_written,
1178 node_l->statics_written);
1179 }
1180
1181 w_info = (struct ipa_dfs_info *) node->aux;
1182 w = w_info->next_cycle;
1183 while (w)
1184 {
1185 ipa_reference_vars_info_t w_ri =
1186 get_reference_vars_info_from_cgraph (w);
1187 ipa_reference_local_vars_info_t w_l = w_ri->local;
1188
1189 /* All nodes within a cycle share the same global info bitmaps. */
1190 w_ri->global = node_g;
1191
1192 /* These global bitmaps are initialized from the local info
1193 of all of the nodes in the region. However there is no
1194 need to do any work if the bitmaps were set to
1195 all_module_statics. */
1196 if (!read_all)
1197 bitmap_ior_into (node_g->statics_read,
1198 w_l->statics_read);
1199 if (!write_all)
1200 bitmap_ior_into (node_g->statics_written,
1201 w_l->statics_written);
1202 w_info = (struct ipa_dfs_info *) w->aux;
1203 w = w_info->next_cycle;
1204 }
1205
1206 w = node;
1207 while (w)
1208 {
1209 propagate_bits (w);
1210 w_info = (struct ipa_dfs_info *) w->aux;
1211 w = w_info->next_cycle;
1212 }
1213 }
1214
1215 /* Need to fix up the local information sets. The information that
1216 has been gathered so far is preinlining. However, the
1217 compilation will progress post inlining so the local sets for the
1218 inlined calls need to be merged into the callers. Note that the
1219 local sets are not shared between all of the nodes in a cycle so
1220 those nodes in the cycle must be processed explicitly. */
1221 for (i = 0; i < order_pos; i++ )
1222 {
1223 struct ipa_dfs_info * w_info;
1224 node = order[i];
1225 merge_callee_local_info (node, node);
1226
1227 w_info = (struct ipa_dfs_info *) node->aux;
1228 w = w_info->next_cycle;
1229 while (w)
1230 {
1231 merge_callee_local_info (w, w);
1232 w_info = (struct ipa_dfs_info *) w->aux;
1233 w = w_info->next_cycle;
1234 }
1235 }
1236
1237 if (dump_file)
1238 {
1239 for (i = 0; i < order_pos; i++ )
1240 {
1241 ipa_reference_vars_info_t node_info;
1242 ipa_reference_global_vars_info_t node_g;
1243 ipa_reference_local_vars_info_t node_l;
1244 unsigned int index;
1245 bitmap_iterator bi;
1246 struct ipa_dfs_info * w_info;
1247
1248 node = order[i];
1249 node_info = get_reference_vars_info_from_cgraph (node);
1250 node_g = node_info->global;
1251 node_l = node_info->local;
1252 fprintf (dump_file,
1253 "\nFunction name:%s/%i:",
1254 cgraph_node_name (node), node->uid);
1255 fprintf (dump_file, "\n locals read: ");
1256 EXECUTE_IF_SET_IN_BITMAP (node_l->statics_read,
1257 0, index, bi)
1258 {
1259 fprintf (dump_file, "%s ",
1260 get_static_name (index));
1261 }
1262 fprintf (dump_file, "\n locals written: ");
1263 EXECUTE_IF_SET_IN_BITMAP (node_l->statics_written,
1264 0, index, bi)
1265 {
1266 fprintf(dump_file, "%s ",
1267 get_static_name (index));
1268 }
1269
1270 w_info = (struct ipa_dfs_info *) node->aux;
1271 w = w_info->next_cycle;
1272 while (w)
1273 {
1274 ipa_reference_vars_info_t w_ri =
1275 get_reference_vars_info_from_cgraph (w);
1276 ipa_reference_local_vars_info_t w_l = w_ri->local;
1277 fprintf (dump_file, "\n next cycle: %s/%i ",
1278 cgraph_node_name (w), w->uid);
1279 fprintf (dump_file, "\n locals read: ");
1280 EXECUTE_IF_SET_IN_BITMAP (w_l->statics_read,
1281 0, index, bi)
1282 {
1283 fprintf (dump_file, "%s ",
1284 get_static_name (index));
1285 }
1286
1287 fprintf (dump_file, "\n locals written: ");
1288 EXECUTE_IF_SET_IN_BITMAP (w_l->statics_written,
1289 0, index, bi)
1290 {
1291 fprintf(dump_file, "%s ",
1292 get_static_name (index));
1293 }
1294
1295
1296 w_info = (struct ipa_dfs_info *) w->aux;
1297 w = w_info->next_cycle;
1298 }
1299 fprintf (dump_file, "\n globals read: ");
1300 EXECUTE_IF_SET_IN_BITMAP (node_g->statics_read,
1301 0, index, bi)
1302 {
1303 fprintf (dump_file, "%s ",
1304 get_static_name (index));
1305 }
1306 fprintf (dump_file, "\n globals written: ");
1307 EXECUTE_IF_SET_IN_BITMAP (node_g->statics_written,
1308 0, index, bi)
1309 {
1310 fprintf (dump_file, "%s ",
1311 get_static_name (index));
1312 }
1313 }
1314 }
1315
1316 /* Cleanup. */
1317 for (i = 0; i < order_pos; i++ )
1318 {
1319 ipa_reference_vars_info_t node_info;
1320 ipa_reference_global_vars_info_t node_g;
1321 node = order[i];
1322 node_info = get_reference_vars_info_from_cgraph (node);
1323 node_g = node_info->global;
1324
1325 /* Create the complimentary sets. These are more useful for
1326 certain apis. */
1327 node_g->statics_not_read = BITMAP_ALLOC (&ipa_obstack);
1328 node_g->statics_not_written = BITMAP_ALLOC (&ipa_obstack);
1329
1330 if (node_g->statics_read != all_module_statics)
1331 {
1332 bitmap_and_compl (node_g->statics_not_read,
1333 all_module_statics,
1334 node_g->statics_read);
1335 }
1336
1337 if (node_g->statics_written
1338 != all_module_statics)
1339 bitmap_and_compl (node_g->statics_not_written,
1340 all_module_statics,
1341 node_g->statics_written);
1342 }
1343
1344 free (order);
1345
1346 for (node = cgraph_nodes; node; node = node->next)
1347 {
1348 /* Get rid of the aux information. */
1349
1350 if (node->aux)
1351 {
1352 free (node->aux);
1353 node->aux = NULL;
1354 }
1355
1356 if (node->analyzed
1357 && (cgraph_function_body_availability (node) == AVAIL_OVERWRITABLE))
1358 clean_function (node);
1359 }
1360 return 0;
1361 }
1362
1363
1364 static bool
1365 gate_reference (void)
1366 {
1367 return (flag_ipa_reference
1368 /* Don't bother doing anything if the program has errors. */
1369 && !(errorcount || sorrycount));
1370 }
1371
1372 struct ipa_opt_pass pass_ipa_reference =
1373 {
1374 {
1375 IPA_PASS,
1376 "static-var", /* name */
1377 gate_reference, /* gate */
1378 propagate, /* execute */
1379 NULL, /* sub */
1380 NULL, /* next */
1381 0, /* static_pass_number */
1382 TV_IPA_REFERENCE, /* tv_id */
1383 0, /* properties_required */
1384 0, /* properties_provided */
1385 0, /* properties_destroyed */
1386 0, /* todo_flags_start */
1387 0 /* todo_flags_finish */
1388 },
1389 generate_summary, /* generate_summary */
1390 NULL, /* write_summary */
1391 NULL, /* read_summary */
1392 NULL, /* function_read_summary */
1393 0, /* TODOs */
1394 NULL, /* function_transform */
1395 NULL /* variable_transform */
1396 };
1397
1398 #include "gt-ipa-reference.h"