Mercurial > hg > CbC > CbC_gcc
comparison gcc/tree-ssa-alias.c @ 0:a06113de4d67
first commit
author | kent <kent@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 17 Jul 2009 14:47:48 +0900 |
parents | |
children | 3bfb6c00c1e0 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:a06113de4d67 |
---|---|
1 /* Alias analysis for trees. | |
2 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 | |
3 Free Software Foundation, Inc. | |
4 Contributed by Diego Novillo <dnovillo@redhat.com> | |
5 | |
6 This file is part of GCC. | |
7 | |
8 GCC is free software; you can redistribute it and/or modify | |
9 it under the terms of the GNU General Public License as published by | |
10 the Free Software Foundation; either version 3, or (at your option) | |
11 any later version. | |
12 | |
13 GCC is distributed in the hope that it will be useful, | |
14 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 GNU General Public License 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 #include "config.h" | |
23 #include "system.h" | |
24 #include "coretypes.h" | |
25 #include "tm.h" | |
26 #include "tree.h" | |
27 #include "rtl.h" | |
28 #include "tm_p.h" | |
29 #include "hard-reg-set.h" | |
30 #include "basic-block.h" | |
31 #include "timevar.h" | |
32 #include "expr.h" | |
33 #include "ggc.h" | |
34 #include "langhooks.h" | |
35 #include "flags.h" | |
36 #include "function.h" | |
37 #include "diagnostic.h" | |
38 #include "tree-dump.h" | |
39 #include "gimple.h" | |
40 #include "tree-flow.h" | |
41 #include "tree-inline.h" | |
42 #include "tree-pass.h" | |
43 #include "tree-ssa-structalias.h" | |
44 #include "convert.h" | |
45 #include "params.h" | |
46 #include "ipa-type-escape.h" | |
47 #include "vec.h" | |
48 #include "bitmap.h" | |
49 #include "vecprim.h" | |
50 #include "pointer-set.h" | |
51 #include "alloc-pool.h" | |
52 | |
53 /* Broad overview of how aliasing works: | |
54 | |
55 First we compute points-to sets, which is done in | |
56 tree-ssa-structalias.c | |
57 | |
58 During points-to set constraint finding, a bunch of little bits of | |
59 information is collected. | |
60 This is not done because it is necessary for points-to, but because | |
61 points-to has to walk every statement anyway. The function performing | |
62 this collecting is update_alias_info. | |
63 | |
64 Bits update_alias_info collects include: | |
65 1. Directly escaping variables and variables whose value escapes | |
66 (using is_escape_site). This is the set of variables and values that | |
67 escape prior to transitive closure of the clobbers. | |
68 2. The set of variables dereferenced on the LHS (into | |
69 dereferenced_ptr_stores) | |
70 3. The set of variables dereferenced on the RHS (into | |
71 dereferenced_ptr_loads) | |
72 4. The set of all pointers we saw. | |
73 5. The number of loads and stores for each variable | |
74 6. The number of statements touching memory | |
75 7. The set of address taken variables. | |
76 | |
77 | |
78 #1 is computed by a combination of is_escape_site, and counting the | |
79 number of uses/deref operators. This function properly accounts for | |
80 situations like &ptr->field, which is *not* a dereference. | |
81 | |
82 After points-to sets are computed, the sets themselves still | |
83 contain points-to specific variables, such as a variable that says | |
84 the pointer points to anything, a variable that says the pointer | |
85 points to readonly memory, etc. | |
86 | |
87 These are eliminated in a later phase, as we will see. | |
88 | |
89 The rest of the phases are located in tree-ssa-alias.c | |
90 | |
91 The next phase after points-to set computation is called | |
92 "setup_pointers_and_addressables" | |
93 | |
94 This pass does 3 main things: | |
95 | |
96 1. All variables that can have TREE_ADDRESSABLE removed safely (IE | |
97 non-globals whose address is not taken), have TREE_ADDRESSABLE | |
98 removed. | |
99 2. All variables that may be aliased (which is the set of addressable | |
100 variables and globals) at all, are marked for renaming, and have | |
101 symbol memory tags created for them. | |
102 3. All variables which are stored into have their SMT's added to | |
103 written vars. | |
104 | |
105 | |
106 After this function is run, all variables that will ever have an | |
107 SMT, have one, though its aliases are not filled in. | |
108 | |
109 The next phase is to compute flow-insensitive aliasing, which in | |
110 our case, is a misnomer. it is really computing aliasing that | |
111 requires no transitive closure to be correct. In particular, it | |
112 uses stack vs non-stack, TBAA, etc, to determine whether two | |
113 symbols could *ever* alias . This phase works by going through all | |
114 the pointers we collected during update_alias_info, and for every | |
115 addressable variable in the program, seeing if they alias. If so, | |
116 the addressable variable is added to the symbol memory tag for the | |
117 pointer. | |
118 | |
119 As part of this, we handle symbol memory tags that conflict but | |
120 have no aliases in common, by forcing them to have a symbol in | |
121 common (through unioning alias sets or adding one as an alias of | |
122 the other), or by adding one as an alias of another. The case of | |
123 conflicts with no aliases in common occurs mainly due to aliasing | |
124 we cannot see. In particular, it generally means we have a load | |
125 through a pointer whose value came from outside the function. | |
126 Without an addressable symbol to point to, they would get the wrong | |
127 answer. | |
128 | |
129 After flow insensitive aliasing is computed, we compute name tags | |
130 (called compute_flow_sensitive_info). We walk each pointer we | |
131 collected and see if it has a usable points-to set. If so, we | |
132 generate a name tag using that pointer, and make an alias bitmap for | |
133 it. Name tags are shared between all things with the same alias | |
134 bitmap. The alias bitmap will be translated from what points-to | |
135 computed. In particular, the "anything" variable in points-to will be | |
136 transformed into a pruned set of SMT's and their aliases that | |
137 compute_flow_insensitive_aliasing computed. | |
138 Note that since 4.3, every pointer that points-to computed a solution for | |
139 will get a name tag (whereas before 4.3, only those whose set did | |
140 *not* include the anything variable would). At the point where name | |
141 tags are all assigned, symbol memory tags are dead, and could be | |
142 deleted, *except* on global variables. Global variables still use | |
143 symbol memory tags as of right now. | |
144 | |
145 After name tags are computed, the set of clobbered variables is | |
146 transitively closed. In particular, we compute the set of clobbered | |
147 variables based on the initial set of clobbers, plus the aliases of | |
148 pointers which either escape, or have their value escape. | |
149 | |
150 After this, maybe_create_global_var is run, which handles a corner | |
151 case where we have no call clobbered variables, but have pure and | |
152 non-pure functions. | |
153 | |
154 Staring at this function, I now remember it is a hack for the fact | |
155 that we do not mark all globals in the program as call clobbered for a | |
156 function unless they are actually used in that function. Instead, we | |
157 only mark the set that is actually clobbered. As a result, you can | |
158 end up with situations where you have no call clobbered vars set. | |
159 | |
160 After maybe_create_global_var, we set pointers with the REF_ALL flag | |
161 to have alias sets that include all clobbered | |
162 memory tags and variables. | |
163 | |
164 After this, memory partitioning is computed (by the function | |
165 compute_memory_partitions) and alias sets are reworked accordingly. | |
166 | |
167 Lastly, we delete partitions with no symbols, and clean up after | |
168 ourselves. */ | |
169 | |
170 | |
171 /* Alias information used by compute_may_aliases and its helpers. */ | |
172 struct alias_info | |
173 { | |
174 /* SSA names visited while collecting points-to information. If bit I | |
175 is set, it means that SSA variable with version I has already been | |
176 visited. */ | |
177 sbitmap ssa_names_visited; | |
178 | |
179 /* Array of SSA_NAME pointers processed by the points-to collector. */ | |
180 VEC(tree,heap) *processed_ptrs; | |
181 | |
182 /* ADDRESSABLE_VARS contains all the global variables and locals that | |
183 have had their address taken. */ | |
184 struct alias_map_d **addressable_vars; | |
185 size_t num_addressable_vars; | |
186 | |
187 /* POINTERS contains all the _DECL pointers with unique memory tags | |
188 that have been referenced in the program. */ | |
189 struct alias_map_d **pointers; | |
190 size_t num_pointers; | |
191 | |
192 /* Pointers that have been used in an indirect load/store operation. */ | |
193 struct pointer_set_t *dereferenced_ptrs; | |
194 }; | |
195 | |
196 | |
197 /* Structure to map a variable to its alias set. */ | |
198 struct alias_map_d | |
199 { | |
200 /* Variable and its alias set. */ | |
201 tree var; | |
202 alias_set_type set; | |
203 }; | |
204 | |
205 | |
206 /* Counters used to display statistics on alias analysis. */ | |
207 struct alias_stats_d | |
208 { | |
209 unsigned int alias_queries; | |
210 unsigned int alias_mayalias; | |
211 unsigned int alias_noalias; | |
212 unsigned int simple_queries; | |
213 unsigned int simple_resolved; | |
214 unsigned int tbaa_queries; | |
215 unsigned int tbaa_resolved; | |
216 unsigned int structnoaddress_queries; | |
217 unsigned int structnoaddress_resolved; | |
218 }; | |
219 | |
220 | |
221 /* Local variables. */ | |
222 static struct alias_stats_d alias_stats; | |
223 static bitmap_obstack alias_bitmap_obstack; | |
224 | |
225 /* Local functions. */ | |
226 static void compute_flow_insensitive_aliasing (struct alias_info *); | |
227 static void dump_alias_stats (FILE *); | |
228 static tree create_memory_tag (tree type, bool is_type_tag); | |
229 static tree get_smt_for (tree, struct alias_info *); | |
230 static tree get_nmt_for (tree); | |
231 static void add_may_alias (tree, tree); | |
232 static struct alias_info *init_alias_info (void); | |
233 static void delete_alias_info (struct alias_info *); | |
234 static void compute_flow_sensitive_aliasing (struct alias_info *); | |
235 static void setup_pointers_and_addressables (struct alias_info *); | |
236 static void update_alias_info (struct alias_info *); | |
237 static void create_global_var (void); | |
238 static void maybe_create_global_var (void); | |
239 static void set_pt_anything (tree); | |
240 | |
241 void debug_mp_info (VEC(mem_sym_stats_t,heap) *); | |
242 | |
243 static alloc_pool mem_sym_stats_pool; | |
244 | |
245 /* Return memory reference stats for symbol VAR. Create a new slot in | |
246 cfun->gimple_df->mem_sym_stats if needed. */ | |
247 | |
248 static struct mem_sym_stats_d * | |
249 get_mem_sym_stats_for (tree var) | |
250 { | |
251 void **slot; | |
252 struct mem_sym_stats_d *stats; | |
253 struct pointer_map_t *map = gimple_mem_ref_stats (cfun)->mem_sym_stats; | |
254 | |
255 gcc_assert (map); | |
256 | |
257 slot = pointer_map_insert (map, var); | |
258 if (*slot == NULL) | |
259 { | |
260 stats = (struct mem_sym_stats_d *) pool_alloc (mem_sym_stats_pool); | |
261 memset (stats, 0, sizeof (*stats)); | |
262 stats->var = var; | |
263 *slot = (void *) stats; | |
264 } | |
265 else | |
266 stats = (struct mem_sym_stats_d *) *slot; | |
267 | |
268 return stats; | |
269 } | |
270 | |
271 | |
272 /* Return memory reference statistics for variable VAR in function FN. | |
273 This is computed by alias analysis, but it is not kept | |
274 incrementally up-to-date. So, these stats are only accurate if | |
275 pass_may_alias has been run recently. If no alias information | |
276 exists, this function returns NULL. */ | |
277 | |
278 static mem_sym_stats_t | |
279 mem_sym_stats (struct function *fn, tree var) | |
280 { | |
281 void **slot; | |
282 struct pointer_map_t *stats_map = gimple_mem_ref_stats (fn)->mem_sym_stats; | |
283 | |
284 if (stats_map == NULL) | |
285 return NULL; | |
286 | |
287 slot = pointer_map_contains (stats_map, var); | |
288 if (slot == NULL) | |
289 return NULL; | |
290 | |
291 return (mem_sym_stats_t) *slot; | |
292 } | |
293 | |
294 | |
295 /* Set MPT to be the memory partition associated with symbol SYM. */ | |
296 | |
297 static inline void | |
298 set_memory_partition (tree sym, tree mpt) | |
299 { | |
300 #if defined ENABLE_CHECKING | |
301 if (mpt) | |
302 gcc_assert (TREE_CODE (mpt) == MEMORY_PARTITION_TAG | |
303 && !is_gimple_reg (sym)); | |
304 #endif | |
305 | |
306 var_ann (sym)->mpt = mpt; | |
307 if (mpt) | |
308 { | |
309 if (MPT_SYMBOLS (mpt) == NULL) | |
310 MPT_SYMBOLS (mpt) = BITMAP_ALLOC (&alias_bitmap_obstack); | |
311 | |
312 bitmap_set_bit (MPT_SYMBOLS (mpt), DECL_UID (sym)); | |
313 | |
314 /* MPT inherits the call-clobbering attributes from SYM. */ | |
315 if (is_call_clobbered (sym)) | |
316 { | |
317 MTAG_GLOBAL (mpt) = 1; | |
318 mark_call_clobbered (mpt, ESCAPE_IS_GLOBAL); | |
319 } | |
320 } | |
321 } | |
322 | |
323 | |
324 /* Mark variable VAR as being non-addressable. */ | |
325 | |
326 static void | |
327 mark_non_addressable (tree var) | |
328 { | |
329 tree mpt; | |
330 | |
331 if (!TREE_ADDRESSABLE (var)) | |
332 return; | |
333 | |
334 mpt = memory_partition (var); | |
335 | |
336 clear_call_clobbered (var); | |
337 TREE_ADDRESSABLE (var) = 0; | |
338 | |
339 if (mpt) | |
340 { | |
341 /* Note that it's possible for a symbol to have an associated | |
342 MPT and the MPT have a NULL empty set. During | |
343 init_alias_info, all MPTs get their sets cleared out, but the | |
344 symbols still point to the old MPTs that used to hold them. | |
345 This is done so that compute_memory_partitions can now which | |
346 symbols are losing or changing partitions and mark them for | |
347 renaming. */ | |
348 if (MPT_SYMBOLS (mpt)) | |
349 bitmap_clear_bit (MPT_SYMBOLS (mpt), DECL_UID (var)); | |
350 set_memory_partition (var, NULL_TREE); | |
351 } | |
352 } | |
353 | |
354 | |
355 /* qsort comparison function to sort type/name tags by DECL_UID. */ | |
356 | |
357 static int | |
358 sort_tags_by_id (const void *pa, const void *pb) | |
359 { | |
360 const_tree const a = *(const_tree const *)pa; | |
361 const_tree const b = *(const_tree const *)pb; | |
362 | |
363 return DECL_UID (a) - DECL_UID (b); | |
364 } | |
365 | |
366 /* Initialize WORKLIST to contain those memory tags that are marked call | |
367 clobbered. Initialized WORKLIST2 to contain the reasons these | |
368 memory tags escaped. */ | |
369 | |
370 static void | |
371 init_transitive_clobber_worklist (VEC (tree, heap) **worklist, | |
372 VEC (int, heap) **worklist2, | |
373 bitmap on_worklist) | |
374 { | |
375 referenced_var_iterator rvi; | |
376 tree curr; | |
377 | |
378 FOR_EACH_REFERENCED_VAR (curr, rvi) | |
379 { | |
380 if (MTAG_P (curr) && is_call_clobbered (curr)) | |
381 { | |
382 VEC_safe_push (tree, heap, *worklist, curr); | |
383 VEC_safe_push (int, heap, *worklist2, | |
384 var_ann (curr)->escape_mask); | |
385 bitmap_set_bit (on_worklist, DECL_UID (curr)); | |
386 } | |
387 } | |
388 } | |
389 | |
390 /* Add ALIAS to WORKLIST (and the reason for escaping REASON to WORKLIST2) if | |
391 ALIAS is not already marked call clobbered, and is a memory | |
392 tag. */ | |
393 | |
394 static void | |
395 add_to_worklist (tree alias, VEC (tree, heap) **worklist, | |
396 VEC (int, heap) **worklist2, int reason, | |
397 bitmap on_worklist) | |
398 { | |
399 if (MTAG_P (alias) && !is_call_clobbered (alias) | |
400 && !bitmap_bit_p (on_worklist, DECL_UID (alias))) | |
401 { | |
402 VEC_safe_push (tree, heap, *worklist, alias); | |
403 VEC_safe_push (int, heap, *worklist2, reason); | |
404 bitmap_set_bit (on_worklist, DECL_UID (alias)); | |
405 } | |
406 } | |
407 | |
408 /* Mark aliases of TAG as call clobbered, and place any tags on the | |
409 alias list that were not already call clobbered on WORKLIST. */ | |
410 | |
411 static void | |
412 mark_aliases_call_clobbered (tree tag, VEC (tree, heap) **worklist, | |
413 VEC (int, heap) **worklist2, bitmap on_worklist) | |
414 { | |
415 bitmap aliases; | |
416 bitmap_iterator bi; | |
417 unsigned int i; | |
418 tree entry; | |
419 var_ann_t ta = var_ann (tag); | |
420 | |
421 if (!MTAG_P (tag)) | |
422 return; | |
423 aliases = may_aliases (tag); | |
424 if (!aliases) | |
425 return; | |
426 | |
427 EXECUTE_IF_SET_IN_BITMAP (aliases, 0, i, bi) | |
428 { | |
429 entry = referenced_var (i); | |
430 /* If you clobber one part of a structure, you | |
431 clobber the entire thing. While this does not make | |
432 the world a particularly nice place, it is necessary | |
433 in order to allow C/C++ tricks that involve | |
434 pointer arithmetic to work. */ | |
435 if (!unmodifiable_var_p (entry)) | |
436 { | |
437 add_to_worklist (entry, worklist, worklist2, ta->escape_mask, | |
438 on_worklist); | |
439 mark_call_clobbered (entry, ta->escape_mask); | |
440 } | |
441 } | |
442 } | |
443 | |
444 /* Tags containing global vars need to be marked as global. | |
445 Tags containing call clobbered vars need to be marked as call | |
446 clobbered. */ | |
447 | |
448 static void | |
449 compute_tag_properties (void) | |
450 { | |
451 referenced_var_iterator rvi; | |
452 tree tag; | |
453 bool changed = true; | |
454 VEC (tree, heap) *taglist = NULL; | |
455 | |
456 FOR_EACH_REFERENCED_VAR (tag, rvi) | |
457 { | |
458 if (!MTAG_P (tag)) | |
459 continue; | |
460 VEC_safe_push (tree, heap, taglist, tag); | |
461 } | |
462 | |
463 /* We sort the taglist by DECL_UID, for two reasons. | |
464 1. To get a sequential ordering to make the bitmap accesses | |
465 faster. | |
466 2. Because of the way we compute aliases, it's more likely that | |
467 an earlier tag is included in a later tag, and this will reduce | |
468 the number of iterations. | |
469 | |
470 If we had a real tag graph, we would just topo-order it and be | |
471 done with it. */ | |
472 qsort (VEC_address (tree, taglist), | |
473 VEC_length (tree, taglist), | |
474 sizeof (tree), | |
475 sort_tags_by_id); | |
476 | |
477 /* Go through each tag not marked as global, and if it aliases | |
478 global vars, mark it global. | |
479 | |
480 If the tag contains call clobbered vars, mark it call | |
481 clobbered. | |
482 | |
483 This loop iterates because tags may appear in the may-aliases | |
484 list of other tags when we group. */ | |
485 | |
486 while (changed) | |
487 { | |
488 unsigned int k; | |
489 | |
490 changed = false; | |
491 for (k = 0; VEC_iterate (tree, taglist, k, tag); k++) | |
492 { | |
493 bitmap ma; | |
494 bitmap_iterator bi; | |
495 unsigned int i; | |
496 tree entry; | |
497 bool tagcc = is_call_clobbered (tag); | |
498 bool tagglobal = MTAG_GLOBAL (tag); | |
499 | |
500 if (tagcc && tagglobal) | |
501 continue; | |
502 | |
503 ma = may_aliases (tag); | |
504 if (!ma) | |
505 continue; | |
506 | |
507 EXECUTE_IF_SET_IN_BITMAP (ma, 0, i, bi) | |
508 { | |
509 entry = referenced_var (i); | |
510 /* Call clobbered entries cause the tag to be marked | |
511 call clobbered. */ | |
512 if (!tagcc && is_call_clobbered (entry)) | |
513 { | |
514 mark_call_clobbered (tag, var_ann (entry)->escape_mask); | |
515 tagcc = true; | |
516 changed = true; | |
517 } | |
518 | |
519 /* Global vars cause the tag to be marked global. */ | |
520 if (!tagglobal && is_global_var (entry)) | |
521 { | |
522 MTAG_GLOBAL (tag) = true; | |
523 changed = true; | |
524 tagglobal = true; | |
525 } | |
526 | |
527 /* Early exit once both global and cc are set, since the | |
528 loop can't do any more than that. */ | |
529 if (tagcc && tagglobal) | |
530 break; | |
531 } | |
532 } | |
533 } | |
534 VEC_free (tree, heap, taglist); | |
535 } | |
536 | |
537 /* Set up the initial variable clobbers, call-uses and globalness. | |
538 When this function completes, only tags whose aliases need to be | |
539 clobbered will be set clobbered. Tags clobbered because they | |
540 contain call clobbered vars are handled in compute_tag_properties. */ | |
541 | |
542 static void | |
543 set_initial_properties (struct alias_info *ai) | |
544 { | |
545 unsigned int i; | |
546 referenced_var_iterator rvi; | |
547 tree var; | |
548 tree ptr; | |
549 bool any_pt_anything = false; | |
550 enum escape_type pt_anything_mask = 0; | |
551 | |
552 FOR_EACH_REFERENCED_VAR (var, rvi) | |
553 { | |
554 if (is_global_var (var)) | |
555 { | |
556 if (!unmodifiable_var_p (var)) | |
557 mark_call_clobbered (var, ESCAPE_IS_GLOBAL); | |
558 } | |
559 else if (TREE_CODE (var) == PARM_DECL | |
560 && gimple_default_def (cfun, var) | |
561 && POINTER_TYPE_P (TREE_TYPE (var))) | |
562 { | |
563 tree def = gimple_default_def (cfun, var); | |
564 get_ptr_info (def)->value_escapes_p = 1; | |
565 get_ptr_info (def)->escape_mask |= ESCAPE_IS_PARM; | |
566 } | |
567 } | |
568 | |
569 if (!clobber_what_escaped ()) | |
570 { | |
571 any_pt_anything = true; | |
572 pt_anything_mask |= ESCAPE_TO_CALL; | |
573 } | |
574 | |
575 compute_call_used_vars (); | |
576 | |
577 for (i = 0; VEC_iterate (tree, ai->processed_ptrs, i, ptr); i++) | |
578 { | |
579 struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr); | |
580 tree tag = symbol_mem_tag (SSA_NAME_VAR (ptr)); | |
581 | |
582 /* A pointer that only escapes via a function return does not | |
583 add to the call clobber or call used solution. | |
584 To exclude ESCAPE_TO_PURE_CONST we would need to track | |
585 call used variables separately or compute those properly | |
586 in the operand scanner. */ | |
587 if (pi->value_escapes_p | |
588 && pi->escape_mask & ~ESCAPE_TO_RETURN) | |
589 { | |
590 /* If PTR escapes then its associated memory tags and | |
591 pointed-to variables are call-clobbered. */ | |
592 if (pi->name_mem_tag) | |
593 mark_call_clobbered (pi->name_mem_tag, pi->escape_mask); | |
594 | |
595 if (tag) | |
596 mark_call_clobbered (tag, pi->escape_mask); | |
597 } | |
598 | |
599 /* If the name tag is call clobbered, so is the symbol tag | |
600 associated with the base VAR_DECL. */ | |
601 if (pi->name_mem_tag | |
602 && tag | |
603 && is_call_clobbered (pi->name_mem_tag)) | |
604 mark_call_clobbered (tag, pi->escape_mask); | |
605 | |
606 /* Name tags and symbol tags that we don't know where they point | |
607 to, might point to global memory, and thus, are clobbered. | |
608 | |
609 FIXME: This is not quite right. They should only be | |
610 clobbered if value_escapes_p is true, regardless of whether | |
611 they point to global memory or not. | |
612 So removing this code and fixing all the bugs would be nice. | |
613 It is the cause of a bunch of clobbering. */ | |
614 if ((pi->pt_global_mem || pi->pt_anything) | |
615 && pi->memory_tag_needed && pi->name_mem_tag) | |
616 { | |
617 mark_call_clobbered (pi->name_mem_tag, ESCAPE_IS_GLOBAL); | |
618 MTAG_GLOBAL (pi->name_mem_tag) = true; | |
619 } | |
620 | |
621 if ((pi->pt_global_mem || pi->pt_anything) | |
622 && pi->memory_tag_needed | |
623 && tag) | |
624 { | |
625 mark_call_clobbered (tag, ESCAPE_IS_GLOBAL); | |
626 MTAG_GLOBAL (tag) = true; | |
627 } | |
628 } | |
629 | |
630 /* If a pt_anything pointer escaped we need to mark all addressable | |
631 variables call clobbered. */ | |
632 if (any_pt_anything) | |
633 { | |
634 bitmap_iterator bi; | |
635 unsigned int j; | |
636 | |
637 EXECUTE_IF_SET_IN_BITMAP (gimple_addressable_vars (cfun), 0, j, bi) | |
638 { | |
639 tree var = referenced_var (j); | |
640 if (!unmodifiable_var_p (var)) | |
641 mark_call_clobbered (var, pt_anything_mask); | |
642 } | |
643 } | |
644 } | |
645 | |
646 /* Compute which variables need to be marked call clobbered because | |
647 their tag is call clobbered, and which tags need to be marked | |
648 global because they contain global variables. */ | |
649 | |
650 static void | |
651 compute_call_clobbered (struct alias_info *ai) | |
652 { | |
653 VEC (tree, heap) *worklist = NULL; | |
654 VEC (int,heap) *worklist2 = NULL; | |
655 bitmap on_worklist; | |
656 | |
657 timevar_push (TV_CALL_CLOBBER); | |
658 on_worklist = BITMAP_ALLOC (NULL); | |
659 | |
660 set_initial_properties (ai); | |
661 init_transitive_clobber_worklist (&worklist, &worklist2, on_worklist); | |
662 while (VEC_length (tree, worklist) != 0) | |
663 { | |
664 tree curr = VEC_pop (tree, worklist); | |
665 int reason = VEC_pop (int, worklist2); | |
666 | |
667 bitmap_clear_bit (on_worklist, DECL_UID (curr)); | |
668 mark_call_clobbered (curr, reason); | |
669 mark_aliases_call_clobbered (curr, &worklist, &worklist2, on_worklist); | |
670 } | |
671 VEC_free (tree, heap, worklist); | |
672 VEC_free (int, heap, worklist2); | |
673 BITMAP_FREE (on_worklist); | |
674 compute_tag_properties (); | |
675 timevar_pop (TV_CALL_CLOBBER); | |
676 } | |
677 | |
678 | |
679 /* Dump memory partition information to FILE. */ | |
680 | |
681 static void | |
682 dump_memory_partitions (FILE *file) | |
683 { | |
684 unsigned i, npart; | |
685 unsigned long nsyms; | |
686 tree mpt; | |
687 | |
688 fprintf (file, "\nMemory partitions\n\n"); | |
689 for (i = 0, npart = 0, nsyms = 0; | |
690 VEC_iterate (tree, gimple_ssa_operands (cfun)->mpt_table, i, mpt); | |
691 i++) | |
692 { | |
693 if (mpt) | |
694 { | |
695 bitmap syms = MPT_SYMBOLS (mpt); | |
696 unsigned long n = (syms) ? bitmap_count_bits (syms) : 0; | |
697 | |
698 fprintf (file, "#%u: ", i); | |
699 print_generic_expr (file, mpt, 0); | |
700 fprintf (file, ": %lu elements: ", n); | |
701 dump_decl_set (file, syms); | |
702 npart++; | |
703 nsyms += n; | |
704 } | |
705 } | |
706 | |
707 fprintf (file, "\n%u memory partitions holding %lu symbols\n", npart, nsyms); | |
708 } | |
709 | |
710 | |
711 /* Dump memory partition information to stderr. */ | |
712 | |
713 void | |
714 debug_memory_partitions (void) | |
715 { | |
716 dump_memory_partitions (stderr); | |
717 } | |
718 | |
719 | |
720 /* Return true if memory partitioning is required given the memory | |
721 reference estimates in STATS. */ | |
722 | |
723 static inline bool | |
724 need_to_partition_p (struct mem_ref_stats_d *stats) | |
725 { | |
726 long num_vops = stats->num_vuses + stats->num_vdefs; | |
727 long avg_vops = CEIL (num_vops, stats->num_mem_stmts); | |
728 return (num_vops > (long) MAX_ALIASED_VOPS | |
729 && avg_vops > (long) AVG_ALIASED_VOPS); | |
730 } | |
731 | |
732 | |
733 /* Count the actual number of virtual operators in CFUN. Note that | |
734 this is only meaningful after virtual operands have been populated, | |
735 so it should be invoked at the end of compute_may_aliases. | |
736 | |
737 The number of virtual operators are stored in *NUM_VDEFS_P and | |
738 *NUM_VUSES_P, the number of partitioned symbols in | |
739 *NUM_PARTITIONED_P and the number of unpartitioned symbols in | |
740 *NUM_UNPARTITIONED_P. | |
741 | |
742 If any of these pointers is NULL the corresponding count is not | |
743 computed. */ | |
744 | |
745 static void | |
746 count_mem_refs (long *num_vuses_p, long *num_vdefs_p, | |
747 long *num_partitioned_p, long *num_unpartitioned_p) | |
748 { | |
749 gimple_stmt_iterator gsi; | |
750 basic_block bb; | |
751 long num_vdefs, num_vuses, num_partitioned, num_unpartitioned; | |
752 referenced_var_iterator rvi; | |
753 tree sym; | |
754 | |
755 num_vuses = num_vdefs = num_partitioned = num_unpartitioned = 0; | |
756 | |
757 if (num_vuses_p || num_vdefs_p) | |
758 FOR_EACH_BB (bb) | |
759 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) | |
760 { | |
761 gimple stmt = gsi_stmt (gsi); | |
762 if (gimple_references_memory_p (stmt)) | |
763 { | |
764 num_vuses += NUM_SSA_OPERANDS (stmt, SSA_OP_VUSE); | |
765 num_vdefs += NUM_SSA_OPERANDS (stmt, SSA_OP_VDEF); | |
766 } | |
767 } | |
768 | |
769 if (num_partitioned_p || num_unpartitioned_p) | |
770 FOR_EACH_REFERENCED_VAR (sym, rvi) | |
771 { | |
772 if (is_gimple_reg (sym)) | |
773 continue; | |
774 | |
775 if (memory_partition (sym)) | |
776 num_partitioned++; | |
777 else | |
778 num_unpartitioned++; | |
779 } | |
780 | |
781 if (num_vdefs_p) | |
782 *num_vdefs_p = num_vdefs; | |
783 | |
784 if (num_vuses_p) | |
785 *num_vuses_p = num_vuses; | |
786 | |
787 if (num_partitioned_p) | |
788 *num_partitioned_p = num_partitioned; | |
789 | |
790 if (num_unpartitioned_p) | |
791 *num_unpartitioned_p = num_unpartitioned; | |
792 } | |
793 | |
794 | |
795 /* The list is sorted by increasing partitioning score (PSCORE). | |
796 This score is computed such that symbols with high scores are | |
797 those that are least likely to be partitioned. Given a symbol | |
798 MP->VAR, PSCORE(S) is the result of the following weighted sum | |
799 | |
800 PSCORE(S) = FW * 64 + FR * 32 | |
801 + DW * 16 + DR * 8 | |
802 + IW * 4 + IR * 2 | |
803 + NO_ALIAS | |
804 | |
805 where | |
806 | |
807 FW Execution frequency of writes to S | |
808 FR Execution frequency of reads from S | |
809 DW Number of direct writes to S | |
810 DR Number of direct reads from S | |
811 IW Number of indirect writes to S | |
812 IR Number of indirect reads from S | |
813 NO_ALIAS State of the NO_ALIAS* flags | |
814 | |
815 The basic idea here is that symbols that are frequently | |
816 written-to in hot paths of the code are the last to be considered | |
817 for partitioning. */ | |
818 | |
819 static inline long | |
820 mem_sym_score (mem_sym_stats_t mp) | |
821 { | |
822 return mp->frequency_writes * 64 + mp->frequency_reads * 32 | |
823 + mp->num_direct_writes * 16 + mp->num_direct_reads * 8 | |
824 + mp->num_indirect_writes * 4 + mp->num_indirect_reads * 2 | |
825 + var_ann (mp->var)->noalias_state; | |
826 } | |
827 | |
828 | |
829 /* Dump memory reference stats for function CFUN to FILE. */ | |
830 | |
831 void | |
832 dump_mem_ref_stats (FILE *file) | |
833 { | |
834 long actual_num_vuses, actual_num_vdefs; | |
835 long num_partitioned, num_unpartitioned; | |
836 struct mem_ref_stats_d *stats; | |
837 | |
838 stats = gimple_mem_ref_stats (cfun); | |
839 | |
840 count_mem_refs (&actual_num_vuses, &actual_num_vdefs, &num_partitioned, | |
841 &num_unpartitioned); | |
842 | |
843 fprintf (file, "\nMemory reference statistics for %s\n\n", | |
844 lang_hooks.decl_printable_name (current_function_decl, 2)); | |
845 | |
846 fprintf (file, "Number of memory statements: %ld\n", | |
847 stats->num_mem_stmts); | |
848 fprintf (file, "Number of call sites: %ld\n", | |
849 stats->num_call_sites); | |
850 fprintf (file, "Number of pure/const call sites: %ld\n", | |
851 stats->num_pure_const_call_sites); | |
852 fprintf (file, "Number of asm sites: %ld\n", | |
853 stats->num_asm_sites); | |
854 fprintf (file, "Estimated number of loads: %ld (%ld/stmt)\n", | |
855 stats->num_vuses, | |
856 (stats->num_mem_stmts) | |
857 ? CEIL (stats->num_vuses, stats->num_mem_stmts) | |
858 : 0); | |
859 fprintf (file, "Actual number of loads: %ld (%ld/stmt)\n", | |
860 actual_num_vuses, | |
861 (stats->num_mem_stmts) | |
862 ? CEIL (actual_num_vuses, stats->num_mem_stmts) | |
863 : 0); | |
864 | |
865 if (actual_num_vuses > stats->num_vuses + (stats->num_vuses / 25)) | |
866 fprintf (file, "\t(warning: estimation is lower by more than 25%%)\n"); | |
867 | |
868 fprintf (file, "Estimated number of stores: %ld (%ld/stmt)\n", | |
869 stats->num_vdefs, | |
870 (stats->num_mem_stmts) | |
871 ? CEIL (stats->num_vdefs, stats->num_mem_stmts) | |
872 : 0); | |
873 fprintf (file, "Actual number of stores: %ld (%ld/stmt)\n", | |
874 actual_num_vdefs, | |
875 (stats->num_mem_stmts) | |
876 ? CEIL (actual_num_vdefs, stats->num_mem_stmts) | |
877 : 0); | |
878 | |
879 if (actual_num_vdefs > stats->num_vdefs + (stats->num_vdefs / 25)) | |
880 fprintf (file, "\t(warning: estimation is lower by more than 25%%)\n"); | |
881 | |
882 fprintf (file, "Partitioning thresholds: MAX = %d AVG = %d " | |
883 "(%sNEED TO PARTITION)\n", MAX_ALIASED_VOPS, AVG_ALIASED_VOPS, | |
884 stats->num_mem_stmts && need_to_partition_p (stats) ? "" : "NO "); | |
885 fprintf (file, "Number of partitioned symbols: %ld\n", num_partitioned); | |
886 fprintf (file, "Number of unpartitioned symbols: %ld\n", num_unpartitioned); | |
887 } | |
888 | |
889 | |
890 /* Dump memory reference stats for function FN to stderr. */ | |
891 | |
892 void | |
893 debug_mem_ref_stats (void) | |
894 { | |
895 dump_mem_ref_stats (stderr); | |
896 } | |
897 | |
898 | |
899 /* Dump memory reference stats for variable VAR to FILE. */ | |
900 | |
901 static void | |
902 dump_mem_sym_stats (FILE *file, tree var) | |
903 { | |
904 mem_sym_stats_t stats = mem_sym_stats (cfun, var); | |
905 | |
906 if (stats == NULL) | |
907 return; | |
908 | |
909 fprintf (file, "read frequency: %6ld, write frequency: %6ld, " | |
910 "direct reads: %3ld, direct writes: %3ld, " | |
911 "indirect reads: %4ld, indirect writes: %4ld, symbol: ", | |
912 stats->frequency_reads, stats->frequency_writes, | |
913 stats->num_direct_reads, stats->num_direct_writes, | |
914 stats->num_indirect_reads, stats->num_indirect_writes); | |
915 print_generic_expr (file, stats->var, 0); | |
916 fprintf (file, ", tags: "); | |
917 dump_decl_set (file, stats->parent_tags); | |
918 } | |
919 | |
920 | |
921 /* Dump memory reference stats for variable VAR to stderr. */ | |
922 | |
923 void | |
924 debug_mem_sym_stats (tree var) | |
925 { | |
926 dump_mem_sym_stats (stderr, var); | |
927 } | |
928 | |
929 /* Dump memory reference stats for variable VAR to FILE. For use | |
930 of tree-dfa.c:dump_variable. */ | |
931 | |
932 void | |
933 dump_mem_sym_stats_for_var (FILE *file, tree var) | |
934 { | |
935 mem_sym_stats_t stats = mem_sym_stats (cfun, var); | |
936 | |
937 if (stats == NULL) | |
938 return; | |
939 | |
940 fprintf (file, ", score: %ld", mem_sym_score (stats)); | |
941 fprintf (file, ", direct reads: %ld", stats->num_direct_reads); | |
942 fprintf (file, ", direct writes: %ld", stats->num_direct_writes); | |
943 fprintf (file, ", indirect reads: %ld", stats->num_indirect_reads); | |
944 fprintf (file, ", indirect writes: %ld", stats->num_indirect_writes); | |
945 } | |
946 | |
947 /* Dump memory reference stats for all memory symbols to FILE. */ | |
948 | |
949 static void | |
950 dump_all_mem_sym_stats (FILE *file) | |
951 { | |
952 referenced_var_iterator rvi; | |
953 tree sym; | |
954 | |
955 FOR_EACH_REFERENCED_VAR (sym, rvi) | |
956 { | |
957 if (is_gimple_reg (sym)) | |
958 continue; | |
959 | |
960 dump_mem_sym_stats (file, sym); | |
961 } | |
962 } | |
963 | |
964 | |
965 /* Dump memory reference stats for all memory symbols to stderr. */ | |
966 | |
967 void | |
968 debug_all_mem_sym_stats (void) | |
969 { | |
970 dump_all_mem_sym_stats (stderr); | |
971 } | |
972 | |
973 | |
974 /* Dump the MP_INFO array to FILE. */ | |
975 | |
976 static void | |
977 dump_mp_info (FILE *file, VEC(mem_sym_stats_t,heap) *mp_info) | |
978 { | |
979 unsigned i; | |
980 mem_sym_stats_t mp_p; | |
981 | |
982 for (i = 0; VEC_iterate (mem_sym_stats_t, mp_info, i, mp_p); i++) | |
983 if (!mp_p->partitioned_p) | |
984 dump_mem_sym_stats (file, mp_p->var); | |
985 } | |
986 | |
987 | |
988 /* Dump the MP_INFO array to stderr. */ | |
989 | |
990 void | |
991 debug_mp_info (VEC(mem_sym_stats_t,heap) *mp_info) | |
992 { | |
993 dump_mp_info (stderr, mp_info); | |
994 } | |
995 | |
996 | |
997 /* Update memory reference stats for symbol VAR in statement STMT. | |
998 NUM_DIRECT_READS and NUM_DIRECT_WRITES specify the number of times | |
999 that VAR is read/written in STMT (indirect reads/writes are not | |
1000 recorded by this function, see compute_memory_partitions). */ | |
1001 | |
1002 void | |
1003 update_mem_sym_stats_from_stmt (tree var, gimple stmt, long num_direct_reads, | |
1004 long num_direct_writes) | |
1005 { | |
1006 mem_sym_stats_t stats; | |
1007 | |
1008 gcc_assert (num_direct_reads >= 0 && num_direct_writes >= 0); | |
1009 | |
1010 stats = get_mem_sym_stats_for (var); | |
1011 | |
1012 stats->num_direct_reads += num_direct_reads; | |
1013 stats->frequency_reads += ((long) gimple_bb (stmt)->frequency | |
1014 * num_direct_reads); | |
1015 | |
1016 stats->num_direct_writes += num_direct_writes; | |
1017 stats->frequency_writes += ((long) gimple_bb (stmt)->frequency | |
1018 * num_direct_writes); | |
1019 } | |
1020 | |
1021 | |
1022 /* Given two MP_INFO entries MP1 and MP2, return -1 if MP1->VAR should | |
1023 be partitioned before MP2->VAR, 0 if they are the same or 1 if | |
1024 MP1->VAR should be partitioned after MP2->VAR. */ | |
1025 | |
1026 static inline int | |
1027 compare_mp_info_entries (mem_sym_stats_t mp1, mem_sym_stats_t mp2) | |
1028 { | |
1029 long pscore1 = mem_sym_score (mp1); | |
1030 long pscore2 = mem_sym_score (mp2); | |
1031 | |
1032 if (pscore1 < pscore2) | |
1033 return -1; | |
1034 else if (pscore1 > pscore2) | |
1035 return 1; | |
1036 else | |
1037 return DECL_UID (mp1->var) - DECL_UID (mp2->var); | |
1038 } | |
1039 | |
1040 | |
1041 /* Comparison routine for qsort. The list is sorted by increasing | |
1042 partitioning score (PSCORE). This score is computed such that | |
1043 symbols with high scores are those that are least likely to be | |
1044 partitioned. */ | |
1045 | |
1046 static int | |
1047 mp_info_cmp (const void *p, const void *q) | |
1048 { | |
1049 mem_sym_stats_t e1 = *((const mem_sym_stats_t *) p); | |
1050 mem_sym_stats_t e2 = *((const mem_sym_stats_t *) q); | |
1051 return compare_mp_info_entries (e1, e2); | |
1052 } | |
1053 | |
1054 | |
1055 /* Sort the array of reference counts used to compute memory partitions. | |
1056 Elements are sorted in ascending order of execution frequency and | |
1057 descending order of virtual operators needed. */ | |
1058 | |
1059 static inline void | |
1060 sort_mp_info (VEC(mem_sym_stats_t,heap) *list) | |
1061 { | |
1062 unsigned num = VEC_length (mem_sym_stats_t, list); | |
1063 | |
1064 if (num < 2) | |
1065 return; | |
1066 | |
1067 if (num == 2) | |
1068 { | |
1069 if (compare_mp_info_entries (VEC_index (mem_sym_stats_t, list, 0), | |
1070 VEC_index (mem_sym_stats_t, list, 1)) > 0) | |
1071 { | |
1072 /* Swap elements if they are in the wrong order. */ | |
1073 mem_sym_stats_t tmp = VEC_index (mem_sym_stats_t, list, 0); | |
1074 VEC_replace (mem_sym_stats_t, list, 0, | |
1075 VEC_index (mem_sym_stats_t, list, 1)); | |
1076 VEC_replace (mem_sym_stats_t, list, 1, tmp); | |
1077 } | |
1078 | |
1079 return; | |
1080 } | |
1081 | |
1082 /* There are 3 or more elements, call qsort. */ | |
1083 qsort (VEC_address (mem_sym_stats_t, list), | |
1084 VEC_length (mem_sym_stats_t, list), | |
1085 sizeof (mem_sym_stats_t), | |
1086 mp_info_cmp); | |
1087 } | |
1088 | |
1089 | |
1090 /* Return the memory partition tag (MPT) associated with memory | |
1091 symbol SYM. */ | |
1092 | |
1093 static tree | |
1094 get_mpt_for (tree sym) | |
1095 { | |
1096 tree mpt; | |
1097 | |
1098 /* Don't create a new tag unnecessarily. */ | |
1099 mpt = memory_partition (sym); | |
1100 if (mpt == NULL_TREE) | |
1101 { | |
1102 mpt = create_tag_raw (MEMORY_PARTITION_TAG, TREE_TYPE (sym), "MPT"); | |
1103 TREE_ADDRESSABLE (mpt) = 0; | |
1104 add_referenced_var (mpt); | |
1105 VEC_safe_push (tree, heap, gimple_ssa_operands (cfun)->mpt_table, mpt); | |
1106 gcc_assert (MPT_SYMBOLS (mpt) == NULL); | |
1107 set_memory_partition (sym, mpt); | |
1108 } | |
1109 | |
1110 return mpt; | |
1111 } | |
1112 | |
1113 | |
1114 /* Add MP_P->VAR to a memory partition and return the partition. */ | |
1115 | |
1116 static tree | |
1117 find_partition_for (mem_sym_stats_t mp_p) | |
1118 { | |
1119 unsigned i; | |
1120 VEC(tree,heap) *mpt_table; | |
1121 tree mpt; | |
1122 | |
1123 mpt_table = gimple_ssa_operands (cfun)->mpt_table; | |
1124 mpt = NULL_TREE; | |
1125 | |
1126 /* Find an existing partition for MP_P->VAR. */ | |
1127 for (i = 0; VEC_iterate (tree, mpt_table, i, mpt); i++) | |
1128 { | |
1129 mem_sym_stats_t mpt_stats; | |
1130 | |
1131 /* If MPT does not have any symbols yet, use it. */ | |
1132 if (MPT_SYMBOLS (mpt) == NULL) | |
1133 break; | |
1134 | |
1135 /* Otherwise, see if MPT has common parent tags with MP_P->VAR, | |
1136 but avoid grouping clobbered variables with non-clobbered | |
1137 variables (otherwise, this tends to creates a single memory | |
1138 partition because other call-clobbered variables may have | |
1139 common parent tags with non-clobbered ones). */ | |
1140 mpt_stats = get_mem_sym_stats_for (mpt); | |
1141 if (mp_p->parent_tags | |
1142 && mpt_stats->parent_tags | |
1143 && is_call_clobbered (mpt) == is_call_clobbered (mp_p->var) | |
1144 && bitmap_intersect_p (mpt_stats->parent_tags, mp_p->parent_tags)) | |
1145 break; | |
1146 | |
1147 /* If no common parent tags are found, see if both MPT and | |
1148 MP_P->VAR are call-clobbered. */ | |
1149 if (is_call_clobbered (mpt) && is_call_clobbered (mp_p->var)) | |
1150 break; | |
1151 } | |
1152 | |
1153 if (mpt == NULL_TREE) | |
1154 mpt = get_mpt_for (mp_p->var); | |
1155 else | |
1156 set_memory_partition (mp_p->var, mpt); | |
1157 | |
1158 mp_p->partitioned_p = true; | |
1159 | |
1160 mark_sym_for_renaming (mp_p->var); | |
1161 mark_sym_for_renaming (mpt); | |
1162 | |
1163 return mpt; | |
1164 } | |
1165 | |
1166 | |
1167 /* Rewrite the alias set for TAG to use the newly created partitions. | |
1168 If TAG is NULL, rewrite the set of call-clobbered variables. | |
1169 NEW_ALIASES is a scratch bitmap to build the new set of aliases for | |
1170 TAG. */ | |
1171 | |
1172 static void | |
1173 rewrite_alias_set_for (tree tag, bitmap new_aliases) | |
1174 { | |
1175 bitmap_iterator bi; | |
1176 unsigned i; | |
1177 tree mpt, sym; | |
1178 | |
1179 EXECUTE_IF_SET_IN_BITMAP (MTAG_ALIASES (tag), 0, i, bi) | |
1180 { | |
1181 sym = referenced_var (i); | |
1182 mpt = memory_partition (sym); | |
1183 if (mpt) | |
1184 bitmap_set_bit (new_aliases, DECL_UID (mpt)); | |
1185 else | |
1186 bitmap_set_bit (new_aliases, DECL_UID (sym)); | |
1187 } | |
1188 | |
1189 /* Rebuild the may-alias array for TAG. */ | |
1190 bitmap_copy (MTAG_ALIASES (tag), new_aliases); | |
1191 } | |
1192 | |
1193 | |
1194 /* Determine how many virtual operands can be saved by partitioning | |
1195 MP_P->VAR into MPT. When a symbol S is thrown inside a partition | |
1196 P, every virtual operand that used to reference S will now | |
1197 reference P. Whether it reduces the number of virtual operands | |
1198 depends on: | |
1199 | |
1200 1- Direct references to S are never saved. Instead of the virtual | |
1201 operand to S, we will now have a virtual operand to P. | |
1202 | |
1203 2- Indirect references to S are reduced only for those memory tags | |
1204 holding S that already had other symbols partitioned into P. | |
1205 For instance, if a memory tag T has the alias set { a b S c }, | |
1206 the first time we partition S into P, the alias set will become | |
1207 { a b P c }, so no virtual operands will be saved. However, if | |
1208 we now partition symbol 'c' into P, then the alias set for T | |
1209 will become { a b P }, so we will be saving one virtual operand | |
1210 for every indirect reference to 'c'. | |
1211 | |
1212 3- Is S is call-clobbered, we save as many virtual operands as | |
1213 call/asm sites exist in the code, but only if other | |
1214 call-clobbered symbols have been grouped into P. The first | |
1215 call-clobbered symbol that we group does not produce any | |
1216 savings. | |
1217 | |
1218 MEM_REF_STATS points to CFUN's memory reference information. */ | |
1219 | |
1220 static void | |
1221 estimate_vop_reduction (struct mem_ref_stats_d *mem_ref_stats, | |
1222 mem_sym_stats_t mp_p, tree mpt) | |
1223 { | |
1224 unsigned i; | |
1225 bitmap_iterator bi; | |
1226 mem_sym_stats_t mpt_stats; | |
1227 | |
1228 /* We should only get symbols with indirect references here. */ | |
1229 gcc_assert (mp_p->num_indirect_reads > 0 || mp_p->num_indirect_writes > 0); | |
1230 | |
1231 /* Note that the only statistics we keep for MPT is the set of | |
1232 parent tags to know which memory tags have had alias members | |
1233 partitioned, and the indicator has_call_clobbered_vars. | |
1234 Reference counts are not important for MPT. */ | |
1235 mpt_stats = get_mem_sym_stats_for (mpt); | |
1236 | |
1237 /* Traverse all the parent tags for MP_P->VAR. For every tag T, if | |
1238 partition P is already grouping aliases of T, then reduce the | |
1239 number of virtual operands by the number of direct references | |
1240 to T. */ | |
1241 if (mp_p->parent_tags) | |
1242 { | |
1243 if (mpt_stats->parent_tags == NULL) | |
1244 mpt_stats->parent_tags = BITMAP_ALLOC (&alias_bitmap_obstack); | |
1245 | |
1246 EXECUTE_IF_SET_IN_BITMAP (mp_p->parent_tags, 0, i, bi) | |
1247 { | |
1248 if (bitmap_bit_p (mpt_stats->parent_tags, i)) | |
1249 { | |
1250 /* Partition MPT is already partitioning symbols in the | |
1251 alias set for TAG. This means that we are now saving | |
1252 1 virtual operand for every direct reference to TAG. */ | |
1253 tree tag = referenced_var (i); | |
1254 mem_sym_stats_t tag_stats = mem_sym_stats (cfun, tag); | |
1255 mem_ref_stats->num_vuses -= tag_stats->num_direct_reads; | |
1256 mem_ref_stats->num_vdefs -= tag_stats->num_direct_writes; | |
1257 } | |
1258 else | |
1259 { | |
1260 /* This is the first symbol in tag I's alias set that is | |
1261 being grouped under MPT. We will not save any | |
1262 virtual operands this time, but record that MPT is | |
1263 grouping a symbol from TAG's alias set so that the | |
1264 next time we get the savings. */ | |
1265 bitmap_set_bit (mpt_stats->parent_tags, i); | |
1266 } | |
1267 } | |
1268 } | |
1269 | |
1270 /* If MP_P->VAR is call-clobbered, and MPT is already grouping | |
1271 call-clobbered symbols, then we will save as many virtual | |
1272 operands as asm/call sites there are. */ | |
1273 if (is_call_clobbered (mp_p->var)) | |
1274 { | |
1275 if (mpt_stats->has_call_clobbered_vars) | |
1276 mem_ref_stats->num_vdefs -= mem_ref_stats->num_call_sites | |
1277 + mem_ref_stats->num_asm_sites; | |
1278 else | |
1279 mpt_stats->has_call_clobbered_vars = true; | |
1280 } | |
1281 } | |
1282 | |
1283 | |
1284 /* Helper for compute_memory_partitions. Transfer reference counts | |
1285 from pointers to their pointed-to sets. Counters for pointers were | |
1286 computed by update_alias_info. MEM_REF_STATS points to CFUN's | |
1287 memory reference information. */ | |
1288 | |
1289 static void | |
1290 update_reference_counts (struct mem_ref_stats_d *mem_ref_stats) | |
1291 { | |
1292 unsigned i; | |
1293 bitmap_iterator bi; | |
1294 mem_sym_stats_t sym_stats; | |
1295 | |
1296 for (i = 1; i < num_ssa_names; i++) | |
1297 { | |
1298 tree ptr; | |
1299 struct ptr_info_def *pi; | |
1300 | |
1301 ptr = ssa_name (i); | |
1302 if (ptr | |
1303 && POINTER_TYPE_P (TREE_TYPE (ptr)) | |
1304 && (pi = SSA_NAME_PTR_INFO (ptr)) != NULL | |
1305 && pi->memory_tag_needed) | |
1306 { | |
1307 unsigned j; | |
1308 bitmap_iterator bj; | |
1309 tree tag; | |
1310 mem_sym_stats_t ptr_stats, tag_stats; | |
1311 | |
1312 /* If PTR has flow-sensitive points-to information, use | |
1313 PTR's name tag, otherwise use the symbol tag associated | |
1314 with PTR's symbol. */ | |
1315 if (pi->name_mem_tag) | |
1316 tag = pi->name_mem_tag; | |
1317 else | |
1318 tag = symbol_mem_tag (SSA_NAME_VAR (ptr)); | |
1319 | |
1320 ptr_stats = get_mem_sym_stats_for (ptr); | |
1321 tag_stats = get_mem_sym_stats_for (tag); | |
1322 | |
1323 /* TAG has as many direct references as dereferences we | |
1324 found for its parent pointer. */ | |
1325 tag_stats->num_direct_reads += ptr_stats->num_direct_reads; | |
1326 tag_stats->num_direct_writes += ptr_stats->num_direct_writes; | |
1327 | |
1328 /* All the dereferences of pointer PTR are considered direct | |
1329 references to PTR's memory tag (TAG). In turn, | |
1330 references to TAG will become virtual operands for every | |
1331 symbol in TAG's alias set. So, for every symbol ALIAS in | |
1332 TAG's alias set, add as many indirect references to ALIAS | |
1333 as direct references there are for TAG. */ | |
1334 if (MTAG_ALIASES (tag)) | |
1335 EXECUTE_IF_SET_IN_BITMAP (MTAG_ALIASES (tag), 0, j, bj) | |
1336 { | |
1337 tree alias = referenced_var (j); | |
1338 sym_stats = get_mem_sym_stats_for (alias); | |
1339 | |
1340 /* All the direct references to TAG are indirect references | |
1341 to ALIAS. */ | |
1342 sym_stats->num_indirect_reads += ptr_stats->num_direct_reads; | |
1343 sym_stats->num_indirect_writes += ptr_stats->num_direct_writes; | |
1344 sym_stats->frequency_reads += ptr_stats->frequency_reads; | |
1345 sym_stats->frequency_writes += ptr_stats->frequency_writes; | |
1346 | |
1347 /* Indicate that TAG is one of ALIAS's parent tags. */ | |
1348 if (sym_stats->parent_tags == NULL) | |
1349 sym_stats->parent_tags = BITMAP_ALLOC (&alias_bitmap_obstack); | |
1350 bitmap_set_bit (sym_stats->parent_tags, DECL_UID (tag)); | |
1351 } | |
1352 } | |
1353 } | |
1354 | |
1355 /* Call-clobbered symbols are indirectly written at every | |
1356 call/asm site. */ | |
1357 EXECUTE_IF_SET_IN_BITMAP (gimple_call_clobbered_vars (cfun), 0, i, bi) | |
1358 { | |
1359 tree sym = referenced_var (i); | |
1360 sym_stats = get_mem_sym_stats_for (sym); | |
1361 sym_stats->num_indirect_writes += mem_ref_stats->num_call_sites | |
1362 + mem_ref_stats->num_asm_sites; | |
1363 } | |
1364 | |
1365 /* Addressable symbols are indirectly written at some ASM sites. | |
1366 Since only ASM sites that clobber memory actually affect | |
1367 addressable symbols, this is an over-estimation. */ | |
1368 EXECUTE_IF_SET_IN_BITMAP (gimple_addressable_vars (cfun), 0, i, bi) | |
1369 { | |
1370 tree sym = referenced_var (i); | |
1371 sym_stats = get_mem_sym_stats_for (sym); | |
1372 sym_stats->num_indirect_writes += mem_ref_stats->num_asm_sites; | |
1373 } | |
1374 } | |
1375 | |
1376 | |
1377 /* Helper for compute_memory_partitions. Add all memory symbols to | |
1378 *MP_INFO_P and compute the initial estimate for the total number of | |
1379 virtual operands needed. MEM_REF_STATS points to CFUN's memory | |
1380 reference information. On exit, *TAGS_P will contain the list of | |
1381 memory tags whose alias set need to be rewritten after | |
1382 partitioning. */ | |
1383 | |
1384 static void | |
1385 build_mp_info (struct mem_ref_stats_d *mem_ref_stats, | |
1386 VEC(mem_sym_stats_t,heap) **mp_info_p, | |
1387 VEC(tree,heap) **tags_p) | |
1388 { | |
1389 tree var; | |
1390 referenced_var_iterator rvi; | |
1391 | |
1392 FOR_EACH_REFERENCED_VAR (var, rvi) | |
1393 { | |
1394 mem_sym_stats_t sym_stats; | |
1395 tree old_mpt; | |
1396 | |
1397 /* We are only interested in memory symbols other than MPTs. */ | |
1398 if (is_gimple_reg (var) || TREE_CODE (var) == MEMORY_PARTITION_TAG) | |
1399 continue; | |
1400 | |
1401 /* Collect memory tags into the TAGS array so that we can | |
1402 rewrite their alias sets after partitioning. */ | |
1403 if (MTAG_P (var) && MTAG_ALIASES (var)) | |
1404 VEC_safe_push (tree, heap, *tags_p, var); | |
1405 | |
1406 /* Since we are going to re-compute partitions, any symbols that | |
1407 used to belong to a partition must be detached from it and | |
1408 marked for renaming. */ | |
1409 if ((old_mpt = memory_partition (var)) != NULL) | |
1410 { | |
1411 mark_sym_for_renaming (old_mpt); | |
1412 set_memory_partition (var, NULL_TREE); | |
1413 mark_sym_for_renaming (var); | |
1414 } | |
1415 | |
1416 sym_stats = get_mem_sym_stats_for (var); | |
1417 | |
1418 /* Add VAR's reference info to MP_INFO. Note that the only | |
1419 symbols that make sense to partition are those that have | |
1420 indirect references. If a symbol S is always directly | |
1421 referenced, partitioning it will not reduce the number of | |
1422 virtual operators. The only symbols that are profitable to | |
1423 partition are those that belong to alias sets and/or are | |
1424 call-clobbered. */ | |
1425 if (sym_stats->num_indirect_reads > 0 | |
1426 || sym_stats->num_indirect_writes > 0) | |
1427 VEC_safe_push (mem_sym_stats_t, heap, *mp_info_p, sym_stats); | |
1428 | |
1429 /* Update the number of estimated VOPS. Note that direct | |
1430 references to memory tags are always counted as indirect | |
1431 references to their alias set members, so if a memory tag has | |
1432 aliases, do not count its direct references to avoid double | |
1433 accounting. */ | |
1434 if (!MTAG_P (var) || !MTAG_ALIASES (var)) | |
1435 { | |
1436 mem_ref_stats->num_vuses += sym_stats->num_direct_reads; | |
1437 mem_ref_stats->num_vdefs += sym_stats->num_direct_writes; | |
1438 } | |
1439 | |
1440 mem_ref_stats->num_vuses += sym_stats->num_indirect_reads; | |
1441 mem_ref_stats->num_vdefs += sym_stats->num_indirect_writes; | |
1442 } | |
1443 } | |
1444 | |
1445 | |
1446 /* Compute memory partitions. A memory partition (MPT) is an | |
1447 arbitrary grouping of memory symbols, such that references to one | |
1448 member of the group is considered a reference to all the members of | |
1449 the group. | |
1450 | |
1451 As opposed to alias sets in memory tags, the grouping into | |
1452 partitions is completely arbitrary and only done to reduce the | |
1453 number of virtual operands. The only rule that needs to be | |
1454 observed when creating memory partitions is that given two memory | |
1455 partitions MPT.i and MPT.j, they must not contain symbols in | |
1456 common. | |
1457 | |
1458 Memory partitions are used when putting the program into Memory-SSA | |
1459 form. In particular, in Memory-SSA PHI nodes are not computed for | |
1460 individual memory symbols. They are computed for memory | |
1461 partitions. This reduces the amount of PHI nodes in the SSA graph | |
1462 at the expense of precision (i.e., it makes unrelated stores affect | |
1463 each other). | |
1464 | |
1465 However, it is possible to increase precision by changing this | |
1466 partitioning scheme. For instance, if the partitioning scheme is | |
1467 such that get_mpt_for is the identity function (that is, | |
1468 get_mpt_for (s) = s), this will result in ultimate precision at the | |
1469 expense of huge SSA webs. | |
1470 | |
1471 At the other extreme, a partitioning scheme that groups all the | |
1472 symbols in the same set results in minimal SSA webs and almost | |
1473 total loss of precision. | |
1474 | |
1475 There partitioning heuristic uses three parameters to decide the | |
1476 order in which symbols are processed. The list of symbols is | |
1477 sorted so that symbols that are more likely to be partitioned are | |
1478 near the top of the list: | |
1479 | |
1480 - Execution frequency. If a memory references is in a frequently | |
1481 executed code path, grouping it into a partition may block useful | |
1482 transformations and cause sub-optimal code generation. So, the | |
1483 partition heuristic tries to avoid grouping symbols with high | |
1484 execution frequency scores. Execution frequency is taken | |
1485 directly from the basic blocks where every reference is made (see | |
1486 update_mem_sym_stats_from_stmt), which in turn uses the | |
1487 profile guided machinery, so if the program is compiled with PGO | |
1488 enabled, more accurate partitioning decisions will be made. | |
1489 | |
1490 - Number of references. Symbols with few references in the code, | |
1491 are partitioned before symbols with many references. | |
1492 | |
1493 - NO_ALIAS attributes. Symbols with any of the NO_ALIAS* | |
1494 attributes are partitioned after symbols marked MAY_ALIAS. | |
1495 | |
1496 Once the list is sorted, the partitioning proceeds as follows: | |
1497 | |
1498 1- For every symbol S in MP_INFO, create a new memory partition MP, | |
1499 if necessary. To avoid memory partitions that contain symbols | |
1500 from non-conflicting alias sets, memory partitions are | |
1501 associated to the memory tag that holds S in its alias set. So, | |
1502 when looking for a memory partition for S, the memory partition | |
1503 associated with one of the memory tags holding S is chosen. If | |
1504 none exists, a new one is created. | |
1505 | |
1506 2- Add S to memory partition MP. | |
1507 | |
1508 3- Reduce by 1 the number of VOPS for every memory tag holding S. | |
1509 | |
1510 4- If the total number of VOPS is less than MAX_ALIASED_VOPS or the | |
1511 average number of VOPS per statement is less than | |
1512 AVG_ALIASED_VOPS, stop. Otherwise, go to the next symbol in the | |
1513 list. */ | |
1514 | |
1515 static void | |
1516 compute_memory_partitions (void) | |
1517 { | |
1518 tree tag; | |
1519 unsigned i; | |
1520 mem_sym_stats_t mp_p; | |
1521 VEC(mem_sym_stats_t,heap) *mp_info; | |
1522 bitmap new_aliases; | |
1523 VEC(tree,heap) *tags; | |
1524 struct mem_ref_stats_d *mem_ref_stats; | |
1525 int prev_max_aliased_vops; | |
1526 | |
1527 mem_ref_stats = gimple_mem_ref_stats (cfun); | |
1528 gcc_assert (mem_ref_stats->num_vuses == 0 && mem_ref_stats->num_vdefs == 0); | |
1529 | |
1530 if (mem_ref_stats->num_mem_stmts == 0) | |
1531 return; | |
1532 | |
1533 timevar_push (TV_MEMORY_PARTITIONING); | |
1534 | |
1535 mp_info = NULL; | |
1536 tags = NULL; | |
1537 prev_max_aliased_vops = MAX_ALIASED_VOPS; | |
1538 | |
1539 /* Since we clearly cannot lower the number of virtual operators | |
1540 below the total number of memory statements in the function, we | |
1541 may need to adjust MAX_ALIASED_VOPS beforehand. */ | |
1542 if (MAX_ALIASED_VOPS < mem_ref_stats->num_mem_stmts) | |
1543 MAX_ALIASED_VOPS = mem_ref_stats->num_mem_stmts; | |
1544 | |
1545 /* Update reference stats for all the pointed-to variables and | |
1546 memory tags. */ | |
1547 update_reference_counts (mem_ref_stats); | |
1548 | |
1549 /* Add all the memory symbols to MP_INFO. */ | |
1550 build_mp_info (mem_ref_stats, &mp_info, &tags); | |
1551 | |
1552 /* No partitions required if we are below the threshold. */ | |
1553 if (!need_to_partition_p (mem_ref_stats)) | |
1554 { | |
1555 if (dump_file) | |
1556 fprintf (dump_file, "\nMemory partitioning NOT NEEDED for %s\n", | |
1557 get_name (current_function_decl)); | |
1558 goto done; | |
1559 } | |
1560 | |
1561 /* Sort the MP_INFO array so that symbols that should be partitioned | |
1562 first are near the top of the list. */ | |
1563 sort_mp_info (mp_info); | |
1564 | |
1565 if (dump_file) | |
1566 { | |
1567 fprintf (dump_file, "\nMemory partitioning NEEDED for %s\n\n", | |
1568 get_name (current_function_decl)); | |
1569 fprintf (dump_file, "Memory symbol references before partitioning:\n"); | |
1570 dump_mp_info (dump_file, mp_info); | |
1571 } | |
1572 | |
1573 /* Create partitions for variables in MP_INFO until we have enough | |
1574 to lower the total number of VOPS below MAX_ALIASED_VOPS or if | |
1575 the average number of VOPS per statement is below | |
1576 AVG_ALIASED_VOPS. */ | |
1577 for (i = 0; VEC_iterate (mem_sym_stats_t, mp_info, i, mp_p); i++) | |
1578 { | |
1579 tree mpt; | |
1580 | |
1581 /* If we are below the threshold, stop. */ | |
1582 if (!need_to_partition_p (mem_ref_stats)) | |
1583 break; | |
1584 | |
1585 mpt = find_partition_for (mp_p); | |
1586 estimate_vop_reduction (mem_ref_stats, mp_p, mpt); | |
1587 } | |
1588 | |
1589 /* After partitions have been created, rewrite alias sets to use | |
1590 them instead of the original symbols. This way, if the alias set | |
1591 was computed as { a b c d e f }, and the subset { b e f } was | |
1592 grouped into partition MPT.3, then the new alias set for the tag | |
1593 will be { a c d MPT.3 }. | |
1594 | |
1595 Note that this is not strictly necessary. The operand scanner | |
1596 will always check if a symbol belongs to a partition when adding | |
1597 virtual operands. However, by reducing the size of the alias | |
1598 sets to be scanned, the work needed inside the operand scanner is | |
1599 significantly reduced. */ | |
1600 new_aliases = BITMAP_ALLOC (&alias_bitmap_obstack); | |
1601 | |
1602 for (i = 0; VEC_iterate (tree, tags, i, tag); i++) | |
1603 { | |
1604 rewrite_alias_set_for (tag, new_aliases); | |
1605 bitmap_clear (new_aliases); | |
1606 } | |
1607 | |
1608 BITMAP_FREE (new_aliases); | |
1609 | |
1610 if (dump_file) | |
1611 { | |
1612 fprintf (dump_file, "\nMemory symbol references after partitioning:\n"); | |
1613 dump_mp_info (dump_file, mp_info); | |
1614 } | |
1615 | |
1616 done: | |
1617 /* Free allocated memory. */ | |
1618 VEC_free (mem_sym_stats_t, heap, mp_info); | |
1619 VEC_free (tree, heap, tags); | |
1620 | |
1621 MAX_ALIASED_VOPS = prev_max_aliased_vops; | |
1622 | |
1623 timevar_pop (TV_MEMORY_PARTITIONING); | |
1624 } | |
1625 | |
1626 /* Compute may-alias information for every variable referenced in function | |
1627 FNDECL. | |
1628 | |
1629 Alias analysis proceeds in 3 main phases: | |
1630 | |
1631 1- Points-to and escape analysis. | |
1632 | |
1633 This phase walks the use-def chains in the SSA web looking for three | |
1634 things: | |
1635 | |
1636 * Assignments of the form P_i = &VAR | |
1637 * Assignments of the form P_i = malloc() | |
1638 * Pointers and ADDR_EXPR that escape the current function. | |
1639 | |
1640 The concept of 'escaping' is the same one used in the Java world. When | |
1641 a pointer or an ADDR_EXPR escapes, it means that it has been exposed | |
1642 outside of the current function. So, assignment to global variables, | |
1643 function arguments and returning a pointer are all escape sites, as are | |
1644 conversions between pointers and integers. | |
1645 | |
1646 This is where we are currently limited. Since not everything is renamed | |
1647 into SSA, we lose track of escape properties when a pointer is stashed | |
1648 inside a field in a structure, for instance. In those cases, we are | |
1649 assuming that the pointer does escape. | |
1650 | |
1651 We use escape analysis to determine whether a variable is | |
1652 call-clobbered. Simply put, if an ADDR_EXPR escapes, then the variable | |
1653 is call-clobbered. If a pointer P_i escapes, then all the variables | |
1654 pointed-to by P_i (and its memory tag) also escape. | |
1655 | |
1656 2- Compute flow-sensitive aliases | |
1657 | |
1658 We have two classes of memory tags. Memory tags associated with the | |
1659 pointed-to data type of the pointers in the program. These tags are | |
1660 called "symbol memory tag" (SMT). The other class are those associated | |
1661 with SSA_NAMEs, called "name memory tag" (NMT). The basic idea is that | |
1662 when adding operands for an INDIRECT_REF *P_i, we will first check | |
1663 whether P_i has a name tag, if it does we use it, because that will have | |
1664 more precise aliasing information. Otherwise, we use the standard symbol | |
1665 tag. | |
1666 | |
1667 In this phase, we go through all the pointers we found in points-to | |
1668 analysis and create alias sets for the name memory tags associated with | |
1669 each pointer P_i. If P_i escapes, we mark call-clobbered the variables | |
1670 it points to and its tag. | |
1671 | |
1672 | |
1673 3- Compute flow-insensitive aliases | |
1674 | |
1675 This pass will compare the alias set of every symbol memory tag and | |
1676 every addressable variable found in the program. Given a symbol | |
1677 memory tag SMT and an addressable variable V. If the alias sets of | |
1678 SMT and V conflict (as computed by may_alias_p), then V is marked | |
1679 as an alias tag and added to the alias set of SMT. | |
1680 | |
1681 For instance, consider the following function: | |
1682 | |
1683 foo (int i) | |
1684 { | |
1685 int *p, a, b; | |
1686 | |
1687 if (i > 10) | |
1688 p = &a; | |
1689 else | |
1690 p = &b; | |
1691 | |
1692 *p = 3; | |
1693 a = b + 2; | |
1694 return *p; | |
1695 } | |
1696 | |
1697 After aliasing analysis has finished, the symbol memory tag for pointer | |
1698 'p' will have two aliases, namely variables 'a' and 'b'. Every time | |
1699 pointer 'p' is dereferenced, we want to mark the operation as a | |
1700 potential reference to 'a' and 'b'. | |
1701 | |
1702 foo (int i) | |
1703 { | |
1704 int *p, a, b; | |
1705 | |
1706 if (i_2 > 10) | |
1707 p_4 = &a; | |
1708 else | |
1709 p_6 = &b; | |
1710 # p_1 = PHI <p_4(1), p_6(2)>; | |
1711 | |
1712 # a_7 = VDEF <a_3>; | |
1713 # b_8 = VDEF <b_5>; | |
1714 *p_1 = 3; | |
1715 | |
1716 # a_9 = VDEF <a_7> | |
1717 # VUSE <b_8> | |
1718 a_9 = b_8 + 2; | |
1719 | |
1720 # VUSE <a_9>; | |
1721 # VUSE <b_8>; | |
1722 return *p_1; | |
1723 } | |
1724 | |
1725 In certain cases, the list of may aliases for a pointer may grow too | |
1726 large. This may cause an explosion in the number of virtual operands | |
1727 inserted in the code. Resulting in increased memory consumption and | |
1728 compilation time. | |
1729 | |
1730 When the number of virtual operands needed to represent aliased | |
1731 loads and stores grows too large (configurable with option --param | |
1732 max-aliased-vops and --param avg-aliased-vops), alias sets are | |
1733 grouped to avoid severe compile-time slow downs and memory | |
1734 consumption. See compute_memory_partitions. */ | |
1735 | |
1736 unsigned int | |
1737 compute_may_aliases (void) | |
1738 { | |
1739 struct alias_info *ai; | |
1740 | |
1741 timevar_push (TV_TREE_MAY_ALIAS); | |
1742 | |
1743 memset (&alias_stats, 0, sizeof (alias_stats)); | |
1744 | |
1745 /* Initialize aliasing information. */ | |
1746 ai = init_alias_info (); | |
1747 | |
1748 /* For each pointer P_i, determine the sets of variables that P_i may | |
1749 point-to. For every addressable variable V, determine whether the | |
1750 address of V escapes the current function, making V call-clobbered | |
1751 (i.e., whether &V is stored in a global variable or if its passed as a | |
1752 function call argument). */ | |
1753 compute_points_to_sets (); | |
1754 | |
1755 /* Update various related attributes like escaped addresses, | |
1756 pointer dereferences for loads and stores. This is used | |
1757 when creating name tags and alias sets. */ | |
1758 update_alias_info (ai); | |
1759 | |
1760 /* Collect all pointers and addressable variables, compute alias sets, | |
1761 create memory tags for pointers and promote variables whose address is | |
1762 not needed anymore. */ | |
1763 setup_pointers_and_addressables (ai); | |
1764 | |
1765 /* Compute type-based flow-insensitive aliasing for all the type | |
1766 memory tags. */ | |
1767 compute_flow_insensitive_aliasing (ai); | |
1768 | |
1769 /* Compute flow-sensitive, points-to based aliasing for all the name | |
1770 memory tags. */ | |
1771 compute_flow_sensitive_aliasing (ai); | |
1772 | |
1773 /* Compute call clobbering information. */ | |
1774 compute_call_clobbered (ai); | |
1775 | |
1776 /* If the program makes no reference to global variables, but it | |
1777 contains a mixture of pure and non-pure functions, then we need | |
1778 to create use-def and def-def links between these functions to | |
1779 avoid invalid transformations on them. */ | |
1780 maybe_create_global_var (); | |
1781 | |
1782 /* Compute memory partitions for every memory variable. */ | |
1783 compute_memory_partitions (); | |
1784 | |
1785 /* Remove partitions with no symbols. Partitions may end up with an | |
1786 empty MPT_SYMBOLS set if a previous round of alias analysis | |
1787 needed to partition more symbols. Since we don't need those | |
1788 partitions anymore, remove them to free up the space. */ | |
1789 { | |
1790 tree mpt; | |
1791 unsigned i; | |
1792 VEC(tree,heap) *mpt_table; | |
1793 | |
1794 mpt_table = gimple_ssa_operands (cfun)->mpt_table; | |
1795 i = 0; | |
1796 while (i < VEC_length (tree, mpt_table)) | |
1797 { | |
1798 mpt = VEC_index (tree, mpt_table, i); | |
1799 if (MPT_SYMBOLS (mpt) == NULL) | |
1800 VEC_unordered_remove (tree, mpt_table, i); | |
1801 else | |
1802 i++; | |
1803 } | |
1804 } | |
1805 | |
1806 /* Populate all virtual operands and newly promoted register operands. */ | |
1807 { | |
1808 gimple_stmt_iterator gsi; | |
1809 basic_block bb; | |
1810 FOR_EACH_BB (bb) | |
1811 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) | |
1812 update_stmt_if_modified (gsi_stmt (gsi)); | |
1813 } | |
1814 | |
1815 /* Debugging dumps. */ | |
1816 if (dump_file) | |
1817 { | |
1818 dump_mem_ref_stats (dump_file); | |
1819 dump_alias_info (dump_file); | |
1820 dump_points_to_info (dump_file); | |
1821 | |
1822 if (dump_flags & TDF_STATS) | |
1823 dump_alias_stats (dump_file); | |
1824 | |
1825 if (dump_flags & TDF_DETAILS) | |
1826 dump_referenced_vars (dump_file); | |
1827 } | |
1828 | |
1829 /* Deallocate memory used by aliasing data structures. */ | |
1830 delete_alias_info (ai); | |
1831 | |
1832 if (need_ssa_update_p ()) | |
1833 update_ssa (TODO_update_ssa); | |
1834 | |
1835 timevar_pop (TV_TREE_MAY_ALIAS); | |
1836 | |
1837 return 0; | |
1838 } | |
1839 | |
1840 /* Data structure used to count the number of dereferences to PTR | |
1841 inside an expression. */ | |
1842 struct count_ptr_d | |
1843 { | |
1844 tree ptr; | |
1845 unsigned num_stores; | |
1846 unsigned num_loads; | |
1847 }; | |
1848 | |
1849 | |
1850 /* Helper for count_uses_and_derefs. Called by walk_tree to look for | |
1851 (ALIGN/MISALIGNED_)INDIRECT_REF nodes for the pointer passed in DATA. */ | |
1852 | |
1853 static tree | |
1854 count_ptr_derefs (tree *tp, int *walk_subtrees, void *data) | |
1855 { | |
1856 struct walk_stmt_info *wi_p = (struct walk_stmt_info *) data; | |
1857 struct count_ptr_d *count_p = (struct count_ptr_d *) wi_p->info; | |
1858 | |
1859 /* Do not walk inside ADDR_EXPR nodes. In the expression &ptr->fld, | |
1860 pointer 'ptr' is *not* dereferenced, it is simply used to compute | |
1861 the address of 'fld' as 'ptr + offsetof(fld)'. */ | |
1862 if (TREE_CODE (*tp) == ADDR_EXPR) | |
1863 { | |
1864 *walk_subtrees = 0; | |
1865 return NULL_TREE; | |
1866 } | |
1867 | |
1868 if (INDIRECT_REF_P (*tp) && TREE_OPERAND (*tp, 0) == count_p->ptr) | |
1869 { | |
1870 if (wi_p->is_lhs) | |
1871 count_p->num_stores++; | |
1872 else | |
1873 count_p->num_loads++; | |
1874 } | |
1875 | |
1876 return NULL_TREE; | |
1877 } | |
1878 | |
1879 | |
1880 /* Count the number of direct and indirect uses for pointer PTR in | |
1881 statement STMT. The number of direct uses is stored in | |
1882 *NUM_USES_P. Indirect references are counted separately depending | |
1883 on whether they are store or load operations. The counts are | |
1884 stored in *NUM_STORES_P and *NUM_LOADS_P. */ | |
1885 | |
1886 void | |
1887 count_uses_and_derefs (tree ptr, gimple stmt, unsigned *num_uses_p, | |
1888 unsigned *num_loads_p, unsigned *num_stores_p) | |
1889 { | |
1890 ssa_op_iter i; | |
1891 tree use; | |
1892 | |
1893 *num_uses_p = 0; | |
1894 *num_loads_p = 0; | |
1895 *num_stores_p = 0; | |
1896 | |
1897 /* Find out the total number of uses of PTR in STMT. */ | |
1898 FOR_EACH_SSA_TREE_OPERAND (use, stmt, i, SSA_OP_USE) | |
1899 if (use == ptr) | |
1900 (*num_uses_p)++; | |
1901 | |
1902 /* Now count the number of indirect references to PTR. This is | |
1903 truly awful, but we don't have much choice. There are no parent | |
1904 pointers inside INDIRECT_REFs, so an expression like | |
1905 '*x_1 = foo (x_1, *x_1)' needs to be traversed piece by piece to | |
1906 find all the indirect and direct uses of x_1 inside. The only | |
1907 shortcut we can take is the fact that GIMPLE only allows | |
1908 INDIRECT_REFs inside the expressions below. */ | |
1909 if (is_gimple_assign (stmt) | |
1910 || gimple_code (stmt) == GIMPLE_RETURN | |
1911 || gimple_code (stmt) == GIMPLE_ASM | |
1912 || is_gimple_call (stmt)) | |
1913 { | |
1914 struct walk_stmt_info wi; | |
1915 struct count_ptr_d count; | |
1916 | |
1917 count.ptr = ptr; | |
1918 count.num_stores = 0; | |
1919 count.num_loads = 0; | |
1920 | |
1921 memset (&wi, 0, sizeof (wi)); | |
1922 wi.info = &count; | |
1923 walk_gimple_op (stmt, count_ptr_derefs, &wi); | |
1924 | |
1925 *num_stores_p = count.num_stores; | |
1926 *num_loads_p = count.num_loads; | |
1927 } | |
1928 | |
1929 gcc_assert (*num_uses_p >= *num_loads_p + *num_stores_p); | |
1930 } | |
1931 | |
1932 /* Remove memory references stats for function FN. */ | |
1933 | |
1934 void | |
1935 delete_mem_ref_stats (struct function *fn) | |
1936 { | |
1937 if (gimple_mem_ref_stats (fn)->mem_sym_stats) | |
1938 { | |
1939 free_alloc_pool (mem_sym_stats_pool); | |
1940 pointer_map_destroy (gimple_mem_ref_stats (fn)->mem_sym_stats); | |
1941 } | |
1942 gimple_mem_ref_stats (fn)->mem_sym_stats = NULL; | |
1943 } | |
1944 | |
1945 | |
1946 /* Initialize memory reference stats. */ | |
1947 | |
1948 static void | |
1949 init_mem_ref_stats (void) | |
1950 { | |
1951 struct mem_ref_stats_d *mem_ref_stats = gimple_mem_ref_stats (cfun); | |
1952 | |
1953 mem_sym_stats_pool = create_alloc_pool ("Mem sym stats", | |
1954 sizeof (struct mem_sym_stats_d), | |
1955 100); | |
1956 memset (mem_ref_stats, 0, sizeof (struct mem_ref_stats_d)); | |
1957 mem_ref_stats->mem_sym_stats = pointer_map_create (); | |
1958 } | |
1959 | |
1960 | |
1961 /* Helper for init_alias_info. Reset existing aliasing information. */ | |
1962 | |
1963 static void | |
1964 reset_alias_info (void) | |
1965 { | |
1966 referenced_var_iterator rvi; | |
1967 tree var; | |
1968 unsigned i; | |
1969 bitmap active_nmts, all_nmts; | |
1970 | |
1971 /* Clear the set of addressable variables. We do not need to clear | |
1972 the TREE_ADDRESSABLE bit on every symbol because we are going to | |
1973 re-compute addressability here. */ | |
1974 bitmap_clear (gimple_addressable_vars (cfun)); | |
1975 | |
1976 active_nmts = BITMAP_ALLOC (&alias_bitmap_obstack); | |
1977 all_nmts = BITMAP_ALLOC (&alias_bitmap_obstack); | |
1978 | |
1979 /* Clear flow-insensitive alias information from each symbol. */ | |
1980 FOR_EACH_REFERENCED_VAR (var, rvi) | |
1981 { | |
1982 if (is_gimple_reg (var)) | |
1983 continue; | |
1984 | |
1985 if (MTAG_P (var)) | |
1986 MTAG_ALIASES (var) = NULL; | |
1987 | |
1988 /* Memory partition information will be computed from scratch. */ | |
1989 if (TREE_CODE (var) == MEMORY_PARTITION_TAG) | |
1990 MPT_SYMBOLS (var) = NULL; | |
1991 | |
1992 /* Collect all the name tags to determine if we have any | |
1993 orphaned that need to be removed from the IL. A name tag | |
1994 will be orphaned if it is not associated with any active SSA | |
1995 name. */ | |
1996 if (TREE_CODE (var) == NAME_MEMORY_TAG) | |
1997 bitmap_set_bit (all_nmts, DECL_UID (var)); | |
1998 | |
1999 /* Since we are about to re-discover call-clobbered | |
2000 variables, clear the call-clobbered flag. */ | |
2001 clear_call_clobbered (var); | |
2002 } | |
2003 | |
2004 /* There should be no call-clobbered variable left. */ | |
2005 gcc_assert (bitmap_empty_p (gimple_call_clobbered_vars (cfun))); | |
2006 | |
2007 /* Clear the call-used variables. */ | |
2008 bitmap_clear (gimple_call_used_vars (cfun)); | |
2009 | |
2010 /* Clear flow-sensitive points-to information from each SSA name. */ | |
2011 for (i = 1; i < num_ssa_names; i++) | |
2012 { | |
2013 tree name = ssa_name (i); | |
2014 | |
2015 if (!name || !POINTER_TYPE_P (TREE_TYPE (name))) | |
2016 continue; | |
2017 | |
2018 if (SSA_NAME_PTR_INFO (name)) | |
2019 { | |
2020 struct ptr_info_def *pi = SSA_NAME_PTR_INFO (name); | |
2021 | |
2022 /* Clear all the flags but keep the name tag to | |
2023 avoid creating new temporaries unnecessarily. If | |
2024 this pointer is found to point to a subset or | |
2025 superset of its former points-to set, then a new | |
2026 tag will need to be created in create_name_tags. */ | |
2027 pi->pt_anything = 0; | |
2028 pi->pt_null = 0; | |
2029 pi->value_escapes_p = 0; | |
2030 pi->memory_tag_needed = 0; | |
2031 pi->is_dereferenced = 0; | |
2032 if (pi->pt_vars) | |
2033 bitmap_clear (pi->pt_vars); | |
2034 | |
2035 /* Add NAME's name tag to the set of active tags. */ | |
2036 if (pi->name_mem_tag) | |
2037 bitmap_set_bit (active_nmts, DECL_UID (pi->name_mem_tag)); | |
2038 } | |
2039 } | |
2040 | |
2041 /* Name memory tags that are no longer associated with an SSA name | |
2042 are considered stale and should be removed from the IL. All the | |
2043 name tags that are in the set ALL_NMTS but not in ACTIVE_NMTS are | |
2044 considered stale and marked for renaming. */ | |
2045 bitmap_and_compl_into (all_nmts, active_nmts); | |
2046 mark_set_for_renaming (all_nmts); | |
2047 | |
2048 BITMAP_FREE (all_nmts); | |
2049 BITMAP_FREE (active_nmts); | |
2050 } | |
2051 | |
2052 | |
2053 /* Initialize the data structures used for alias analysis. */ | |
2054 | |
2055 static struct alias_info * | |
2056 init_alias_info (void) | |
2057 { | |
2058 struct alias_info *ai; | |
2059 referenced_var_iterator rvi; | |
2060 tree var; | |
2061 static bool alias_bitmap_obstack_initialized; | |
2062 | |
2063 ai = XCNEW (struct alias_info); | |
2064 ai->ssa_names_visited = sbitmap_alloc (num_ssa_names); | |
2065 sbitmap_zero (ai->ssa_names_visited); | |
2066 ai->processed_ptrs = VEC_alloc (tree, heap, 50); | |
2067 ai->dereferenced_ptrs = pointer_set_create (); | |
2068 | |
2069 /* Clear out all memory reference stats. */ | |
2070 init_mem_ref_stats (); | |
2071 | |
2072 /* If aliases have been computed before, clear existing information. */ | |
2073 if (gimple_aliases_computed_p (cfun)) | |
2074 reset_alias_info (); | |
2075 else | |
2076 { | |
2077 /* If this is the first time we compute aliasing information, | |
2078 every non-register symbol will need to be put into SSA form | |
2079 (the initial SSA form only operates on GIMPLE registers). */ | |
2080 FOR_EACH_REFERENCED_VAR (var, rvi) | |
2081 if (!is_gimple_reg (var)) | |
2082 mark_sym_for_renaming (var); | |
2083 } | |
2084 | |
2085 /* Next time, we will need to reset alias information. */ | |
2086 cfun->gimple_df->aliases_computed_p = true; | |
2087 if (alias_bitmap_obstack_initialized) | |
2088 bitmap_obstack_release (&alias_bitmap_obstack); | |
2089 bitmap_obstack_initialize (&alias_bitmap_obstack); | |
2090 alias_bitmap_obstack_initialized = true; | |
2091 | |
2092 return ai; | |
2093 } | |
2094 | |
2095 | |
2096 /* Deallocate memory used by alias analysis. */ | |
2097 | |
2098 static void | |
2099 delete_alias_info (struct alias_info *ai) | |
2100 { | |
2101 size_t i; | |
2102 | |
2103 sbitmap_free (ai->ssa_names_visited); | |
2104 | |
2105 VEC_free (tree, heap, ai->processed_ptrs); | |
2106 | |
2107 for (i = 0; i < ai->num_addressable_vars; i++) | |
2108 free (ai->addressable_vars[i]); | |
2109 free (ai->addressable_vars); | |
2110 | |
2111 for (i = 0; i < ai->num_pointers; i++) | |
2112 free (ai->pointers[i]); | |
2113 free (ai->pointers); | |
2114 | |
2115 pointer_set_destroy (ai->dereferenced_ptrs); | |
2116 free (ai); | |
2117 | |
2118 delete_mem_ref_stats (cfun); | |
2119 delete_points_to_sets (); | |
2120 } | |
2121 | |
2122 | |
2123 /* Used for hashing to identify pointer infos with identical | |
2124 pt_vars bitmaps. */ | |
2125 | |
2126 static int | |
2127 eq_ptr_info (const void *p1, const void *p2) | |
2128 { | |
2129 const struct ptr_info_def *n1 = (const struct ptr_info_def *) p1; | |
2130 const struct ptr_info_def *n2 = (const struct ptr_info_def *) p2; | |
2131 return bitmap_equal_p (n1->pt_vars, n2->pt_vars); | |
2132 } | |
2133 | |
2134 static hashval_t | |
2135 ptr_info_hash (const void *p) | |
2136 { | |
2137 const struct ptr_info_def *n = (const struct ptr_info_def *) p; | |
2138 return bitmap_hash (n->pt_vars); | |
2139 } | |
2140 | |
2141 | |
2142 /* Create name tags for all the pointers that have been dereferenced. | |
2143 We only create a name tag for a pointer P if P is found to point to | |
2144 a set of variables (so that we can alias them to *P) or if it is | |
2145 the result of a call to malloc (which means that P cannot point to | |
2146 anything else nor alias any other variable). | |
2147 | |
2148 If two pointers P and Q point to the same set of variables, they | |
2149 are assigned the same name tag. */ | |
2150 | |
2151 static void | |
2152 create_name_tags (void) | |
2153 { | |
2154 size_t i; | |
2155 VEC (tree, heap) *with_ptvars = NULL; | |
2156 tree ptr; | |
2157 htab_t ptr_hash; | |
2158 | |
2159 /* Collect the list of pointers with a non-empty points to set. */ | |
2160 for (i = 1; i < num_ssa_names; i++) | |
2161 { | |
2162 tree ptr = ssa_name (i); | |
2163 struct ptr_info_def *pi; | |
2164 | |
2165 if (!ptr | |
2166 || !POINTER_TYPE_P (TREE_TYPE (ptr)) | |
2167 || !SSA_NAME_PTR_INFO (ptr)) | |
2168 continue; | |
2169 | |
2170 pi = SSA_NAME_PTR_INFO (ptr); | |
2171 | |
2172 if (pi->pt_anything || !pi->memory_tag_needed) | |
2173 { | |
2174 /* No name tags for pointers that have not been | |
2175 dereferenced or point to an arbitrary location. */ | |
2176 pi->name_mem_tag = NULL_TREE; | |
2177 continue; | |
2178 } | |
2179 | |
2180 /* Set pt_anything on the pointers without pt_vars filled in so | |
2181 that they are assigned a symbol tag. */ | |
2182 if (pi->pt_vars && !bitmap_empty_p (pi->pt_vars)) | |
2183 VEC_safe_push (tree, heap, with_ptvars, ptr); | |
2184 else | |
2185 set_pt_anything (ptr); | |
2186 } | |
2187 | |
2188 /* If we didn't find any pointers with pt_vars set, we're done. */ | |
2189 if (!with_ptvars) | |
2190 return; | |
2191 | |
2192 ptr_hash = htab_create (10, ptr_info_hash, eq_ptr_info, NULL); | |
2193 | |
2194 /* Now go through the pointers with pt_vars, and find a name tag | |
2195 with the same pt_vars as this pointer, or create one if one | |
2196 doesn't exist. */ | |
2197 for (i = 0; VEC_iterate (tree, with_ptvars, i, ptr); i++) | |
2198 { | |
2199 struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr); | |
2200 tree old_name_tag = pi->name_mem_tag; | |
2201 struct ptr_info_def **slot; | |
2202 | |
2203 /* If PTR points to a set of variables, check if we don't | |
2204 have another pointer Q with the same points-to set before | |
2205 creating a tag. If so, use Q's tag instead of creating a | |
2206 new one. | |
2207 | |
2208 This is important for not creating unnecessary symbols | |
2209 and also for copy propagation. If we ever need to | |
2210 propagate PTR into Q or vice-versa, we would run into | |
2211 problems if they both had different name tags because | |
2212 they would have different SSA version numbers (which | |
2213 would force us to take the name tags in and out of SSA). */ | |
2214 slot = (struct ptr_info_def **) htab_find_slot (ptr_hash, pi, INSERT); | |
2215 if (*slot) | |
2216 pi->name_mem_tag = (*slot)->name_mem_tag; | |
2217 else | |
2218 { | |
2219 *slot = pi; | |
2220 | |
2221 /* If we didn't find a pointer with the same points-to set | |
2222 as PTR, create a new name tag if needed. */ | |
2223 if (pi->name_mem_tag == NULL_TREE) | |
2224 pi->name_mem_tag = get_nmt_for (ptr); | |
2225 } | |
2226 | |
2227 /* If the new name tag computed for PTR is different than | |
2228 the old name tag that it used to have, then the old tag | |
2229 needs to be removed from the IL, so we mark it for | |
2230 renaming. */ | |
2231 if (old_name_tag && old_name_tag != pi->name_mem_tag) | |
2232 mark_sym_for_renaming (old_name_tag); | |
2233 | |
2234 /* Inherit volatility from the pointed-to type. */ | |
2235 TREE_THIS_VOLATILE (pi->name_mem_tag) | |
2236 |= TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (ptr))); | |
2237 | |
2238 /* Mark the new name tag for renaming. */ | |
2239 mark_sym_for_renaming (pi->name_mem_tag); | |
2240 } | |
2241 | |
2242 htab_delete (ptr_hash); | |
2243 | |
2244 VEC_free (tree, heap, with_ptvars); | |
2245 } | |
2246 | |
2247 | |
2248 /* Union the alias set SET into the may-aliases for TAG. */ | |
2249 | |
2250 static void | |
2251 union_alias_set_into (tree tag, bitmap set) | |
2252 { | |
2253 bitmap ma = MTAG_ALIASES (tag); | |
2254 | |
2255 if (bitmap_empty_p (set)) | |
2256 return; | |
2257 | |
2258 if (!ma) | |
2259 ma = MTAG_ALIASES (tag) = BITMAP_ALLOC (&alias_bitmap_obstack); | |
2260 bitmap_ior_into (ma, set); | |
2261 } | |
2262 | |
2263 | |
2264 /* For every pointer P_i in AI->PROCESSED_PTRS, create may-alias sets for | |
2265 the name memory tag (NMT) associated with P_i. If P_i escapes, then its | |
2266 name tag and the variables it points-to are call-clobbered. Finally, if | |
2267 P_i escapes and we could not determine where it points to, then all the | |
2268 variables in the same alias set as *P_i are marked call-clobbered. This | |
2269 is necessary because we must assume that P_i may take the address of any | |
2270 variable in the same alias set. */ | |
2271 | |
2272 static void | |
2273 compute_flow_sensitive_aliasing (struct alias_info *ai) | |
2274 { | |
2275 size_t i; | |
2276 tree ptr; | |
2277 | |
2278 timevar_push (TV_FLOW_SENSITIVE); | |
2279 | |
2280 for (i = 0; VEC_iterate (tree, ai->processed_ptrs, i, ptr); i++) | |
2281 { | |
2282 if (!find_what_p_points_to (ptr)) | |
2283 set_pt_anything (ptr); | |
2284 } | |
2285 | |
2286 create_name_tags (); | |
2287 | |
2288 for (i = 0; VEC_iterate (tree, ai->processed_ptrs, i, ptr); i++) | |
2289 { | |
2290 struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr); | |
2291 | |
2292 /* Set up aliasing information for PTR's name memory tag (if it has | |
2293 one). Note that only pointers that have been dereferenced will | |
2294 have a name memory tag. */ | |
2295 if (pi->name_mem_tag && pi->pt_vars) | |
2296 { | |
2297 if (!bitmap_empty_p (pi->pt_vars)) | |
2298 union_alias_set_into (pi->name_mem_tag, pi->pt_vars); | |
2299 } | |
2300 } | |
2301 timevar_pop (TV_FLOW_SENSITIVE); | |
2302 } | |
2303 | |
2304 | |
2305 /* Return TRUE if at least one symbol in TAG2's alias set is also | |
2306 present in TAG1's alias set. */ | |
2307 | |
2308 static bool | |
2309 have_common_aliases_p (bitmap tag1aliases, bitmap tag2aliases) | |
2310 { | |
2311 | |
2312 /* This is the old behavior of have_common_aliases_p, which is to | |
2313 return false if both sets are empty, or one set is and the other | |
2314 isn't. */ | |
2315 if (tag1aliases == NULL || tag2aliases == NULL) | |
2316 return false; | |
2317 | |
2318 return bitmap_intersect_p (tag1aliases, tag2aliases); | |
2319 } | |
2320 | |
2321 /* Compute type-based alias sets. Traverse all the pointers and | |
2322 addressable variables found in setup_pointers_and_addressables. | |
2323 | |
2324 For every pointer P in AI->POINTERS and addressable variable V in | |
2325 AI->ADDRESSABLE_VARS, add V to the may-alias sets of P's symbol | |
2326 memory tag (SMT) if their alias sets conflict. V is then marked as | |
2327 an aliased symbol so that the operand scanner knows that statements | |
2328 containing V have aliased operands. */ | |
2329 | |
2330 static void | |
2331 compute_flow_insensitive_aliasing (struct alias_info *ai) | |
2332 { | |
2333 referenced_var_iterator rvi; | |
2334 tree var; | |
2335 size_t i; | |
2336 | |
2337 timevar_push (TV_FLOW_INSENSITIVE); | |
2338 /* For every pointer P, determine which addressable variables may alias | |
2339 with P's symbol memory tag. */ | |
2340 for (i = 0; i < ai->num_pointers; i++) | |
2341 { | |
2342 size_t j; | |
2343 struct alias_map_d *p_map = ai->pointers[i]; | |
2344 tree tag = symbol_mem_tag (p_map->var); | |
2345 tree var; | |
2346 | |
2347 for (j = 0; j < ai->num_addressable_vars; j++) | |
2348 { | |
2349 struct alias_map_d *v_map; | |
2350 var_ann_t v_ann; | |
2351 | |
2352 v_map = ai->addressable_vars[j]; | |
2353 var = v_map->var; | |
2354 v_ann = var_ann (var); | |
2355 | |
2356 /* We used to skip variables that have never been written to | |
2357 if the memory tag has been never written to directly (or | |
2358 either of them were call clobbered). This is not enough | |
2359 though, as this misses writes through the tags aliases. | |
2360 So, for correctness we need to include any aliased | |
2361 variable here. */ | |
2362 | |
2363 if (may_alias_p (p_map->var, p_map->set, var, v_map->set, false)) | |
2364 { | |
2365 /* Add VAR to TAG's may-aliases set. */ | |
2366 add_may_alias (tag, var); | |
2367 } | |
2368 } | |
2369 } | |
2370 | |
2371 /* Since this analysis is based exclusively on symbols, it fails to | |
2372 handle cases where two pointers P and Q have different memory | |
2373 tags with conflicting alias set numbers but no aliased symbols in | |
2374 common. | |
2375 | |
2376 For example, suppose that we have two memory tags SMT.1 and SMT.2 | |
2377 such that | |
2378 | |
2379 may-aliases (SMT.1) = { a } | |
2380 may-aliases (SMT.2) = { b } | |
2381 | |
2382 and the alias set number of SMT.1 conflicts with that of SMT.2. | |
2383 Since they don't have symbols in common, loads and stores from | |
2384 SMT.1 and SMT.2 will seem independent of each other, which will | |
2385 lead to the optimizers making invalid transformations (see | |
2386 testsuite/gcc.c-torture/execute/pr15262-[12].c). | |
2387 | |
2388 To avoid this problem, we do a final traversal of AI->POINTERS | |
2389 looking for pairs of pointers that have no aliased symbols in | |
2390 common and yet have conflicting alias set numbers. */ | |
2391 for (i = 0; i < ai->num_pointers; i++) | |
2392 { | |
2393 size_t j; | |
2394 struct alias_map_d *p_map1 = ai->pointers[i]; | |
2395 tree tag1 = symbol_mem_tag (p_map1->var); | |
2396 bitmap may_aliases1 = MTAG_ALIASES (tag1); | |
2397 | |
2398 for (j = 0; j < ai->num_pointers; j++) | |
2399 { | |
2400 struct alias_map_d *p_map2 = ai->pointers[j]; | |
2401 tree tag2 = symbol_mem_tag (p_map2->var); | |
2402 bitmap may_aliases2 = may_aliases (tag2); | |
2403 | |
2404 /* By convention tags don't alias themselves. */ | |
2405 if (tag1 == tag2) | |
2406 continue; | |
2407 | |
2408 /* If the pointers may not point to each other, do nothing. */ | |
2409 if (!may_alias_p (p_map1->var, p_map1->set, tag2, p_map2->set, true)) | |
2410 continue; | |
2411 | |
2412 /* The two pointers may alias each other. If they already have | |
2413 symbols in common, do nothing. */ | |
2414 if (have_common_aliases_p (may_aliases1, may_aliases2)) | |
2415 continue; | |
2416 | |
2417 add_may_alias (tag1, tag2); | |
2418 } | |
2419 } | |
2420 | |
2421 /* We have to add all HEAP variables to all SMTs aliases bitmaps. | |
2422 As we don't know which effective type the HEAP will have we cannot | |
2423 do better here and we need the conflicts with obfuscated pointers | |
2424 (a simple (*(int[n] *)ptr)[i] will do, with ptr from a VLA array | |
2425 allocation). */ | |
2426 for (i = 0; i < ai->num_pointers; i++) | |
2427 { | |
2428 struct alias_map_d *p_map = ai->pointers[i]; | |
2429 tree tag = symbol_mem_tag (p_map->var); | |
2430 | |
2431 FOR_EACH_REFERENCED_VAR (var, rvi) | |
2432 { | |
2433 if (var_ann (var)->is_heapvar) | |
2434 add_may_alias (tag, var); | |
2435 } | |
2436 } | |
2437 | |
2438 timevar_pop (TV_FLOW_INSENSITIVE); | |
2439 } | |
2440 | |
2441 | |
2442 /* Create a new alias set entry for VAR in AI->ADDRESSABLE_VARS. */ | |
2443 | |
2444 static void | |
2445 create_alias_map_for (tree var, struct alias_info *ai) | |
2446 { | |
2447 struct alias_map_d *alias_map; | |
2448 alias_map = XCNEW (struct alias_map_d); | |
2449 alias_map->var = var; | |
2450 alias_map->set = get_alias_set (var); | |
2451 ai->addressable_vars[ai->num_addressable_vars++] = alias_map; | |
2452 } | |
2453 | |
2454 | |
2455 /* Update related alias information kept in AI. This is used when | |
2456 building name tags, alias sets and deciding grouping heuristics. | |
2457 STMT is the statement to process. This function also updates | |
2458 ADDRESSABLE_VARS. */ | |
2459 | |
2460 static void | |
2461 update_alias_info_1 (gimple stmt, struct alias_info *ai) | |
2462 { | |
2463 bitmap addr_taken; | |
2464 use_operand_p use_p; | |
2465 ssa_op_iter iter; | |
2466 bool stmt_dereferences_ptr_p; | |
2467 enum escape_type stmt_escape_type = is_escape_site (stmt); | |
2468 struct mem_ref_stats_d *mem_ref_stats = gimple_mem_ref_stats (cfun); | |
2469 | |
2470 stmt_dereferences_ptr_p = false; | |
2471 | |
2472 if (stmt_escape_type == ESCAPE_TO_CALL | |
2473 || stmt_escape_type == ESCAPE_TO_PURE_CONST) | |
2474 { | |
2475 mem_ref_stats->num_call_sites++; | |
2476 if (stmt_escape_type == ESCAPE_TO_PURE_CONST) | |
2477 mem_ref_stats->num_pure_const_call_sites++; | |
2478 } | |
2479 else if (stmt_escape_type == ESCAPE_TO_ASM) | |
2480 mem_ref_stats->num_asm_sites++; | |
2481 | |
2482 /* Mark all the variables whose address are taken by the statement. */ | |
2483 addr_taken = gimple_addresses_taken (stmt); | |
2484 if (addr_taken) | |
2485 bitmap_ior_into (gimple_addressable_vars (cfun), addr_taken); | |
2486 | |
2487 /* If we have a call or an assignment, see if the lhs contains | |
2488 a local decl that requires not to be a gimple register. */ | |
2489 if (gimple_code (stmt) == GIMPLE_ASSIGN | |
2490 || gimple_code (stmt) == GIMPLE_CALL) | |
2491 { | |
2492 tree lhs = gimple_get_lhs (stmt); | |
2493 /* A plain decl does not need it set. */ | |
2494 if (lhs && handled_component_p (lhs)) | |
2495 { | |
2496 tree var = get_base_address (lhs); | |
2497 if (DECL_P (var) | |
2498 /* We are not going to mess with RESULT_DECL anyway. */ | |
2499 && TREE_CODE (var) != RESULT_DECL | |
2500 && is_gimple_reg_type (TREE_TYPE (var))) | |
2501 bitmap_set_bit (gimple_addressable_vars (cfun), DECL_UID (var)); | |
2502 } | |
2503 } | |
2504 | |
2505 /* Process each operand use. For pointers, determine whether they | |
2506 are dereferenced by the statement, or whether their value | |
2507 escapes, etc. */ | |
2508 FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, iter, SSA_OP_USE) | |
2509 { | |
2510 tree op, var; | |
2511 var_ann_t v_ann; | |
2512 struct ptr_info_def *pi; | |
2513 unsigned num_uses, num_loads, num_stores; | |
2514 | |
2515 op = USE_FROM_PTR (use_p); | |
2516 | |
2517 /* If STMT is a PHI node, OP may be an ADDR_EXPR. If so, add it | |
2518 to the set of addressable variables. */ | |
2519 if (TREE_CODE (op) == ADDR_EXPR) | |
2520 { | |
2521 bitmap addressable_vars = gimple_addressable_vars (cfun); | |
2522 | |
2523 gcc_assert (gimple_code (stmt) == GIMPLE_PHI); | |
2524 gcc_assert (addressable_vars); | |
2525 | |
2526 /* PHI nodes don't have annotations for pinning the set | |
2527 of addresses taken, so we collect them here. | |
2528 | |
2529 FIXME, should we allow PHI nodes to have annotations | |
2530 so that they can be treated like regular statements? | |
2531 Currently, they are treated as second-class | |
2532 statements. */ | |
2533 add_to_addressable_set (TREE_OPERAND (op, 0), &addressable_vars); | |
2534 continue; | |
2535 } | |
2536 | |
2537 /* Ignore constants (they may occur in PHI node arguments). */ | |
2538 if (TREE_CODE (op) != SSA_NAME) | |
2539 continue; | |
2540 | |
2541 var = SSA_NAME_VAR (op); | |
2542 v_ann = var_ann (var); | |
2543 | |
2544 /* The base variable of an SSA name must be a GIMPLE register, and thus | |
2545 it cannot be aliased. */ | |
2546 gcc_assert (!may_be_aliased (var)); | |
2547 | |
2548 /* We are only interested in pointers. */ | |
2549 if (!POINTER_TYPE_P (TREE_TYPE (op))) | |
2550 continue; | |
2551 | |
2552 pi = get_ptr_info (op); | |
2553 | |
2554 /* Add OP to AI->PROCESSED_PTRS, if it's not there already. */ | |
2555 if (!TEST_BIT (ai->ssa_names_visited, SSA_NAME_VERSION (op))) | |
2556 { | |
2557 SET_BIT (ai->ssa_names_visited, SSA_NAME_VERSION (op)); | |
2558 VEC_safe_push (tree, heap, ai->processed_ptrs, op); | |
2559 } | |
2560 | |
2561 /* If STMT is a PHI node, then it will not have pointer | |
2562 dereferences and it will not be an escape point. */ | |
2563 if (gimple_code (stmt) == GIMPLE_PHI) | |
2564 continue; | |
2565 | |
2566 /* Determine whether OP is a dereferenced pointer, and if STMT | |
2567 is an escape point, whether OP escapes. */ | |
2568 count_uses_and_derefs (op, stmt, &num_uses, &num_loads, &num_stores); | |
2569 | |
2570 /* For directly dereferenced pointers we can apply | |
2571 TBAA-pruning to their points-to set. We may not count the | |
2572 implicit dereferences &PTR->FLD here. */ | |
2573 if (num_loads + num_stores > 0) | |
2574 pi->is_dereferenced = 1; | |
2575 | |
2576 /* Handle a corner case involving address expressions of the | |
2577 form '&PTR->FLD'. The problem with these expressions is that | |
2578 they do not represent a dereference of PTR. However, if some | |
2579 other transformation propagates them into an INDIRECT_REF | |
2580 expression, we end up with '*(&PTR->FLD)' which is folded | |
2581 into 'PTR->FLD'. | |
2582 | |
2583 So, if the original code had no other dereferences of PTR, | |
2584 the aliaser will not create memory tags for it, and when | |
2585 &PTR->FLD gets propagated to INDIRECT_REF expressions, the | |
2586 memory operations will receive no VDEF/VUSE operands. | |
2587 | |
2588 One solution would be to have count_uses_and_derefs consider | |
2589 &PTR->FLD a dereference of PTR. But that is wrong, since it | |
2590 is not really a dereference but an offset calculation. | |
2591 | |
2592 What we do here is to recognize these special ADDR_EXPR | |
2593 nodes. Since these expressions are never GIMPLE values (they | |
2594 are not GIMPLE invariants), they can only appear on the RHS | |
2595 of an assignment and their base address is always an | |
2596 INDIRECT_REF expression. */ | |
2597 if (is_gimple_assign (stmt) | |
2598 && gimple_assign_rhs_code (stmt) == ADDR_EXPR | |
2599 && !is_gimple_val (gimple_assign_rhs1 (stmt))) | |
2600 { | |
2601 /* If the RHS if of the form &PTR->FLD and PTR == OP, then | |
2602 this represents a potential dereference of PTR. */ | |
2603 tree rhs = gimple_assign_rhs1 (stmt); | |
2604 tree base = get_base_address (TREE_OPERAND (rhs, 0)); | |
2605 if (TREE_CODE (base) == INDIRECT_REF | |
2606 && TREE_OPERAND (base, 0) == op) | |
2607 num_loads++; | |
2608 } | |
2609 | |
2610 if (num_loads + num_stores > 0) | |
2611 { | |
2612 /* Mark OP as dereferenced. In a subsequent pass, | |
2613 dereferenced pointers that point to a set of | |
2614 variables will be assigned a name tag to alias | |
2615 all the variables OP points to. */ | |
2616 pi->memory_tag_needed = 1; | |
2617 | |
2618 /* ??? For always executed direct dereferences we can | |
2619 apply TBAA-pruning to their escape set. */ | |
2620 | |
2621 /* Mark OP as being dereferenced. */ | |
2622 pointer_set_insert (ai->dereferenced_ptrs, var); | |
2623 | |
2624 /* Update the frequency estimate for all the dereferences of | |
2625 pointer OP. */ | |
2626 update_mem_sym_stats_from_stmt (op, stmt, num_loads, num_stores); | |
2627 | |
2628 /* Indicate that STMT contains pointer dereferences. */ | |
2629 stmt_dereferences_ptr_p = true; | |
2630 } | |
2631 | |
2632 if (stmt_escape_type != NO_ESCAPE && num_loads + num_stores < num_uses) | |
2633 { | |
2634 /* If STMT is an escape point and STMT contains at | |
2635 least one direct use of OP, then the value of OP | |
2636 escapes and so the pointed-to variables need to | |
2637 be marked call-clobbered. */ | |
2638 pi->value_escapes_p = 1; | |
2639 pi->escape_mask |= stmt_escape_type; | |
2640 | |
2641 /* If the statement makes a function call, assume | |
2642 that pointer OP will be dereferenced in a store | |
2643 operation inside the called function. */ | |
2644 if (is_gimple_call (stmt) | |
2645 || stmt_escape_type == ESCAPE_STORED_IN_GLOBAL) | |
2646 { | |
2647 pointer_set_insert (ai->dereferenced_ptrs, var); | |
2648 pi->memory_tag_needed = 1; | |
2649 } | |
2650 } | |
2651 } | |
2652 | |
2653 if (gimple_code (stmt) == GIMPLE_PHI) | |
2654 return; | |
2655 | |
2656 /* Mark stored variables in STMT as being written to and update the | |
2657 memory reference stats for all memory symbols referenced by STMT. */ | |
2658 if (gimple_references_memory_p (stmt)) | |
2659 { | |
2660 unsigned i; | |
2661 bitmap_iterator bi; | |
2662 | |
2663 mem_ref_stats->num_mem_stmts++; | |
2664 | |
2665 /* Notice that we only update memory reference stats for symbols | |
2666 loaded and stored by the statement if the statement does not | |
2667 contain pointer dereferences and it is not a call/asm site. | |
2668 This is to avoid double accounting problems when creating | |
2669 memory partitions. After computing points-to information, | |
2670 pointer dereference statistics are used to update the | |
2671 reference stats of the pointed-to variables, so here we | |
2672 should only update direct references to symbols. | |
2673 | |
2674 Indirect references are not updated here for two reasons: (1) | |
2675 The first time we compute alias information, the sets | |
2676 LOADED/STORED are empty for pointer dereferences, (2) After | |
2677 partitioning, LOADED/STORED may have references to | |
2678 partitions, not the original pointed-to variables. So, if we | |
2679 always counted LOADED/STORED here and during partitioning, we | |
2680 would count many symbols more than once. | |
2681 | |
2682 This does cause some imprecision when a statement has a | |
2683 combination of direct symbol references and pointer | |
2684 dereferences (e.g., MEMORY_VAR = *PTR) or if a call site has | |
2685 memory symbols in its argument list, but these cases do not | |
2686 occur so frequently as to constitute a serious problem. */ | |
2687 if (!stmt_dereferences_ptr_p | |
2688 && stmt_escape_type != ESCAPE_TO_CALL | |
2689 && stmt_escape_type != ESCAPE_TO_PURE_CONST | |
2690 && stmt_escape_type != ESCAPE_TO_ASM) | |
2691 { | |
2692 if (gimple_stored_syms (stmt)) | |
2693 EXECUTE_IF_SET_IN_BITMAP (gimple_stored_syms (stmt), 0, i, bi) | |
2694 update_mem_sym_stats_from_stmt (referenced_var (i), stmt, 0, 1); | |
2695 | |
2696 if (gimple_loaded_syms (stmt)) | |
2697 EXECUTE_IF_SET_IN_BITMAP (gimple_loaded_syms (stmt), 0, i, bi) | |
2698 update_mem_sym_stats_from_stmt (referenced_var (i), stmt, 1, 0); | |
2699 } | |
2700 } | |
2701 } | |
2702 | |
2703 /* Update various related attributes like escaped addresses, | |
2704 pointer dereferences for loads and stores. This is used | |
2705 when creating name tags and alias sets. */ | |
2706 | |
2707 static void | |
2708 update_alias_info (struct alias_info *ai) | |
2709 { | |
2710 basic_block bb; | |
2711 | |
2712 FOR_EACH_BB (bb) | |
2713 { | |
2714 gimple_stmt_iterator gsi; | |
2715 gimple phi; | |
2716 | |
2717 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) | |
2718 { | |
2719 phi = gsi_stmt (gsi); | |
2720 if (is_gimple_reg (PHI_RESULT (phi))) | |
2721 update_alias_info_1 (phi, ai); | |
2722 } | |
2723 | |
2724 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) | |
2725 update_alias_info_1 (gsi_stmt (gsi), ai); | |
2726 } | |
2727 } | |
2728 | |
2729 /* Create memory tags for all the dereferenced pointers and build the | |
2730 ADDRESSABLE_VARS and POINTERS arrays used for building the may-alias | |
2731 sets. Based on the address escape and points-to information collected | |
2732 earlier, this pass will also clear the TREE_ADDRESSABLE flag from those | |
2733 variables whose address is not needed anymore. */ | |
2734 | |
2735 static void | |
2736 setup_pointers_and_addressables (struct alias_info *ai) | |
2737 { | |
2738 size_t num_addressable_vars, num_pointers; | |
2739 referenced_var_iterator rvi; | |
2740 tree var; | |
2741 VEC (tree, heap) *varvec = NULL; | |
2742 safe_referenced_var_iterator srvi; | |
2743 | |
2744 /* Size up the arrays ADDRESSABLE_VARS and POINTERS. */ | |
2745 num_addressable_vars = num_pointers = 0; | |
2746 | |
2747 FOR_EACH_REFERENCED_VAR (var, rvi) | |
2748 { | |
2749 if (may_be_aliased (var)) | |
2750 num_addressable_vars++; | |
2751 | |
2752 if (POINTER_TYPE_P (TREE_TYPE (var))) | |
2753 { | |
2754 /* Since we don't keep track of volatile variables, assume that | |
2755 these pointers are used in indirect store operations. */ | |
2756 if (TREE_THIS_VOLATILE (var)) | |
2757 pointer_set_insert (ai->dereferenced_ptrs, var); | |
2758 | |
2759 num_pointers++; | |
2760 } | |
2761 } | |
2762 | |
2763 /* Create ADDRESSABLE_VARS and POINTERS. Note that these arrays are | |
2764 always going to be slightly bigger than we actually need them | |
2765 because some TREE_ADDRESSABLE variables will be marked | |
2766 non-addressable below and only pointers with unique symbol tags are | |
2767 going to be added to POINTERS. */ | |
2768 ai->addressable_vars = XCNEWVEC (struct alias_map_d *, num_addressable_vars); | |
2769 ai->pointers = XCNEWVEC (struct alias_map_d *, num_pointers); | |
2770 ai->num_addressable_vars = 0; | |
2771 ai->num_pointers = 0; | |
2772 | |
2773 FOR_EACH_REFERENCED_VAR_SAFE (var, varvec, srvi) | |
2774 { | |
2775 /* Name memory tags already have flow-sensitive aliasing | |
2776 information, so they need not be processed by | |
2777 compute_flow_insensitive_aliasing. Similarly, symbol memory | |
2778 tags are already accounted for when we process their | |
2779 associated pointer. | |
2780 | |
2781 Structure fields, on the other hand, have to have some of this | |
2782 information processed for them, but it's pointless to mark them | |
2783 non-addressable (since they are fake variables anyway). */ | |
2784 if (MTAG_P (var)) | |
2785 continue; | |
2786 | |
2787 /* Remove the ADDRESSABLE flag from every addressable variable whose | |
2788 address is not needed anymore. This is caused by the propagation | |
2789 of ADDR_EXPR constants into INDIRECT_REF expressions and the | |
2790 removal of dead pointer assignments done by the early scalar | |
2791 cleanup passes. */ | |
2792 if (TREE_ADDRESSABLE (var)) | |
2793 { | |
2794 if (!bitmap_bit_p (gimple_addressable_vars (cfun), DECL_UID (var)) | |
2795 && TREE_CODE (var) != RESULT_DECL | |
2796 && !is_global_var (var)) | |
2797 { | |
2798 bool okay_to_mark = true; | |
2799 | |
2800 /* Since VAR is now a regular GIMPLE register, we will need | |
2801 to rename VAR into SSA afterwards. */ | |
2802 mark_sym_for_renaming (var); | |
2803 | |
2804 /* The address of VAR is not needed, remove the | |
2805 addressable bit, so that it can be optimized as a | |
2806 regular variable. */ | |
2807 if (okay_to_mark) | |
2808 { | |
2809 /* The memory partition holding VAR will no longer | |
2810 contain VAR, and statements referencing it will need | |
2811 to be updated. */ | |
2812 if (memory_partition (var)) | |
2813 mark_sym_for_renaming (memory_partition (var)); | |
2814 | |
2815 mark_non_addressable (var); | |
2816 } | |
2817 } | |
2818 } | |
2819 | |
2820 /* Global variables and addressable locals may be aliased. Create an | |
2821 entry in ADDRESSABLE_VARS for VAR. */ | |
2822 if (may_be_aliased (var)) | |
2823 { | |
2824 create_alias_map_for (var, ai); | |
2825 mark_sym_for_renaming (var); | |
2826 } | |
2827 | |
2828 /* Add pointer variables that have been dereferenced to the POINTERS | |
2829 array and create a symbol memory tag for them. */ | |
2830 if (POINTER_TYPE_P (TREE_TYPE (var))) | |
2831 { | |
2832 if (pointer_set_contains (ai->dereferenced_ptrs, var)) | |
2833 { | |
2834 tree tag, old_tag; | |
2835 var_ann_t t_ann; | |
2836 | |
2837 /* If pointer VAR still doesn't have a memory tag | |
2838 associated with it, create it now or re-use an | |
2839 existing one. */ | |
2840 tag = get_smt_for (var, ai); | |
2841 t_ann = var_ann (tag); | |
2842 | |
2843 /* The symbol tag will need to be renamed into SSA | |
2844 afterwards. Note that we cannot do this inside | |
2845 get_smt_for because aliasing may run multiple times | |
2846 and we only create symbol tags the first time. */ | |
2847 mark_sym_for_renaming (tag); | |
2848 | |
2849 /* Similarly, if pointer VAR used to have another type | |
2850 tag, we will need to process it in the renamer to | |
2851 remove the stale virtual operands. */ | |
2852 old_tag = symbol_mem_tag (var); | |
2853 if (old_tag) | |
2854 mark_sym_for_renaming (old_tag); | |
2855 | |
2856 /* Associate the tag with pointer VAR. */ | |
2857 set_symbol_mem_tag (var, tag); | |
2858 } | |
2859 else | |
2860 { | |
2861 /* The pointer has not been dereferenced. If it had a | |
2862 symbol memory tag, remove it and mark the old tag for | |
2863 renaming to remove it out of the IL. */ | |
2864 tree tag = symbol_mem_tag (var); | |
2865 if (tag) | |
2866 { | |
2867 mark_sym_for_renaming (tag); | |
2868 set_symbol_mem_tag (var, NULL_TREE); | |
2869 } | |
2870 } | |
2871 } | |
2872 } | |
2873 | |
2874 VEC_free (tree, heap, varvec); | |
2875 } | |
2876 | |
2877 | |
2878 /* Determine whether to use .GLOBAL_VAR to model call clobbering | |
2879 semantics. If the function makes no references to global | |
2880 variables and contains at least one call to a non-pure function, | |
2881 then we need to mark the side-effects of the call using .GLOBAL_VAR | |
2882 to represent all possible global memory referenced by the callee. */ | |
2883 | |
2884 static void | |
2885 maybe_create_global_var (void) | |
2886 { | |
2887 /* No need to create it, if we have one already. */ | |
2888 if (gimple_global_var (cfun) == NULL_TREE) | |
2889 { | |
2890 struct mem_ref_stats_d *stats = gimple_mem_ref_stats (cfun); | |
2891 | |
2892 /* Create .GLOBAL_VAR if there are no call-clobbered | |
2893 variables and the program contains a mixture of pure/const | |
2894 and regular function calls. This is to avoid the problem | |
2895 described in PR 20115: | |
2896 | |
2897 int X; | |
2898 int func_pure (void) { return X; } | |
2899 int func_non_pure (int a) { X += a; } | |
2900 int foo () | |
2901 { | |
2902 int a = func_pure (); | |
2903 func_non_pure (a); | |
2904 a = func_pure (); | |
2905 return a; | |
2906 } | |
2907 | |
2908 Since foo() has no call-clobbered variables, there is | |
2909 no relationship between the calls to func_pure and | |
2910 func_non_pure. Since func_pure has no side-effects, value | |
2911 numbering optimizations elide the second call to func_pure. | |
2912 So, if we have some pure/const and some regular calls in the | |
2913 program we create .GLOBAL_VAR to avoid missing these | |
2914 relations. */ | |
2915 if (bitmap_empty_p (gimple_call_clobbered_vars (cfun)) | |
2916 && stats->num_call_sites > 0 | |
2917 && stats->num_pure_const_call_sites > 0 | |
2918 && stats->num_call_sites > stats->num_pure_const_call_sites) | |
2919 create_global_var (); | |
2920 } | |
2921 } | |
2922 | |
2923 | |
2924 /* Return TRUE if pointer PTR may point to variable VAR. | |
2925 | |
2926 MEM_ALIAS_SET is the alias set for the memory location pointed-to by PTR | |
2927 This is needed because when checking for type conflicts we are | |
2928 interested in the alias set of the memory location pointed-to by | |
2929 PTR. The alias set of PTR itself is irrelevant. | |
2930 | |
2931 VAR_ALIAS_SET is the alias set for VAR. */ | |
2932 | |
2933 bool | |
2934 may_alias_p (tree ptr, alias_set_type mem_alias_set, | |
2935 tree var, alias_set_type var_alias_set, | |
2936 bool alias_set_only) | |
2937 { | |
2938 tree mem; | |
2939 | |
2940 alias_stats.alias_queries++; | |
2941 alias_stats.simple_queries++; | |
2942 | |
2943 /* By convention, a variable cannot alias itself. */ | |
2944 mem = symbol_mem_tag (ptr); | |
2945 if (mem == var) | |
2946 { | |
2947 alias_stats.alias_noalias++; | |
2948 alias_stats.simple_resolved++; | |
2949 return false; | |
2950 } | |
2951 | |
2952 /* If -fargument-noalias-global is > 2, pointer arguments may | |
2953 not point to anything else. */ | |
2954 if (flag_argument_noalias > 2 && TREE_CODE (ptr) == PARM_DECL) | |
2955 { | |
2956 alias_stats.alias_noalias++; | |
2957 alias_stats.simple_resolved++; | |
2958 return false; | |
2959 } | |
2960 | |
2961 /* If -fargument-noalias-global is > 1, pointer arguments may | |
2962 not point to global variables. */ | |
2963 if (flag_argument_noalias > 1 && is_global_var (var) | |
2964 && TREE_CODE (ptr) == PARM_DECL) | |
2965 { | |
2966 alias_stats.alias_noalias++; | |
2967 alias_stats.simple_resolved++; | |
2968 return false; | |
2969 } | |
2970 | |
2971 /* If the pointed to memory has alias set zero, or the pointer | |
2972 is ref-all, or the pointer decl is marked that no TBAA is to | |
2973 be applied, the MEM can alias VAR. */ | |
2974 if (mem_alias_set == 0 | |
2975 || DECL_POINTER_ALIAS_SET (ptr) == 0 | |
2976 || TYPE_REF_CAN_ALIAS_ALL (TREE_TYPE (ptr)) | |
2977 || DECL_NO_TBAA_P (ptr)) | |
2978 { | |
2979 alias_stats.alias_mayalias++; | |
2980 alias_stats.simple_resolved++; | |
2981 return true; | |
2982 } | |
2983 | |
2984 gcc_assert (TREE_CODE (mem) == SYMBOL_MEMORY_TAG); | |
2985 | |
2986 alias_stats.tbaa_queries++; | |
2987 | |
2988 /* If the alias sets don't conflict then MEM cannot alias VAR. */ | |
2989 if (mem_alias_set != var_alias_set | |
2990 && !alias_set_subset_of (mem_alias_set, var_alias_set)) | |
2991 { | |
2992 alias_stats.alias_noalias++; | |
2993 alias_stats.tbaa_resolved++; | |
2994 return false; | |
2995 } | |
2996 | |
2997 /* If VAR is a record or union type, PTR cannot point into VAR | |
2998 unless there is some explicit address operation in the | |
2999 program that can reference a field of the type pointed-to by | |
3000 PTR. This also assumes that the types of both VAR and PTR | |
3001 are contained within the compilation unit, and that there is | |
3002 no fancy addressing arithmetic associated with any of the | |
3003 types involved. */ | |
3004 if (mem_alias_set != 0 && var_alias_set != 0) | |
3005 { | |
3006 tree ptr_type = TREE_TYPE (ptr); | |
3007 tree var_type = TREE_TYPE (var); | |
3008 | |
3009 /* The star count is -1 if the type at the end of the | |
3010 pointer_to chain is not a record or union type. */ | |
3011 if (!alias_set_only && | |
3012 0 /* FIXME tuples ipa_type_escape_star_count_of_interesting_type (var_type) >= 0*/) | |
3013 { | |
3014 int ptr_star_count = 0; | |
3015 | |
3016 /* ipa_type_escape_star_count_of_interesting_type is a | |
3017 little too restrictive for the pointer type, need to | |
3018 allow pointers to primitive types as long as those | |
3019 types cannot be pointers to everything. */ | |
3020 while (POINTER_TYPE_P (ptr_type)) | |
3021 { | |
3022 /* Strip the *s off. */ | |
3023 ptr_type = TREE_TYPE (ptr_type); | |
3024 ptr_star_count++; | |
3025 } | |
3026 | |
3027 /* There does not appear to be a better test to see if | |
3028 the pointer type was one of the pointer to everything | |
3029 types. */ | |
3030 if (ptr_star_count > 0) | |
3031 { | |
3032 alias_stats.structnoaddress_queries++; | |
3033 if (ipa_type_escape_field_does_not_clobber_p (var_type, | |
3034 TREE_TYPE (ptr))) | |
3035 { | |
3036 alias_stats.structnoaddress_resolved++; | |
3037 alias_stats.alias_noalias++; | |
3038 return false; | |
3039 } | |
3040 } | |
3041 else if (ptr_star_count == 0) | |
3042 { | |
3043 /* If PTR_TYPE was not really a pointer to type, it cannot | |
3044 alias. */ | |
3045 alias_stats.structnoaddress_queries++; | |
3046 alias_stats.structnoaddress_resolved++; | |
3047 alias_stats.alias_noalias++; | |
3048 return false; | |
3049 } | |
3050 } | |
3051 } | |
3052 | |
3053 alias_stats.alias_mayalias++; | |
3054 return true; | |
3055 } | |
3056 | |
3057 /* Return true, if PTR may point to a global variable. */ | |
3058 | |
3059 bool | |
3060 may_point_to_global_var (tree ptr) | |
3061 { | |
3062 struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr); | |
3063 | |
3064 /* If we do not have points-to information for this variable, | |
3065 we have to punt. */ | |
3066 if (!pi | |
3067 || !pi->name_mem_tag) | |
3068 return true; | |
3069 | |
3070 /* The name memory tag is marked as global variable if the points-to | |
3071 set contains a global variable. */ | |
3072 return is_global_var (pi->name_mem_tag); | |
3073 } | |
3074 | |
3075 /* Add ALIAS to the set of variables that may alias VAR. */ | |
3076 | |
3077 static void | |
3078 add_may_alias (tree var, tree alias) | |
3079 { | |
3080 /* Don't allow self-referential aliases. */ | |
3081 gcc_assert (var != alias); | |
3082 | |
3083 /* ALIAS must be addressable if it's being added to an alias set. */ | |
3084 #if 1 | |
3085 TREE_ADDRESSABLE (alias) = 1; | |
3086 #else | |
3087 gcc_assert (may_be_aliased (alias)); | |
3088 #endif | |
3089 | |
3090 /* VAR must be a symbol or a name tag. */ | |
3091 gcc_assert (TREE_CODE (var) == SYMBOL_MEMORY_TAG | |
3092 || TREE_CODE (var) == NAME_MEMORY_TAG); | |
3093 | |
3094 if (MTAG_ALIASES (var) == NULL) | |
3095 MTAG_ALIASES (var) = BITMAP_ALLOC (&alias_bitmap_obstack); | |
3096 | |
3097 bitmap_set_bit (MTAG_ALIASES (var), DECL_UID (alias)); | |
3098 } | |
3099 | |
3100 | |
3101 /* Mark pointer PTR as pointing to an arbitrary memory location. */ | |
3102 | |
3103 static void | |
3104 set_pt_anything (tree ptr) | |
3105 { | |
3106 struct ptr_info_def *pi = get_ptr_info (ptr); | |
3107 | |
3108 pi->pt_anything = 1; | |
3109 /* Anything includes global memory. */ | |
3110 pi->pt_global_mem = 1; | |
3111 pi->pt_vars = NULL; | |
3112 | |
3113 /* The pointer used to have a name tag, but we now found it pointing | |
3114 to an arbitrary location. The name tag needs to be renamed and | |
3115 disassociated from PTR. */ | |
3116 if (pi->name_mem_tag) | |
3117 { | |
3118 mark_sym_for_renaming (pi->name_mem_tag); | |
3119 pi->name_mem_tag = NULL_TREE; | |
3120 } | |
3121 } | |
3122 | |
3123 | |
3124 /* Return true if STMT is an "escape" site from the current function. Escape | |
3125 sites those statements which might expose the address of a variable | |
3126 outside the current function. STMT is an escape site iff: | |
3127 | |
3128 1- STMT is a function call, or | |
3129 2- STMT is an __asm__ expression, or | |
3130 3- STMT is an assignment to a non-local variable, or | |
3131 4- STMT is a return statement. | |
3132 | |
3133 Return the type of escape site found, if we found one, or NO_ESCAPE | |
3134 if none. */ | |
3135 | |
3136 enum escape_type | |
3137 is_escape_site (gimple stmt) | |
3138 { | |
3139 if (is_gimple_call (stmt)) | |
3140 { | |
3141 if (gimple_call_flags (stmt) & (ECF_PURE | ECF_CONST)) | |
3142 return ESCAPE_TO_PURE_CONST; | |
3143 | |
3144 return ESCAPE_TO_CALL; | |
3145 } | |
3146 else if (gimple_code (stmt) == GIMPLE_ASM) | |
3147 return ESCAPE_TO_ASM; | |
3148 else if (is_gimple_assign (stmt)) | |
3149 { | |
3150 tree lhs = gimple_assign_lhs (stmt); | |
3151 | |
3152 /* Get to the base of _REF nodes. */ | |
3153 if (TREE_CODE (lhs) != SSA_NAME) | |
3154 lhs = get_base_address (lhs); | |
3155 | |
3156 /* If we couldn't recognize the LHS of the assignment, assume that it | |
3157 is a non-local store. */ | |
3158 if (lhs == NULL_TREE) | |
3159 return ESCAPE_UNKNOWN; | |
3160 | |
3161 if (gimple_assign_cast_p (stmt)) | |
3162 { | |
3163 tree from = TREE_TYPE (gimple_assign_rhs1 (stmt)); | |
3164 tree to = TREE_TYPE (lhs); | |
3165 | |
3166 /* If the RHS is a conversion between a pointer and an integer, the | |
3167 pointer escapes since we can't track the integer. */ | |
3168 if (POINTER_TYPE_P (from) && !POINTER_TYPE_P (to)) | |
3169 return ESCAPE_BAD_CAST; | |
3170 } | |
3171 | |
3172 /* If the LHS is an SSA name, it can't possibly represent a non-local | |
3173 memory store. */ | |
3174 if (TREE_CODE (lhs) == SSA_NAME) | |
3175 return NO_ESCAPE; | |
3176 | |
3177 /* If the LHS is a non-global decl, it isn't a non-local memory store. | |
3178 If the LHS escapes, the RHS escape is dealt with in the PTA solver. */ | |
3179 if (DECL_P (lhs) | |
3180 && !is_global_var (lhs)) | |
3181 return NO_ESCAPE; | |
3182 | |
3183 /* FIXME: LHS is not an SSA_NAME. Even if it's an assignment to a | |
3184 local variables we cannot be sure if it will escape, because we | |
3185 don't have information about objects not in SSA form. Need to | |
3186 implement something along the lines of | |
3187 | |
3188 J.-D. Choi, M. Gupta, M. J. Serrano, V. C. Sreedhar, and S. P. | |
3189 Midkiff, ``Escape analysis for java,'' in Proceedings of the | |
3190 Conference on Object-Oriented Programming Systems, Languages, and | |
3191 Applications (OOPSLA), pp. 1-19, 1999. */ | |
3192 return ESCAPE_STORED_IN_GLOBAL; | |
3193 } | |
3194 else if (gimple_code (stmt) == GIMPLE_RETURN) | |
3195 return ESCAPE_TO_RETURN; | |
3196 | |
3197 return NO_ESCAPE; | |
3198 } | |
3199 | |
3200 /* Create a new memory tag of type TYPE. | |
3201 Does NOT push it into the current binding. */ | |
3202 | |
3203 tree | |
3204 create_tag_raw (enum tree_code code, tree type, const char *prefix) | |
3205 { | |
3206 tree tmp_var; | |
3207 | |
3208 tmp_var = build_decl (code, create_tmp_var_name (prefix), type); | |
3209 | |
3210 /* Memory tags are always writable and non-static. */ | |
3211 TREE_READONLY (tmp_var) = 0; | |
3212 TREE_STATIC (tmp_var) = 0; | |
3213 | |
3214 /* It doesn't start out global. */ | |
3215 MTAG_GLOBAL (tmp_var) = 0; | |
3216 TREE_USED (tmp_var) = 1; | |
3217 | |
3218 return tmp_var; | |
3219 } | |
3220 | |
3221 /* Create a new memory tag of type TYPE. If IS_TYPE_TAG is true, the tag | |
3222 is considered to represent all the pointers whose pointed-to types are | |
3223 in the same alias set class. Otherwise, the tag represents a single | |
3224 SSA_NAME pointer variable. */ | |
3225 | |
3226 static tree | |
3227 create_memory_tag (tree type, bool is_type_tag) | |
3228 { | |
3229 tree tag = create_tag_raw (is_type_tag ? SYMBOL_MEMORY_TAG : NAME_MEMORY_TAG, | |
3230 type, (is_type_tag) ? "SMT" : "NMT"); | |
3231 | |
3232 /* By default, memory tags are local variables. Alias analysis will | |
3233 determine whether they should be considered globals. */ | |
3234 DECL_CONTEXT (tag) = current_function_decl; | |
3235 | |
3236 /* Memory tags are by definition addressable. */ | |
3237 TREE_ADDRESSABLE (tag) = 1; | |
3238 | |
3239 set_symbol_mem_tag (tag, NULL_TREE); | |
3240 | |
3241 /* Add the tag to the symbol table. */ | |
3242 add_referenced_var (tag); | |
3243 | |
3244 return tag; | |
3245 } | |
3246 | |
3247 | |
3248 /* Create a name memory tag to represent a specific SSA_NAME pointer P_i. | |
3249 This is used if P_i has been found to point to a specific set of | |
3250 variables or to a non-aliased memory location like the address returned | |
3251 by malloc functions. */ | |
3252 | |
3253 static tree | |
3254 get_nmt_for (tree ptr) | |
3255 { | |
3256 struct ptr_info_def *pi = get_ptr_info (ptr); | |
3257 tree tag = pi->name_mem_tag; | |
3258 | |
3259 if (tag == NULL_TREE) | |
3260 tag = create_memory_tag (TREE_TYPE (TREE_TYPE (ptr)), false); | |
3261 return tag; | |
3262 } | |
3263 | |
3264 | |
3265 /* Return the symbol memory tag associated to pointer PTR. A memory | |
3266 tag is an artificial variable that represents the memory location | |
3267 pointed-to by PTR. It is used to model the effects of pointer | |
3268 de-references on addressable variables. | |
3269 | |
3270 AI points to the data gathered during alias analysis. This | |
3271 function populates the array AI->POINTERS. */ | |
3272 | |
3273 static tree | |
3274 get_smt_for (tree ptr, struct alias_info *ai) | |
3275 { | |
3276 size_t i; | |
3277 tree tag; | |
3278 tree tag_type = TREE_TYPE (TREE_TYPE (ptr)); | |
3279 alias_set_type tag_set; | |
3280 | |
3281 /* Get the alias set to be used for the pointed-to memory. If that | |
3282 differs from what we would get from looking at the type adjust | |
3283 the tag_type to void to make sure we get a proper alias set from | |
3284 just looking at the SMT we create. */ | |
3285 tag_set = get_alias_set (tag_type); | |
3286 if (TYPE_REF_CAN_ALIAS_ALL (TREE_TYPE (ptr)) | |
3287 /* This is overly conservative but we do not want to assign | |
3288 restrict alias sets here (which if they are not assigned | |
3289 are -2 but still "known"). */ | |
3290 || DECL_POINTER_ALIAS_SET_KNOWN_P (ptr)) | |
3291 { | |
3292 tag_set = 0; | |
3293 tag_type = void_type_node; | |
3294 } | |
3295 | |
3296 /* To avoid creating unnecessary memory tags, only create one memory tag | |
3297 per alias set class. Note that it may be tempting to group | |
3298 memory tags based on conflicting alias sets instead of | |
3299 equivalence. That would be wrong because alias sets are not | |
3300 necessarily transitive (as demonstrated by the libstdc++ test | |
3301 23_containers/vector/cons/4.cc). Given three alias sets A, B, C | |
3302 such that conflicts (A, B) == true and conflicts (A, C) == true, | |
3303 it does not necessarily follow that conflicts (B, C) == true. */ | |
3304 for (i = 0, tag = NULL_TREE; i < ai->num_pointers; i++) | |
3305 { | |
3306 struct alias_map_d *curr = ai->pointers[i]; | |
3307 tree curr_tag = symbol_mem_tag (curr->var); | |
3308 if (tag_set == curr->set) | |
3309 { | |
3310 tag = curr_tag; | |
3311 break; | |
3312 } | |
3313 } | |
3314 | |
3315 /* If VAR cannot alias with any of the existing memory tags, create a new | |
3316 tag for PTR and add it to the POINTERS array. */ | |
3317 if (tag == NULL_TREE) | |
3318 { | |
3319 struct alias_map_d *alias_map; | |
3320 | |
3321 /* If PTR did not have a symbol tag already, create a new SMT.* | |
3322 artificial variable representing the memory location | |
3323 pointed-to by PTR. */ | |
3324 tag = symbol_mem_tag (ptr); | |
3325 if (tag == NULL_TREE | |
3326 || tag_set != get_alias_set (tag)) | |
3327 tag = create_memory_tag (tag_type, true); | |
3328 | |
3329 /* Add PTR to the POINTERS array. Note that we are not interested in | |
3330 PTR's alias set. Instead, we cache the alias set for the memory that | |
3331 PTR points to. */ | |
3332 alias_map = XCNEW (struct alias_map_d); | |
3333 alias_map->var = ptr; | |
3334 alias_map->set = tag_set; | |
3335 ai->pointers[ai->num_pointers++] = alias_map; | |
3336 } | |
3337 | |
3338 /* If the pointed-to type is volatile, so is the tag. */ | |
3339 TREE_THIS_VOLATILE (tag) |= TREE_THIS_VOLATILE (tag_type); | |
3340 | |
3341 /* Make sure that the symbol tag has the same alias set as the | |
3342 pointed-to type or at least accesses through the pointer will | |
3343 alias that set. The latter can happen after the vectorizer | |
3344 created pointers of vector type. */ | |
3345 gcc_assert (tag_set == get_alias_set (tag) | |
3346 || alias_set_subset_of (tag_set, get_alias_set (tag))); | |
3347 | |
3348 return tag; | |
3349 } | |
3350 | |
3351 | |
3352 /* Create GLOBAL_VAR, an artificial global variable to act as a | |
3353 representative of all the variables that may be clobbered by function | |
3354 calls. */ | |
3355 | |
3356 static void | |
3357 create_global_var (void) | |
3358 { | |
3359 tree global_var = build_decl (VAR_DECL, get_identifier (".GLOBAL_VAR"), | |
3360 void_type_node); | |
3361 DECL_ARTIFICIAL (global_var) = 1; | |
3362 TREE_READONLY (global_var) = 0; | |
3363 DECL_EXTERNAL (global_var) = 1; | |
3364 TREE_STATIC (global_var) = 1; | |
3365 TREE_USED (global_var) = 1; | |
3366 DECL_CONTEXT (global_var) = NULL_TREE; | |
3367 TREE_THIS_VOLATILE (global_var) = 0; | |
3368 TREE_ADDRESSABLE (global_var) = 0; | |
3369 | |
3370 create_var_ann (global_var); | |
3371 mark_call_clobbered (global_var, ESCAPE_UNKNOWN); | |
3372 add_referenced_var (global_var); | |
3373 mark_sym_for_renaming (global_var); | |
3374 cfun->gimple_df->global_var = global_var; | |
3375 } | |
3376 | |
3377 | |
3378 /* Dump alias statistics on FILE. */ | |
3379 | |
3380 static void | |
3381 dump_alias_stats (FILE *file) | |
3382 { | |
3383 const char *funcname | |
3384 = lang_hooks.decl_printable_name (current_function_decl, 2); | |
3385 fprintf (file, "\nAlias statistics for %s\n\n", funcname); | |
3386 fprintf (file, "Total alias queries:\t%u\n", alias_stats.alias_queries); | |
3387 fprintf (file, "Total alias mayalias results:\t%u\n", | |
3388 alias_stats.alias_mayalias); | |
3389 fprintf (file, "Total alias noalias results:\t%u\n", | |
3390 alias_stats.alias_noalias); | |
3391 fprintf (file, "Total simple queries:\t%u\n", | |
3392 alias_stats.simple_queries); | |
3393 fprintf (file, "Total simple resolved:\t%u\n", | |
3394 alias_stats.simple_resolved); | |
3395 fprintf (file, "Total TBAA queries:\t%u\n", | |
3396 alias_stats.tbaa_queries); | |
3397 fprintf (file, "Total TBAA resolved:\t%u\n", | |
3398 alias_stats.tbaa_resolved); | |
3399 fprintf (file, "Total non-addressable structure type queries:\t%u\n", | |
3400 alias_stats.structnoaddress_queries); | |
3401 fprintf (file, "Total non-addressable structure type resolved:\t%u\n", | |
3402 alias_stats.structnoaddress_resolved); | |
3403 } | |
3404 | |
3405 | |
3406 /* Dump alias information on FILE. */ | |
3407 | |
3408 void | |
3409 dump_alias_info (FILE *file) | |
3410 { | |
3411 size_t i; | |
3412 const char *funcname | |
3413 = lang_hooks.decl_printable_name (current_function_decl, 2); | |
3414 referenced_var_iterator rvi; | |
3415 tree var; | |
3416 | |
3417 fprintf (file, "\nAlias information for %s\n\n", funcname); | |
3418 | |
3419 dump_memory_partitions (file); | |
3420 | |
3421 fprintf (file, "\nFlow-insensitive alias information for %s\n\n", funcname); | |
3422 | |
3423 fprintf (file, "Aliased symbols\n\n"); | |
3424 | |
3425 FOR_EACH_REFERENCED_VAR (var, rvi) | |
3426 { | |
3427 if (may_be_aliased (var)) | |
3428 dump_variable (file, var); | |
3429 } | |
3430 | |
3431 fprintf (file, "\nDereferenced pointers\n\n"); | |
3432 | |
3433 FOR_EACH_REFERENCED_VAR (var, rvi) | |
3434 if (symbol_mem_tag (var)) | |
3435 dump_variable (file, var); | |
3436 | |
3437 fprintf (file, "\nSymbol memory tags\n\n"); | |
3438 | |
3439 FOR_EACH_REFERENCED_VAR (var, rvi) | |
3440 { | |
3441 if (TREE_CODE (var) == SYMBOL_MEMORY_TAG) | |
3442 dump_variable (file, var); | |
3443 } | |
3444 | |
3445 fprintf (file, "\n\nFlow-sensitive alias information for %s\n\n", funcname); | |
3446 | |
3447 fprintf (file, "SSA_NAME pointers\n\n"); | |
3448 for (i = 1; i < num_ssa_names; i++) | |
3449 { | |
3450 tree ptr = ssa_name (i); | |
3451 struct ptr_info_def *pi; | |
3452 | |
3453 if (ptr == NULL_TREE) | |
3454 continue; | |
3455 | |
3456 pi = SSA_NAME_PTR_INFO (ptr); | |
3457 if (!SSA_NAME_IN_FREE_LIST (ptr) | |
3458 && pi | |
3459 && pi->name_mem_tag) | |
3460 dump_points_to_info_for (file, ptr); | |
3461 } | |
3462 | |
3463 fprintf (file, "\nName memory tags\n\n"); | |
3464 | |
3465 FOR_EACH_REFERENCED_VAR (var, rvi) | |
3466 { | |
3467 if (TREE_CODE (var) == NAME_MEMORY_TAG) | |
3468 dump_variable (file, var); | |
3469 } | |
3470 | |
3471 fprintf (file, "\n"); | |
3472 } | |
3473 | |
3474 | |
3475 /* Dump alias information on stderr. */ | |
3476 | |
3477 void | |
3478 debug_alias_info (void) | |
3479 { | |
3480 dump_alias_info (stderr); | |
3481 } | |
3482 | |
3483 | |
3484 /* Return the alias information associated with pointer T. It creates a | |
3485 new instance if none existed. */ | |
3486 | |
3487 struct ptr_info_def * | |
3488 get_ptr_info (tree t) | |
3489 { | |
3490 struct ptr_info_def *pi; | |
3491 | |
3492 gcc_assert (POINTER_TYPE_P (TREE_TYPE (t))); | |
3493 | |
3494 pi = SSA_NAME_PTR_INFO (t); | |
3495 if (pi == NULL) | |
3496 { | |
3497 pi = GGC_CNEW (struct ptr_info_def); | |
3498 SSA_NAME_PTR_INFO (t) = pi; | |
3499 } | |
3500 | |
3501 return pi; | |
3502 } | |
3503 | |
3504 /* Dump points-to information for SSA_NAME PTR into FILE. */ | |
3505 | |
3506 void | |
3507 dump_points_to_info_for (FILE *file, tree ptr) | |
3508 { | |
3509 struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr); | |
3510 | |
3511 print_generic_expr (file, ptr, dump_flags); | |
3512 | |
3513 if (pi) | |
3514 { | |
3515 if (pi->name_mem_tag) | |
3516 { | |
3517 fprintf (file, ", name memory tag: "); | |
3518 print_generic_expr (file, pi->name_mem_tag, dump_flags); | |
3519 } | |
3520 | |
3521 if (pi->is_dereferenced) | |
3522 fprintf (file, ", is dereferenced"); | |
3523 else if (pi->memory_tag_needed) | |
3524 fprintf (file, ", is dereferenced in call"); | |
3525 | |
3526 if (pi->value_escapes_p) | |
3527 fprintf (file, ", its value escapes"); | |
3528 | |
3529 if (pi->pt_anything) | |
3530 fprintf (file, ", points-to anything"); | |
3531 | |
3532 if (pi->pt_null) | |
3533 fprintf (file, ", points-to NULL"); | |
3534 | |
3535 if (pi->pt_vars) | |
3536 { | |
3537 fprintf (file, ", points-to vars: "); | |
3538 dump_decl_set (file, pi->pt_vars); | |
3539 } | |
3540 } | |
3541 | |
3542 fprintf (file, "\n"); | |
3543 } | |
3544 | |
3545 | |
3546 /* Dump points-to information for VAR into stderr. */ | |
3547 | |
3548 void | |
3549 debug_points_to_info_for (tree var) | |
3550 { | |
3551 dump_points_to_info_for (stderr, var); | |
3552 } | |
3553 | |
3554 | |
3555 /* Dump points-to information into FILE. NOTE: This function is slow, as | |
3556 it needs to traverse the whole CFG looking for pointer SSA_NAMEs. */ | |
3557 | |
3558 void | |
3559 dump_points_to_info (FILE *file ATTRIBUTE_UNUSED) | |
3560 { | |
3561 basic_block bb; | |
3562 gimple_stmt_iterator si; | |
3563 ssa_op_iter iter; | |
3564 const char *fname = | |
3565 lang_hooks.decl_printable_name (current_function_decl, 2); | |
3566 referenced_var_iterator rvi; | |
3567 tree var; | |
3568 | |
3569 fprintf (file, "\n\nPointed-to sets for pointers in %s\n\n", fname); | |
3570 | |
3571 /* First dump points-to information for the default definitions of | |
3572 pointer variables. This is necessary because default definitions are | |
3573 not part of the code. */ | |
3574 FOR_EACH_REFERENCED_VAR (var, rvi) | |
3575 { | |
3576 if (POINTER_TYPE_P (TREE_TYPE (var))) | |
3577 { | |
3578 tree def = gimple_default_def (cfun, var); | |
3579 if (def) | |
3580 dump_points_to_info_for (file, def); | |
3581 } | |
3582 } | |
3583 | |
3584 /* Dump points-to information for every pointer defined in the program. */ | |
3585 FOR_EACH_BB (bb) | |
3586 { | |
3587 for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si)) | |
3588 { | |
3589 gimple phi = gsi_stmt (si); | |
3590 tree ptr = PHI_RESULT (phi); | |
3591 if (POINTER_TYPE_P (TREE_TYPE (ptr))) | |
3592 dump_points_to_info_for (file, ptr); | |
3593 } | |
3594 | |
3595 for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si)) | |
3596 { | |
3597 gimple stmt = gsi_stmt (si); | |
3598 tree def; | |
3599 FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF) | |
3600 if (TREE_CODE (def) == SSA_NAME | |
3601 && POINTER_TYPE_P (TREE_TYPE (def))) | |
3602 dump_points_to_info_for (file, def); | |
3603 } | |
3604 } | |
3605 | |
3606 fprintf (file, "\n"); | |
3607 } | |
3608 | |
3609 | |
3610 /* Dump points-to info pointed to by PTO into STDERR. */ | |
3611 | |
3612 void | |
3613 debug_points_to_info (void) | |
3614 { | |
3615 dump_points_to_info (stderr); | |
3616 } | |
3617 | |
3618 /* Dump to FILE the list of variables that may be aliasing VAR. */ | |
3619 | |
3620 void | |
3621 dump_may_aliases_for (FILE *file, tree var) | |
3622 { | |
3623 bitmap aliases; | |
3624 | |
3625 aliases = MTAG_ALIASES (var); | |
3626 if (aliases) | |
3627 { | |
3628 bitmap_iterator bi; | |
3629 unsigned int i; | |
3630 tree al; | |
3631 | |
3632 fprintf (file, "{ "); | |
3633 EXECUTE_IF_SET_IN_BITMAP (aliases, 0, i, bi) | |
3634 { | |
3635 al = referenced_var (i); | |
3636 print_generic_expr (file, al, dump_flags); | |
3637 fprintf (file, " "); | |
3638 } | |
3639 fprintf (file, "}"); | |
3640 } | |
3641 } | |
3642 | |
3643 | |
3644 /* Dump to stderr the list of variables that may be aliasing VAR. */ | |
3645 | |
3646 void | |
3647 debug_may_aliases_for (tree var) | |
3648 { | |
3649 dump_may_aliases_for (stderr, var); | |
3650 } | |
3651 | |
3652 /* Return true if VAR may be aliased. */ | |
3653 | |
3654 bool | |
3655 may_be_aliased (tree var) | |
3656 { | |
3657 /* Obviously. */ | |
3658 if (TREE_ADDRESSABLE (var)) | |
3659 return true; | |
3660 | |
3661 /* Globally visible variables can have their addresses taken by other | |
3662 translation units. */ | |
3663 if (MTAG_P (var) | |
3664 && MTAG_GLOBAL (var)) | |
3665 return true; | |
3666 else if (!MTAG_P (var) | |
3667 && (DECL_EXTERNAL (var) || TREE_PUBLIC (var))) | |
3668 return true; | |
3669 | |
3670 /* Automatic variables can't have their addresses escape any other | |
3671 way. This must be after the check for global variables, as | |
3672 extern declarations do not have TREE_STATIC set. */ | |
3673 if (!TREE_STATIC (var)) | |
3674 return false; | |
3675 | |
3676 return false; | |
3677 } | |
3678 | |
3679 /* The following is based on code in add_stmt_operand to ensure that the | |
3680 same defs/uses/vdefs/vuses will be found after replacing a reference | |
3681 to var (or ARRAY_REF to var) with an INDIRECT_REF to ptr whose value | |
3682 is the address of var. Return a memtag for the ptr, after adding the | |
3683 proper may_aliases to it (which are the aliases of var, if it has any, | |
3684 or var itself). */ | |
3685 | |
3686 static tree | |
3687 add_may_alias_for_new_tag (tree tag, tree var) | |
3688 { | |
3689 bitmap aliases = NULL; | |
3690 | |
3691 if (MTAG_P (var)) | |
3692 aliases = may_aliases (var); | |
3693 | |
3694 /* Case 1: |aliases| == 1 */ | |
3695 if (aliases | |
3696 && bitmap_single_bit_set_p (aliases)) | |
3697 { | |
3698 tree ali = referenced_var (bitmap_first_set_bit (aliases)); | |
3699 if (TREE_CODE (ali) == SYMBOL_MEMORY_TAG) | |
3700 return ali; | |
3701 } | |
3702 | |
3703 /* Case 2: |aliases| == 0 */ | |
3704 if (aliases == NULL) | |
3705 add_may_alias (tag, var); | |
3706 else | |
3707 { | |
3708 /* Case 3: |aliases| > 1 */ | |
3709 union_alias_set_into (tag, aliases); | |
3710 } | |
3711 return tag; | |
3712 } | |
3713 | |
3714 /* Create a new symbol tag for PTR. Construct the may-alias list of | |
3715 this type tag so that it has the aliasing of VAR according to the | |
3716 location accessed by EXPR. | |
3717 | |
3718 Note, the set of aliases represented by the new symbol tag are not | |
3719 marked for renaming. */ | |
3720 | |
3721 void | |
3722 new_type_alias (tree ptr, tree var, tree expr) | |
3723 { | |
3724 tree tag_type = TREE_TYPE (TREE_TYPE (ptr)); | |
3725 tree tag; | |
3726 tree ali = NULL_TREE; | |
3727 HOST_WIDE_INT offset, size, maxsize; | |
3728 tree ref; | |
3729 | |
3730 gcc_assert (symbol_mem_tag (ptr) == NULL_TREE); | |
3731 gcc_assert (!MTAG_P (var)); | |
3732 | |
3733 ref = get_ref_base_and_extent (expr, &offset, &size, &maxsize); | |
3734 gcc_assert (ref); | |
3735 | |
3736 tag = create_memory_tag (tag_type, true); | |
3737 set_symbol_mem_tag (ptr, tag); | |
3738 | |
3739 ali = add_may_alias_for_new_tag (tag, var); | |
3740 | |
3741 set_symbol_mem_tag (ptr, ali); | |
3742 MTAG_GLOBAL (tag) = is_global_var (var); | |
3743 } | |
3744 | |
3745 | |
3746 /* Reset the call_clobbered flags on our referenced vars. In | |
3747 theory, this only needs to be done for globals. */ | |
3748 | |
3749 static unsigned int | |
3750 reset_cc_flags (void) | |
3751 { | |
3752 tree var; | |
3753 referenced_var_iterator rvi; | |
3754 | |
3755 FOR_EACH_REFERENCED_VAR (var, rvi) | |
3756 var_ann (var)->call_clobbered = false; | |
3757 return 0; | |
3758 } | |
3759 | |
3760 struct gimple_opt_pass pass_reset_cc_flags = | |
3761 { | |
3762 { | |
3763 GIMPLE_PASS, | |
3764 NULL, /* name */ | |
3765 NULL, /* gate */ | |
3766 reset_cc_flags, /* execute */ | |
3767 NULL, /* sub */ | |
3768 NULL, /* next */ | |
3769 0, /* static_pass_number */ | |
3770 0, /* tv_id */ | |
3771 PROP_referenced_vars |PROP_cfg, /* properties_required */ | |
3772 0, /* properties_provided */ | |
3773 0, /* properties_destroyed */ | |
3774 0, /* todo_flags_start */ | |
3775 0 /* todo_flags_finish */ | |
3776 } | |
3777 }; | |
3778 | |
3779 | |
3780 /* A dummy pass to cause aliases to be computed via TODO_rebuild_alias. */ | |
3781 | |
3782 struct gimple_opt_pass pass_build_alias = | |
3783 { | |
3784 { | |
3785 GIMPLE_PASS, | |
3786 "alias", /* name */ | |
3787 NULL, /* gate */ | |
3788 NULL, /* execute */ | |
3789 NULL, /* sub */ | |
3790 NULL, /* next */ | |
3791 0, /* static_pass_number */ | |
3792 0, /* tv_id */ | |
3793 PROP_cfg | PROP_ssa, /* properties_required */ | |
3794 PROP_alias, /* properties_provided */ | |
3795 0, /* properties_destroyed */ | |
3796 0, /* todo_flags_start */ | |
3797 TODO_rebuild_alias | TODO_dump_func /* todo_flags_finish */ | |
3798 } | |
3799 }; |