00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "config.h"
00023 #include "system.h"
00024 #include "coretypes.h"
00025 #include "tm.h"
00026 #include "tree.h"
00027 #include "rtl.h"
00028 #include "tm_p.h"
00029 #include "hard-reg-set.h"
00030 #include "basic-block.h"
00031 #include "timevar.h"
00032 #include "expr.h"
00033 #include "ggc.h"
00034 #include "langhooks.h"
00035 #include "flags.h"
00036 #include "function.h"
00037 #include "diagnostic.h"
00038 #include "tree-dump.h"
00039 #include "tree-gimple.h"
00040 #include "tree-flow.h"
00041 #include "tree-inline.h"
00042 #include "tree-pass.h"
00043 #include "convert.h"
00044 #include "params.h"
00045
00046
00047 bool aliases_computed_p;
00048
00049
00050
00051 struct alias_map_d
00052 {
00053
00054 tree var;
00055 HOST_WIDE_INT set;
00056
00057
00058
00059 long total_alias_vops;
00060
00061
00062
00063 unsigned int grouped_p : 1;
00064
00065
00066
00067
00068 sbitmap may_aliases;
00069 };
00070
00071
00072
00073 struct alias_info
00074 {
00075
00076
00077
00078 sbitmap ssa_names_visited;
00079
00080
00081 varray_type processed_ptrs;
00082
00083
00084 bitmap addresses_needed;
00085
00086
00087
00088 struct alias_map_d **addressable_vars;
00089 size_t num_addressable_vars;
00090
00091
00092
00093 struct alias_map_d **pointers;
00094 size_t num_pointers;
00095
00096
00097 size_t num_calls_found;
00098
00099
00100 size_t num_pure_const_calls_found;
00101
00102
00103
00104
00105 varray_type num_references;
00106
00107
00108
00109 long total_alias_vops;
00110
00111
00112 bitmap written_vars;
00113
00114
00115 bitmap dereferenced_ptrs_store;
00116
00117
00118 bitmap dereferenced_ptrs_load;
00119 };
00120
00121
00122
00123 struct alias_stats_d
00124 {
00125 unsigned int alias_queries;
00126 unsigned int alias_mayalias;
00127 unsigned int alias_noalias;
00128 unsigned int simple_queries;
00129 unsigned int simple_resolved;
00130 unsigned int tbaa_queries;
00131 unsigned int tbaa_resolved;
00132 };
00133
00134
00135
00136 static struct alias_stats_d alias_stats;
00137
00138
00139 static void compute_flow_insensitive_aliasing (struct alias_info *);
00140 static void dump_alias_stats (FILE *);
00141 static bool may_alias_p (tree, HOST_WIDE_INT, tree, HOST_WIDE_INT);
00142 static tree create_memory_tag (tree type, bool is_type_tag);
00143 static tree get_tmt_for (tree, struct alias_info *);
00144 static tree get_nmt_for (tree);
00145 static void add_may_alias (tree, tree);
00146 static void replace_may_alias (tree, size_t, tree);
00147 static struct alias_info *init_alias_info (void);
00148 static void delete_alias_info (struct alias_info *);
00149 static void compute_points_to_and_addr_escape (struct alias_info *);
00150 static void compute_flow_sensitive_aliasing (struct alias_info *);
00151 static void setup_pointers_and_addressables (struct alias_info *);
00152 static bool collect_points_to_info_r (tree, tree, void *);
00153 static bool is_escape_site (tree, struct alias_info *);
00154 static void add_pointed_to_var (struct alias_info *, tree, tree);
00155 static void create_global_var (void);
00156 static void collect_points_to_info_for (struct alias_info *, tree);
00157 static void maybe_create_global_var (struct alias_info *ai);
00158 static void group_aliases (struct alias_info *);
00159 static void set_pt_anything (tree ptr);
00160 static void set_pt_malloc (tree ptr);
00161
00162
00163
00164
00165
00166 bitmap call_clobbered_vars;
00167
00168
00169
00170
00171
00172
00173
00174
00175 bitmap addressable_vars;
00176
00177
00178
00179
00180
00181
00182 tree global_var;
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294 static void
00295 compute_may_aliases (void)
00296 {
00297 struct alias_info *ai;
00298
00299 memset (&alias_stats, 0, sizeof (alias_stats));
00300
00301
00302 ai = init_alias_info ();
00303
00304
00305
00306
00307
00308
00309 compute_points_to_and_addr_escape (ai);
00310
00311
00312
00313
00314 setup_pointers_and_addressables (ai);
00315
00316
00317
00318
00319
00320 compute_flow_sensitive_aliasing (ai);
00321
00322
00323
00324 compute_flow_insensitive_aliasing (ai);
00325
00326
00327
00328
00329
00330
00331 maybe_create_global_var (ai);
00332
00333
00334 if (dump_file)
00335 {
00336 dump_referenced_vars (dump_file);
00337 if (dump_flags & TDF_STATS)
00338 dump_alias_stats (dump_file);
00339 dump_points_to_info (dump_file);
00340 dump_alias_info (dump_file);
00341 }
00342
00343
00344 delete_alias_info (ai);
00345 }
00346
00347 struct tree_opt_pass pass_may_alias =
00348 {
00349 "alias",
00350 NULL,
00351 compute_may_aliases,
00352 NULL,
00353 NULL,
00354 0,
00355 TV_TREE_MAY_ALIAS,
00356 PROP_cfg | PROP_ssa,
00357 PROP_alias,
00358 0,
00359 0,
00360 TODO_dump_func | TODO_rename_vars
00361 | TODO_ggc_collect | TODO_verify_ssa
00362 | TODO_verify_stmts,
00363 0
00364 };
00365
00366
00367
00368
00369 struct count_ptr_d
00370 {
00371 tree ptr;
00372 unsigned count;
00373 };
00374
00375
00376
00377
00378
00379 static tree
00380 count_ptr_derefs (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, void *data)
00381 {
00382 struct count_ptr_d *count_p = (struct count_ptr_d *) data;
00383
00384 if (INDIRECT_REF_P (*tp) && TREE_OPERAND (*tp, 0) == count_p->ptr)
00385 count_p->count++;
00386
00387 return NULL_TREE;
00388 }
00389
00390
00391
00392
00393
00394
00395
00396 static void
00397 count_uses_and_derefs (tree ptr, tree stmt, unsigned *num_uses_p,
00398 unsigned *num_derefs_p, bool *is_store)
00399 {
00400 ssa_op_iter i;
00401 tree use;
00402
00403 *num_uses_p = 0;
00404 *num_derefs_p = 0;
00405 *is_store = false;
00406
00407
00408 FOR_EACH_SSA_TREE_OPERAND (use, stmt, i, SSA_OP_USE)
00409 if (use == ptr)
00410 (*num_uses_p)++;
00411
00412
00413
00414
00415
00416
00417
00418
00419 if (TREE_CODE (stmt) == MODIFY_EXPR
00420 || (TREE_CODE (stmt) == RETURN_EXPR
00421 && TREE_CODE (TREE_OPERAND (stmt, 0)) == MODIFY_EXPR)
00422 || TREE_CODE (stmt) == ASM_EXPR
00423 || TREE_CODE (stmt) == CALL_EXPR)
00424 {
00425 tree lhs, rhs;
00426
00427 if (TREE_CODE (stmt) == MODIFY_EXPR)
00428 {
00429 lhs = TREE_OPERAND (stmt, 0);
00430 rhs = TREE_OPERAND (stmt, 1);
00431 }
00432 else if (TREE_CODE (stmt) == RETURN_EXPR)
00433 {
00434 tree e = TREE_OPERAND (stmt, 0);
00435 lhs = TREE_OPERAND (e, 0);
00436 rhs = TREE_OPERAND (e, 1);
00437 }
00438 else if (TREE_CODE (stmt) == ASM_EXPR)
00439 {
00440 lhs = ASM_OUTPUTS (stmt);
00441 rhs = ASM_INPUTS (stmt);
00442 }
00443 else
00444 {
00445 lhs = NULL_TREE;
00446 rhs = stmt;
00447 }
00448
00449 if (lhs && (TREE_CODE (lhs) == TREE_LIST || EXPR_P (lhs)))
00450 {
00451 struct count_ptr_d count;
00452 count.ptr = ptr;
00453 count.count = 0;
00454 walk_tree (&lhs, count_ptr_derefs, &count, NULL);
00455 *is_store = true;
00456 *num_derefs_p = count.count;
00457 }
00458
00459 if (rhs && (TREE_CODE (rhs) == TREE_LIST || EXPR_P (rhs)))
00460 {
00461 struct count_ptr_d count;
00462 count.ptr = ptr;
00463 count.count = 0;
00464 walk_tree (&rhs, count_ptr_derefs, &count, NULL);
00465 *num_derefs_p += count.count;
00466 }
00467 }
00468
00469 gcc_assert (*num_uses_p >= *num_derefs_p);
00470 }
00471
00472
00473
00474
00475 static struct alias_info *
00476 init_alias_info (void)
00477 {
00478 struct alias_info *ai;
00479
00480 ai = xcalloc (1, sizeof (struct alias_info));
00481 ai->ssa_names_visited = sbitmap_alloc (num_ssa_names);
00482 sbitmap_zero (ai->ssa_names_visited);
00483 VARRAY_TREE_INIT (ai->processed_ptrs, 50, "processed_ptrs");
00484 ai->addresses_needed = BITMAP_ALLOC (NULL);
00485 VARRAY_UINT_INIT (ai->num_references, num_referenced_vars, "num_references");
00486 ai->written_vars = BITMAP_ALLOC (NULL);
00487 ai->dereferenced_ptrs_store = BITMAP_ALLOC (NULL);
00488 ai->dereferenced_ptrs_load = BITMAP_ALLOC (NULL);
00489
00490
00491 if (aliases_computed_p)
00492 {
00493 unsigned i;
00494 basic_block bb;
00495
00496
00497
00498
00499
00500
00501
00502 FOR_EACH_BB (bb)
00503 {
00504 block_stmt_iterator si;
00505 for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
00506 get_stmt_operands (bsi_stmt (si));
00507 }
00508
00509
00510
00511
00512 bitmap_clear (addressable_vars);
00513
00514
00515 for (i = 0; i < num_referenced_vars; i++)
00516 {
00517 tree var = referenced_var (i);
00518 var_ann_t ann = var_ann (var);
00519
00520 ann->is_alias_tag = 0;
00521 ann->may_aliases = NULL;
00522
00523
00524
00525
00526
00527
00528 if (ann->mem_tag_kind != NOT_A_TAG || !is_global_var (var))
00529 clear_call_clobbered (var);
00530 }
00531
00532
00533 for (i = 1; i < num_ssa_names; i++)
00534 {
00535 tree name = ssa_name (i);
00536
00537 if (!name || !POINTER_TYPE_P (TREE_TYPE (name)))
00538 continue;
00539
00540 if (SSA_NAME_PTR_INFO (name))
00541 {
00542 struct ptr_info_def *pi = SSA_NAME_PTR_INFO (name);
00543
00544
00545
00546
00547
00548
00549 pi->pt_anything = 0;
00550 pi->pt_malloc = 0;
00551 pi->pt_null = 0;
00552 pi->value_escapes_p = 0;
00553 pi->is_dereferenced = 0;
00554 if (pi->pt_vars)
00555 bitmap_clear (pi->pt_vars);
00556 }
00557 }
00558 }
00559
00560
00561 aliases_computed_p = true;
00562
00563 return ai;
00564 }
00565
00566
00567
00568
00569 static void
00570 delete_alias_info (struct alias_info *ai)
00571 {
00572 size_t i;
00573
00574 sbitmap_free (ai->ssa_names_visited);
00575 ai->processed_ptrs = NULL;
00576 BITMAP_FREE (ai->addresses_needed);
00577
00578 for (i = 0; i < ai->num_addressable_vars; i++)
00579 {
00580 sbitmap_free (ai->addressable_vars[i]->may_aliases);
00581 free (ai->addressable_vars[i]);
00582 }
00583 free (ai->addressable_vars);
00584
00585 for (i = 0; i < ai->num_pointers; i++)
00586 {
00587 sbitmap_free (ai->pointers[i]->may_aliases);
00588 free (ai->pointers[i]);
00589 }
00590 free (ai->pointers);
00591
00592 ai->num_references = NULL;
00593 BITMAP_FREE (ai->written_vars);
00594 BITMAP_FREE (ai->dereferenced_ptrs_store);
00595 BITMAP_FREE (ai->dereferenced_ptrs_load);
00596
00597 free (ai);
00598 }
00599
00600
00601
00602
00603
00604 static void
00605 collect_points_to_info_for (struct alias_info *ai, tree ptr)
00606 {
00607 gcc_assert (POINTER_TYPE_P (TREE_TYPE (ptr)));
00608
00609 if (!TEST_BIT (ai->ssa_names_visited, SSA_NAME_VERSION (ptr)))
00610 {
00611 SET_BIT (ai->ssa_names_visited, SSA_NAME_VERSION (ptr));
00612 walk_use_def_chains (ptr, collect_points_to_info_r, ai, true);
00613 VARRAY_PUSH_TREE (ai->processed_ptrs, ptr);
00614 }
00615 }
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626 static void
00627 compute_points_to_and_addr_escape (struct alias_info *ai)
00628 {
00629 basic_block bb;
00630 unsigned i;
00631 tree op;
00632 ssa_op_iter iter;
00633
00634 timevar_push (TV_TREE_PTA);
00635
00636 FOR_EACH_BB (bb)
00637 {
00638 bb_ann_t block_ann = bb_ann (bb);
00639 block_stmt_iterator si;
00640
00641 for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
00642 {
00643 bitmap addr_taken;
00644 tree stmt = bsi_stmt (si);
00645 bool stmt_escapes_p = is_escape_site (stmt, ai);
00646 bitmap_iterator bi;
00647
00648
00649
00650
00651
00652 get_stmt_operands (stmt);
00653 addr_taken = addresses_taken (stmt);
00654 if (addr_taken)
00655 EXECUTE_IF_SET_IN_BITMAP (addr_taken, 0, i, bi)
00656 {
00657 tree var = referenced_var (i);
00658 bitmap_set_bit (ai->addresses_needed, var_ann (var)->uid);
00659 if (stmt_escapes_p)
00660 mark_call_clobbered (var);
00661 }
00662
00663 if (stmt_escapes_p)
00664 block_ann->has_escape_site = 1;
00665
00666 FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE)
00667 {
00668 var_ann_t v_ann = var_ann (SSA_NAME_VAR (op));
00669 struct ptr_info_def *pi;
00670 bool is_store;
00671 unsigned num_uses, num_derefs;
00672
00673
00674
00675
00676
00677
00678
00679
00680 if (may_be_aliased (SSA_NAME_VAR (op)))
00681 (VARRAY_UINT (ai->num_references, v_ann->uid))++;
00682
00683 if (!POINTER_TYPE_P (TREE_TYPE (op)))
00684 continue;
00685
00686 collect_points_to_info_for (ai, op);
00687
00688 pi = SSA_NAME_PTR_INFO (op);
00689 count_uses_and_derefs (op, stmt, &num_uses, &num_derefs,
00690 &is_store);
00691
00692 if (num_derefs > 0)
00693 {
00694
00695
00696
00697
00698 pi->is_dereferenced = 1;
00699
00700
00701
00702
00703
00704 (VARRAY_UINT (ai->num_references, v_ann->uid))++;
00705
00706
00707
00708
00709 if (is_store)
00710 bitmap_set_bit (ai->dereferenced_ptrs_store, v_ann->uid);
00711 else
00712 bitmap_set_bit (ai->dereferenced_ptrs_load, v_ann->uid);
00713 }
00714
00715 if (stmt_escapes_p && num_derefs < num_uses)
00716 {
00717
00718
00719
00720
00721 pi->value_escapes_p = 1;
00722
00723
00724
00725
00726 if (get_call_expr_in (stmt))
00727 {
00728 bitmap_set_bit (ai->dereferenced_ptrs_store, v_ann->uid);
00729 pi->is_dereferenced = 1;
00730 }
00731 }
00732 }
00733
00734
00735
00736
00737 FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_DEF)
00738 {
00739 tree var = SSA_NAME_VAR (op);
00740 var_ann_t ann = var_ann (var);
00741 bitmap_set_bit (ai->written_vars, ann->uid);
00742 if (may_be_aliased (var))
00743 (VARRAY_UINT (ai->num_references, ann->uid))++;
00744
00745 if (POINTER_TYPE_P (TREE_TYPE (op)))
00746 collect_points_to_info_for (ai, op);
00747 }
00748
00749
00750 FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_VIRTUAL_DEFS)
00751 {
00752 tree var = SSA_NAME_VAR (op);
00753 var_ann_t ann = var_ann (var);
00754 bitmap_set_bit (ai->written_vars, ann->uid);
00755 }
00756
00757
00758
00759
00760
00761 modify_stmt (stmt);
00762 }
00763 }
00764
00765 timevar_pop (TV_TREE_PTA);
00766 }
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778 static void
00779 create_name_tags (struct alias_info *ai)
00780 {
00781 size_t i;
00782
00783 for (i = 0; i < VARRAY_ACTIVE_SIZE (ai->processed_ptrs); i++)
00784 {
00785 tree ptr = VARRAY_TREE (ai->processed_ptrs, i);
00786 struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr);
00787
00788 if (pi->pt_anything || !pi->is_dereferenced)
00789 {
00790
00791
00792 pi->name_mem_tag = NULL_TREE;
00793 continue;
00794 }
00795
00796 if (pi->pt_vars && !bitmap_empty_p (pi->pt_vars))
00797 {
00798 size_t j;
00799 tree old_name_tag = pi->name_mem_tag;
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812 for (j = 0; j < i; j++)
00813 {
00814 tree q = VARRAY_TREE (ai->processed_ptrs, j);
00815 struct ptr_info_def *qi = SSA_NAME_PTR_INFO (q);
00816
00817 if (qi
00818 && qi->pt_vars
00819 && qi->name_mem_tag
00820 && bitmap_equal_p (pi->pt_vars, qi->pt_vars))
00821 {
00822 pi->name_mem_tag = qi->name_mem_tag;
00823 break;
00824 }
00825 }
00826
00827
00828
00829 if (pi->name_mem_tag == NULL_TREE)
00830 pi->name_mem_tag = get_nmt_for (ptr);
00831
00832
00833
00834
00835
00836 if (old_name_tag && old_name_tag != pi->name_mem_tag)
00837 bitmap_set_bit (vars_to_rename, var_ann (old_name_tag)->uid);
00838 }
00839 else if (pi->pt_malloc)
00840 {
00841
00842 pi->name_mem_tag = get_nmt_for (ptr);
00843 }
00844 else
00845 {
00846
00847
00848
00849 set_pt_anything (ptr);
00850 continue;
00851 }
00852
00853 TREE_THIS_VOLATILE (pi->name_mem_tag)
00854 |= TREE_THIS_VOLATILE (TREE_TYPE (TREE_TYPE (ptr)));
00855
00856
00857 bitmap_set_bit (vars_to_rename, var_ann (pi->name_mem_tag)->uid);
00858 }
00859 }
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871 static void
00872 compute_flow_sensitive_aliasing (struct alias_info *ai)
00873 {
00874 size_t i;
00875
00876 create_name_tags (ai);
00877
00878 for (i = 0; i < VARRAY_ACTIVE_SIZE (ai->processed_ptrs); i++)
00879 {
00880 unsigned j;
00881 tree ptr = VARRAY_TREE (ai->processed_ptrs, i);
00882 struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr);
00883 var_ann_t v_ann = var_ann (SSA_NAME_VAR (ptr));
00884 bitmap_iterator bi;
00885
00886 if (pi->value_escapes_p || pi->pt_anything)
00887 {
00888
00889
00890 if (pi->name_mem_tag)
00891 mark_call_clobbered (pi->name_mem_tag);
00892
00893 if (v_ann->type_mem_tag)
00894 mark_call_clobbered (v_ann->type_mem_tag);
00895
00896 if (pi->pt_vars)
00897 EXECUTE_IF_SET_IN_BITMAP (pi->pt_vars, 0, j, bi)
00898 {
00899 mark_call_clobbered (referenced_var (j));
00900 }
00901 }
00902
00903
00904
00905
00906 if (pi->name_mem_tag && pi->pt_vars)
00907 EXECUTE_IF_SET_IN_BITMAP (pi->pt_vars, 0, j, bi)
00908 {
00909 add_may_alias (pi->name_mem_tag, referenced_var (j));
00910 add_may_alias (v_ann->type_mem_tag, referenced_var (j));
00911 }
00912
00913
00914
00915 if (pi->name_mem_tag
00916 && v_ann->type_mem_tag
00917 && is_call_clobbered (pi->name_mem_tag))
00918 mark_call_clobbered (v_ann->type_mem_tag);
00919 }
00920 }
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932 static void
00933 compute_flow_insensitive_aliasing (struct alias_info *ai)
00934 {
00935 size_t i;
00936
00937
00938
00939
00940
00941 ai->total_alias_vops = 0;
00942
00943
00944
00945 for (i = 0; i < ai->num_pointers; i++)
00946 {
00947 size_t j;
00948 struct alias_map_d *p_map = ai->pointers[i];
00949 tree tag = var_ann (p_map->var)->type_mem_tag;
00950 var_ann_t tag_ann = var_ann (tag);
00951
00952 p_map->total_alias_vops = 0;
00953 p_map->may_aliases = sbitmap_alloc (num_referenced_vars);
00954 sbitmap_zero (p_map->may_aliases);
00955
00956 for (j = 0; j < ai->num_addressable_vars; j++)
00957 {
00958 struct alias_map_d *v_map;
00959 var_ann_t v_ann;
00960 tree var;
00961 bool tag_stored_p, var_stored_p;
00962
00963 v_map = ai->addressable_vars[j];
00964 var = v_map->var;
00965 v_ann = var_ann (var);
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976 tag_stored_p = is_call_clobbered (tag)
00977 || bitmap_bit_p (ai->written_vars, tag_ann->uid);
00978 var_stored_p = is_call_clobbered (var)
00979 || bitmap_bit_p (ai->written_vars, v_ann->uid);
00980 if (!tag_stored_p && !var_stored_p)
00981 continue;
00982
00983 if (may_alias_p (p_map->var, p_map->set, var, v_map->set))
00984 {
00985 size_t num_tag_refs, num_var_refs;
00986
00987 num_tag_refs = VARRAY_UINT (ai->num_references, tag_ann->uid);
00988 num_var_refs = VARRAY_UINT (ai->num_references, v_ann->uid);
00989
00990
00991 add_may_alias (tag, var);
00992
00993
00994
00995
00996
00997
00998
00999 ai->total_alias_vops += (num_var_refs + num_tag_refs);
01000 p_map->total_alias_vops += (num_var_refs + num_tag_refs);
01001
01002
01003
01004 SET_BIT (p_map->may_aliases, var_ann (var)->uid);
01005 }
01006 }
01007 }
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029 for (i = 0; i < ai->num_pointers; i++)
01030 {
01031 size_t j;
01032 struct alias_map_d *p_map1 = ai->pointers[i];
01033 tree tag1 = var_ann (p_map1->var)->type_mem_tag;
01034 sbitmap may_aliases1 = p_map1->may_aliases;
01035
01036 for (j = i + 1; j < ai->num_pointers; j++)
01037 {
01038 struct alias_map_d *p_map2 = ai->pointers[j];
01039 tree tag2 = var_ann (p_map2->var)->type_mem_tag;
01040 sbitmap may_aliases2 = p_map2->may_aliases;
01041
01042
01043 if (!may_alias_p (p_map1->var, p_map1->set, p_map2->var, p_map2->set))
01044 continue;
01045
01046
01047
01048 if (sbitmap_any_common_bits (may_aliases1, may_aliases2))
01049 continue;
01050
01051 if (sbitmap_first_set_bit (may_aliases2) >= 0)
01052 {
01053 size_t k;
01054
01055
01056
01057 EXECUTE_IF_SET_IN_SBITMAP (may_aliases2, 0, k,
01058 add_may_alias (tag1, referenced_var (k)));
01059 sbitmap_a_or_b (may_aliases1, may_aliases1, may_aliases2);
01060 }
01061 else
01062 {
01063
01064
01065 add_may_alias (tag1, tag2);
01066 SET_BIT (may_aliases1, var_ann (tag2)->uid);
01067 }
01068 }
01069 }
01070
01071 if (dump_file)
01072 fprintf (dump_file, "%s: Total number of aliased vops: %ld\n",
01073 get_name (current_function_decl),
01074 ai->total_alias_vops);
01075
01076
01077 if (ai->total_alias_vops >= MAX_ALIASED_VOPS)
01078 group_aliases (ai);
01079 }
01080
01081
01082
01083
01084 static int
01085 total_alias_vops_cmp (const void *p, const void *q)
01086 {
01087 const struct alias_map_d **p1 = (const struct alias_map_d **)p;
01088 const struct alias_map_d **p2 = (const struct alias_map_d **)q;
01089 long n1 = (*p1)->total_alias_vops;
01090 long n2 = (*p2)->total_alias_vops;
01091
01092
01093 return (n1 > n2 ? -1 : (n1 == n2) ? 0 : 1);
01094 }
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110 static void
01111 group_aliases_into (tree tag, sbitmap tag_aliases, struct alias_info *ai)
01112 {
01113 size_t i;
01114 var_ann_t tag_ann = var_ann (tag);
01115 size_t num_tag_refs = VARRAY_UINT (ai->num_references, tag_ann->uid);
01116
01117 EXECUTE_IF_SET_IN_SBITMAP (tag_aliases, 0, i,
01118 {
01119 tree var = referenced_var (i);
01120 var_ann_t ann = var_ann (var);
01121
01122
01123 ann->is_alias_tag = 0;
01124 ann->may_aliases = NULL;
01125
01126
01127
01128
01129 if (var != tag)
01130 add_may_alias (var, tag);
01131
01132
01133
01134
01135
01136 ai->total_alias_vops -= num_tag_refs;
01137 });
01138
01139
01140
01141
01142
01143 ai->total_alias_vops += num_tag_refs;
01144
01145
01146 tag_ann->may_aliases = NULL;
01147 }
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209 static void
01210 group_aliases (struct alias_info *ai)
01211 {
01212 size_t i;
01213
01214
01215
01216 qsort (ai->pointers, ai->num_pointers, sizeof (struct alias_map_d *),
01217 total_alias_vops_cmp);
01218
01219
01220
01221 for (i = 0; i < ai->num_pointers; i++)
01222 {
01223 size_t j;
01224 tree tag1 = var_ann (ai->pointers[i]->var)->type_mem_tag;
01225 sbitmap tag1_aliases = ai->pointers[i]->may_aliases;
01226
01227
01228 if (ai->pointers[i]->grouped_p)
01229 continue;
01230
01231
01232
01233
01234 for (j = i + 1; j < ai->num_pointers; j++)
01235 {
01236 sbitmap tag2_aliases = ai->pointers[j]->may_aliases;
01237
01238 if (sbitmap_any_common_bits (tag1_aliases, tag2_aliases))
01239 {
01240 tree tag2 = var_ann (ai->pointers[j]->var)->type_mem_tag;
01241
01242 sbitmap_a_or_b (tag1_aliases, tag1_aliases, tag2_aliases);
01243
01244
01245 sbitmap_zero (tag2_aliases);
01246 var_ann (tag2)->may_aliases = NULL;
01247
01248
01249 add_may_alias (tag2, tag1);
01250
01251 ai->pointers[j]->grouped_p = true;
01252 }
01253 }
01254
01255
01256 group_aliases_into (tag1, tag1_aliases, ai);
01257
01258
01259
01260 if (ai->total_alias_vops < MAX_ALIASED_VOPS)
01261 break;
01262 }
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280 for (i = 0; i < VARRAY_ACTIVE_SIZE (ai->processed_ptrs); i++)
01281 {
01282 size_t j;
01283 tree ptr = VARRAY_TREE (ai->processed_ptrs, i);
01284 tree name_tag = SSA_NAME_PTR_INFO (ptr)->name_mem_tag;
01285 varray_type aliases;
01286
01287 if (name_tag == NULL_TREE)
01288 continue;
01289
01290 aliases = var_ann (name_tag)->may_aliases;
01291 for (j = 0; aliases && j < VARRAY_ACTIVE_SIZE (aliases); j++)
01292 {
01293 tree alias = VARRAY_TREE (aliases, j);
01294 var_ann_t ann = var_ann (alias);
01295
01296 if (ann->mem_tag_kind == NOT_A_TAG && ann->may_aliases)
01297 {
01298 tree new_alias;
01299
01300 gcc_assert (VARRAY_ACTIVE_SIZE (ann->may_aliases) == 1);
01301
01302 new_alias = VARRAY_TREE (ann->may_aliases, 0);
01303 replace_may_alias (name_tag, j, new_alias);
01304 }
01305 }
01306 }
01307
01308 if (dump_file)
01309 fprintf (dump_file,
01310 "%s: Total number of aliased vops after grouping: %ld%s\n",
01311 get_name (current_function_decl),
01312 ai->total_alias_vops,
01313 (ai->total_alias_vops < 0) ? " (negative values are OK)" : "");
01314 }
01315
01316
01317
01318
01319 static void
01320 create_alias_map_for (tree var, struct alias_info *ai)
01321 {
01322 struct alias_map_d *alias_map;
01323 alias_map = xcalloc (1, sizeof (*alias_map));
01324 alias_map->var = var;
01325 alias_map->set = get_alias_set (var);
01326 ai->addressable_vars[ai->num_addressable_vars++] = alias_map;
01327 }
01328
01329
01330
01331
01332
01333
01334
01335
01336 static void
01337 setup_pointers_and_addressables (struct alias_info *ai)
01338 {
01339 size_t i, n_vars, num_addressable_vars, num_pointers;
01340
01341
01342 num_addressable_vars = num_pointers = 0;
01343 for (i = 0; i < num_referenced_vars; i++)
01344 {
01345 tree var = referenced_var (i);
01346
01347 if (may_be_aliased (var))
01348 num_addressable_vars++;
01349
01350 if (POINTER_TYPE_P (TREE_TYPE (var)))
01351 {
01352
01353
01354 if (TREE_THIS_VOLATILE (var))
01355 bitmap_set_bit (ai->dereferenced_ptrs_store, var_ann (var)->uid);
01356
01357 num_pointers++;
01358 }
01359 }
01360
01361
01362
01363
01364
01365
01366 ai->addressable_vars = xcalloc (num_addressable_vars,
01367 sizeof (struct alias_map_d *));
01368 ai->pointers = xcalloc (num_pointers, sizeof (struct alias_map_d *));
01369 ai->num_addressable_vars = 0;
01370 ai->num_pointers = 0;
01371
01372
01373
01374
01375 n_vars = num_referenced_vars;
01376
01377 for (i = 0; i < n_vars; i++)
01378 {
01379 tree var = referenced_var (i);
01380 var_ann_t v_ann = var_ann (var);
01381
01382
01383
01384
01385
01386
01387 if (v_ann->mem_tag_kind != NOT_A_TAG)
01388 continue;
01389
01390
01391
01392
01393
01394
01395 if (TREE_ADDRESSABLE (var))
01396 {
01397 if (!bitmap_bit_p (ai->addresses_needed, v_ann->uid)
01398 && TREE_CODE (var) != RESULT_DECL
01399 && !is_global_var (var))
01400 {
01401
01402
01403
01404 mark_non_addressable (var);
01405
01406
01407
01408 bitmap_set_bit (vars_to_rename, v_ann->uid);
01409 }
01410 else
01411 {
01412
01413
01414
01415
01416 bitmap_set_bit (addressable_vars, v_ann->uid);
01417 }
01418 }
01419
01420
01421
01422 if (may_be_aliased (var))
01423 {
01424 create_alias_map_for (var, ai);
01425 bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
01426 }
01427
01428
01429
01430 if (POINTER_TYPE_P (TREE_TYPE (var)))
01431 {
01432 if ((bitmap_bit_p (ai->dereferenced_ptrs_store, v_ann->uid)
01433 || bitmap_bit_p (ai->dereferenced_ptrs_load, v_ann->uid)))
01434 {
01435 tree tag;
01436 var_ann_t t_ann;
01437
01438
01439
01440
01441 tag = get_tmt_for (var, ai);
01442 t_ann = var_ann (tag);
01443
01444
01445
01446
01447
01448 bitmap_set_bit (vars_to_rename, t_ann->uid);
01449
01450
01451 v_ann->type_mem_tag = tag;
01452
01453
01454
01455 if (bitmap_bit_p (ai->dereferenced_ptrs_store, v_ann->uid))
01456 bitmap_set_bit (ai->written_vars, t_ann->uid);
01457
01458
01459
01460
01461 if (TREE_CODE (var) == PARM_DECL || is_global_var (var))
01462 mark_call_clobbered (tag);
01463
01464
01465
01466
01467
01468
01469 if (t_ann->uid >= VARRAY_SIZE (ai->num_references))
01470 VARRAY_GROW (ai->num_references, t_ann->uid + 10);
01471
01472 VARRAY_UINT (ai->num_references, t_ann->uid)
01473 += VARRAY_UINT (ai->num_references, v_ann->uid);
01474 }
01475 else
01476 {
01477
01478
01479
01480 var_ann_t ann = var_ann (var);
01481 tree tag = ann->type_mem_tag;
01482 if (tag)
01483 {
01484 bitmap_set_bit (vars_to_rename, var_ann (tag)->uid);
01485 ann->type_mem_tag = NULL_TREE;
01486 }
01487 }
01488 }
01489 }
01490 }
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520 static void
01521 maybe_create_global_var (struct alias_info *ai)
01522 {
01523 unsigned i, n_clobbered;
01524 bitmap_iterator bi;
01525
01526
01527 if (global_var == NULL_TREE)
01528 {
01529
01530 n_clobbered = 0;
01531 EXECUTE_IF_SET_IN_BITMAP (call_clobbered_vars, 0, i, bi)
01532 {
01533 n_clobbered++;
01534 }
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563 if (ai->num_calls_found * n_clobbered >= (size_t) GLOBAL_VAR_THRESHOLD
01564 || (n_clobbered == 0
01565 && ai->num_calls_found > 0
01566 && ai->num_pure_const_calls_found > 0
01567 && ai->num_calls_found > ai->num_pure_const_calls_found))
01568 create_global_var ();
01569 }
01570
01571
01572
01573
01574 EXECUTE_IF_SET_IN_BITMAP (call_clobbered_vars, 0, i, bi)
01575 {
01576 tree var = referenced_var (i);
01577
01578
01579
01580
01581 if (global_var && var != global_var)
01582 add_may_alias (var, global_var);
01583
01584 bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
01585 }
01586 }
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598 static bool
01599 may_alias_p (tree ptr, HOST_WIDE_INT mem_alias_set,
01600 tree var, HOST_WIDE_INT var_alias_set)
01601 {
01602 tree mem;
01603 var_ann_t v_ann, m_ann;
01604
01605 alias_stats.alias_queries++;
01606 alias_stats.simple_queries++;
01607
01608
01609 mem = var_ann (ptr)->type_mem_tag;
01610 if (mem == var)
01611 {
01612 alias_stats.alias_noalias++;
01613 alias_stats.simple_resolved++;
01614 return false;
01615 }
01616
01617 v_ann = var_ann (var);
01618 m_ann = var_ann (mem);
01619
01620 gcc_assert (m_ann->mem_tag_kind == TYPE_TAG);
01621
01622 alias_stats.tbaa_queries++;
01623
01624
01625 if (!alias_sets_conflict_p (mem_alias_set, var_alias_set))
01626 {
01627 alias_stats.alias_noalias++;
01628 alias_stats.tbaa_resolved++;
01629 return false;
01630 }
01631
01632 alias_stats.alias_mayalias++;
01633 return true;
01634 }
01635
01636
01637
01638
01639 static void
01640 add_may_alias (tree var, tree alias)
01641 {
01642 size_t i;
01643 var_ann_t v_ann = get_var_ann (var);
01644 var_ann_t a_ann = get_var_ann (alias);
01645
01646 gcc_assert (var != alias);
01647
01648 if (v_ann->may_aliases == NULL)
01649 VARRAY_TREE_INIT (v_ann->may_aliases, 2, "aliases");
01650
01651
01652 for (i = 0; i < VARRAY_ACTIVE_SIZE (v_ann->may_aliases); i++)
01653 if (alias == VARRAY_TREE (v_ann->may_aliases, i))
01654 return;
01655
01656
01657
01658
01659 if (is_call_clobbered (var))
01660 mark_call_clobbered (alias);
01661
01662
01663 else if (is_call_clobbered (alias))
01664 mark_call_clobbered (var);
01665
01666 VARRAY_PUSH_TREE (v_ann->may_aliases, alias);
01667 a_ann->is_alias_tag = 1;
01668 }
01669
01670
01671
01672
01673 static void
01674 replace_may_alias (tree var, size_t i, tree new_alias)
01675 {
01676 var_ann_t v_ann = var_ann (var);
01677 VARRAY_TREE (v_ann->may_aliases, i) = new_alias;
01678
01679
01680
01681
01682 if (is_call_clobbered (var))
01683 mark_call_clobbered (new_alias);
01684
01685
01686 else if (is_call_clobbered (new_alias))
01687 mark_call_clobbered (var);
01688 }
01689
01690
01691
01692
01693 static void
01694 set_pt_anything (tree ptr)
01695 {
01696 struct ptr_info_def *pi = get_ptr_info (ptr);
01697
01698 pi->pt_anything = 1;
01699 pi->pt_malloc = 0;
01700
01701
01702
01703
01704 if (pi->name_mem_tag)
01705 {
01706 bitmap_set_bit (vars_to_rename, var_ann (pi->name_mem_tag)->uid);
01707 pi->name_mem_tag = NULL_TREE;
01708 }
01709 }
01710
01711
01712
01713
01714 static void
01715 set_pt_malloc (tree ptr)
01716 {
01717 struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr);
01718
01719
01720
01721 if (pi->pt_anything)
01722 return;
01723
01724 pi->pt_malloc = 1;
01725 }
01726
01727
01728
01729
01730
01731
01732 static void
01733 merge_pointed_to_info (struct alias_info *ai, tree dest, tree orig)
01734 {
01735 struct ptr_info_def *dest_pi, *orig_pi;
01736
01737 gcc_assert (dest != orig);
01738
01739
01740 collect_points_to_info_for (ai, orig);
01741
01742 dest_pi = get_ptr_info (dest);
01743 orig_pi = SSA_NAME_PTR_INFO (orig);
01744
01745 if (orig_pi)
01746 {
01747 gcc_assert (orig_pi != dest_pi);
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768 dest_pi->pt_malloc = 0;
01769 if (orig_pi->pt_malloc || orig_pi->pt_anything)
01770 set_pt_anything (dest);
01771
01772 dest_pi->pt_null |= orig_pi->pt_null;
01773
01774 if (!dest_pi->pt_anything
01775 && orig_pi->pt_vars
01776 && !bitmap_empty_p (orig_pi->pt_vars))
01777 {
01778 if (dest_pi->pt_vars == NULL)
01779 {
01780 dest_pi->pt_vars = BITMAP_GGC_ALLOC ();
01781 bitmap_copy (dest_pi->pt_vars, orig_pi->pt_vars);
01782 }
01783 else
01784 bitmap_ior_into (dest_pi->pt_vars, orig_pi->pt_vars);
01785 }
01786 }
01787 else
01788 set_pt_anything (dest);
01789 }
01790
01791
01792
01793
01794 static void
01795 add_pointed_to_expr (struct alias_info *ai, tree ptr, tree expr)
01796 {
01797 if (TREE_CODE (expr) == WITH_SIZE_EXPR)
01798 expr = TREE_OPERAND (expr, 0);
01799
01800 get_ptr_info (ptr);
01801
01802 if (TREE_CODE (expr) == CALL_EXPR
01803 && (call_expr_flags (expr) & (ECF_MALLOC | ECF_MAY_BE_ALLOCA)))
01804 {
01805
01806
01807 set_pt_malloc (ptr);
01808 }
01809 else if (TREE_CODE (expr) == ADDR_EXPR)
01810 {
01811
01812 add_pointed_to_var (ai, ptr, expr);
01813 }
01814 else if (TREE_CODE (expr) == SSA_NAME && POINTER_TYPE_P (TREE_TYPE (expr)))
01815 {
01816
01817 merge_pointed_to_info (ai, ptr, expr);
01818 }
01819 else if (TREE_CODE (expr) == PLUS_EXPR || TREE_CODE (expr) == MINUS_EXPR)
01820 {
01821
01822 tree op0 = TREE_OPERAND (expr, 0);
01823 tree op1 = TREE_OPERAND (expr, 1);
01824
01825
01826
01827 if (POINTER_TYPE_P (TREE_TYPE (op0))
01828 && TREE_CODE (op0) != INTEGER_CST)
01829 {
01830 if (TREE_CODE (op0) == SSA_NAME)
01831 merge_pointed_to_info (ai, ptr, op0);
01832 else if (TREE_CODE (op0) == ADDR_EXPR)
01833 add_pointed_to_var (ai, ptr, op0);
01834 else
01835 set_pt_anything (ptr);
01836 }
01837
01838 if (POINTER_TYPE_P (TREE_TYPE (op1))
01839 && TREE_CODE (op1) != INTEGER_CST)
01840 {
01841 if (TREE_CODE (op1) == SSA_NAME)
01842 merge_pointed_to_info (ai, ptr, op1);
01843 else if (TREE_CODE (op1) == ADDR_EXPR)
01844 add_pointed_to_var (ai, ptr, op1);
01845 else
01846 set_pt_anything (ptr);
01847 }
01848
01849
01850
01851
01852
01853 if (!(POINTER_TYPE_P (TREE_TYPE (op0))
01854 && TREE_CODE (op0) != INTEGER_CST)
01855 && !(POINTER_TYPE_P (TREE_TYPE (op1))
01856 && TREE_CODE (op1) != INTEGER_CST))
01857 set_pt_anything (ptr);
01858 }
01859 else if (integer_zerop (expr))
01860 {
01861
01862 SSA_NAME_PTR_INFO (ptr)->pt_null = 1;
01863 }
01864 else
01865 {
01866
01867
01868 set_pt_anything (ptr);
01869 }
01870 }
01871
01872
01873
01874
01875
01876
01877 static void
01878 add_pointed_to_var (struct alias_info *ai, tree ptr, tree value)
01879 {
01880 struct ptr_info_def *pi = get_ptr_info (ptr);
01881 tree pt_var;
01882 size_t uid;
01883
01884 gcc_assert (TREE_CODE (value) == ADDR_EXPR);
01885
01886 pt_var = TREE_OPERAND (value, 0);
01887 if (REFERENCE_CLASS_P (pt_var))
01888 pt_var = get_base_address (pt_var);
01889
01890 if (pt_var == NULL)
01891 {
01892 pi->pt_anything = 1;
01893 }
01894 else if (SSA_VAR_P (pt_var))
01895 {
01896 uid = var_ann (pt_var)->uid;
01897 bitmap_set_bit (ai->addresses_needed, uid);
01898
01899 if (pi->pt_vars == NULL)
01900 pi->pt_vars = BITMAP_GGC_ALLOC ();
01901 bitmap_set_bit (pi->pt_vars, uid);
01902
01903
01904
01905 if (is_global_var (pt_var))
01906 pi->pt_global_mem = 1;
01907 }
01908 else if (TREE_CODE (pt_var) == INDIRECT_REF
01909 && TREE_CODE (TREE_OPERAND (pt_var, 0)) == SSA_NAME)
01910 {
01911
01912
01913 add_pointed_to_expr (ai, ptr, TREE_OPERAND (pt_var, 0));
01914 }
01915 else
01916 {
01917
01918 set_pt_anything (ptr);
01919 }
01920 }
01921
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933 static bool
01934 collect_points_to_info_r (tree var, tree stmt, void *data)
01935 {
01936 struct alias_info *ai = (struct alias_info *) data;
01937
01938 if (dump_file && (dump_flags & TDF_DETAILS))
01939 {
01940 fprintf (dump_file, "Visiting use-def links for ");
01941 print_generic_expr (dump_file, var, dump_flags);
01942 fprintf (dump_file, "\n");
01943 }
01944
01945 switch (TREE_CODE (stmt))
01946 {
01947 case RETURN_EXPR:
01948 if (TREE_CODE (TREE_OPERAND (stmt, 0)) != MODIFY_EXPR)
01949 abort ();
01950 stmt = TREE_OPERAND (stmt, 0);
01951
01952
01953 case MODIFY_EXPR:
01954 {
01955 tree rhs = TREE_OPERAND (stmt, 1);
01956 STRIP_NOPS (rhs);
01957 add_pointed_to_expr (ai, var, rhs);
01958 break;
01959 }
01960
01961 case ASM_EXPR:
01962
01963 set_pt_anything (var);
01964 break;
01965
01966 case NOP_EXPR:
01967 if (IS_EMPTY_STMT (stmt))
01968 {
01969 tree decl = SSA_NAME_VAR (var);
01970
01971 if (TREE_CODE (decl) == PARM_DECL)
01972 add_pointed_to_expr (ai, var, decl);
01973 else if (DECL_INITIAL (decl))
01974 add_pointed_to_expr (ai, var, DECL_INITIAL (decl));
01975 else
01976 add_pointed_to_expr (ai, var, decl);
01977 }
01978 break;
01979
01980 case PHI_NODE:
01981 {
01982
01983
01984 tree lhs = PHI_RESULT (stmt);
01985
01986 switch (TREE_CODE (var))
01987 {
01988 case ADDR_EXPR:
01989 add_pointed_to_var (ai, lhs, var);
01990 break;
01991
01992 case SSA_NAME:
01993
01994 if (lhs != var)
01995 merge_pointed_to_info (ai, lhs, var);
01996 break;
01997
01998 default:
01999 gcc_assert (is_gimple_min_invariant (var));
02000 add_pointed_to_expr (ai, lhs, var);
02001 break;
02002 }
02003 break;
02004 }
02005
02006 default:
02007 gcc_unreachable ();
02008 }
02009
02010 return false;
02011 }
02012
02013
02014
02015
02016
02017
02018
02019
02020
02021
02022
02023
02024
02025 static bool
02026 is_escape_site (tree stmt, struct alias_info *ai)
02027 {
02028 tree call = get_call_expr_in (stmt);
02029 if (call != NULL_TREE)
02030 {
02031 ai->num_calls_found++;
02032
02033 if (!TREE_SIDE_EFFECTS (call))
02034 ai->num_pure_const_calls_found++;
02035
02036 return true;
02037 }
02038 else if (TREE_CODE (stmt) == ASM_EXPR)
02039 return true;
02040 else if (TREE_CODE (stmt) == MODIFY_EXPR)
02041 {
02042 tree lhs = TREE_OPERAND (stmt, 0);
02043
02044
02045 if (TREE_CODE (lhs) != SSA_NAME)
02046 lhs = get_base_address (lhs);
02047
02048
02049
02050 if (lhs == NULL_TREE)
02051 return true;
02052
02053
02054
02055 if ((TREE_CODE (TREE_OPERAND (stmt, 1)) == NOP_EXPR
02056 || TREE_CODE (TREE_OPERAND (stmt, 1)) == CONVERT_EXPR
02057 || TREE_CODE (TREE_OPERAND (stmt, 1)) == VIEW_CONVERT_EXPR)
02058 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND
02059 (TREE_OPERAND (stmt, 1), 0)))
02060 && !POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (stmt, 1))))
02061 return true;
02062
02063
02064
02065 if (TREE_CODE (lhs) == SSA_NAME)
02066 return false;
02067
02068
02069
02070
02071
02072
02073
02074
02075
02076
02077 return true;
02078 }
02079 else if (TREE_CODE (stmt) == RETURN_EXPR)
02080 return true;
02081
02082 return false;
02083 }
02084
02085
02086
02087
02088
02089
02090
02091 static tree
02092 create_memory_tag (tree type, bool is_type_tag)
02093 {
02094 var_ann_t ann;
02095 tree tag = create_tmp_var_raw (type, (is_type_tag) ? "TMT" : "NMT");
02096
02097
02098
02099 DECL_CONTEXT (tag) = current_function_decl;
02100
02101
02102
02103
02104 TREE_ADDRESSABLE (tag) = 1;
02105
02106 ann = get_var_ann (tag);
02107 ann->mem_tag_kind = (is_type_tag) ? TYPE_TAG : NAME_TAG;
02108 ann->type_mem_tag = NULL_TREE;
02109
02110
02111 add_referenced_tmp_var (tag);
02112
02113 return tag;
02114 }
02115
02116
02117
02118
02119
02120
02121
02122 static tree
02123 get_nmt_for (tree ptr)
02124 {
02125 struct ptr_info_def *pi = get_ptr_info (ptr);
02126 tree tag = pi->name_mem_tag;
02127
02128 if (tag == NULL_TREE)
02129 tag = create_memory_tag (TREE_TYPE (TREE_TYPE (ptr)), false);
02130
02131
02132
02133 if (TREE_CODE (SSA_NAME_VAR (ptr)) == PARM_DECL
02134 || pi->pt_malloc
02135 || pi->pt_global_mem)
02136 mark_call_clobbered (tag);
02137
02138 return tag;
02139 }
02140
02141
02142
02143
02144
02145
02146
02147
02148
02149
02150 static tree
02151 get_tmt_for (tree ptr, struct alias_info *ai)
02152 {
02153 size_t i;
02154 tree tag;
02155 tree tag_type = TREE_TYPE (TREE_TYPE (ptr));
02156 HOST_WIDE_INT tag_set = get_alias_set (tag_type);
02157
02158
02159
02160
02161
02162
02163
02164
02165
02166 for (i = 0, tag = NULL_TREE; i < ai->num_pointers; i++)
02167 {
02168 struct alias_map_d *curr = ai->pointers[i];
02169 if (tag_set == curr->set)
02170 {
02171 tag = var_ann (curr->var)->type_mem_tag;
02172 break;
02173 }
02174 }
02175
02176
02177
02178 if (tag == NULL_TREE)
02179 {
02180 struct alias_map_d *alias_map;
02181
02182
02183
02184
02185 if (var_ann (ptr)->type_mem_tag == NULL_TREE)
02186 tag = create_memory_tag (tag_type, true);
02187 else
02188 tag = var_ann (ptr)->type_mem_tag;
02189
02190
02191
02192
02193 alias_map = xcalloc (1, sizeof (*alias_map));
02194 alias_map->var = ptr;
02195 alias_map->set = tag_set;
02196 ai->pointers[ai->num_pointers++] = alias_map;
02197 }
02198
02199
02200 TREE_THIS_VOLATILE (tag) |= TREE_THIS_VOLATILE (tag_type);
02201
02202
02203
02204 gcc_assert (tag_set == get_alias_set (tag));
02205
02206 return tag;
02207 }
02208
02209
02210
02211
02212
02213
02214 static void
02215 create_global_var (void)
02216 {
02217 global_var = build_decl (VAR_DECL, get_identifier (".GLOBAL_VAR"),
02218 void_type_node);
02219 DECL_ARTIFICIAL (global_var) = 1;
02220 TREE_READONLY (global_var) = 0;
02221 DECL_EXTERNAL (global_var) = 1;
02222 TREE_STATIC (global_var) = 1;
02223 TREE_USED (global_var) = 1;
02224 DECL_CONTEXT (global_var) = NULL_TREE;
02225 TREE_THIS_VOLATILE (global_var) = 0;
02226 TREE_ADDRESSABLE (global_var) = 0;
02227
02228 add_referenced_tmp_var (global_var);
02229 bitmap_set_bit (vars_to_rename, var_ann (global_var)->uid);
02230 }
02231
02232
02233
02234
02235 static void
02236 dump_alias_stats (FILE *file)
02237 {
02238 const char *funcname
02239 = lang_hooks.decl_printable_name (current_function_decl, 2);
02240 fprintf (file, "\nAlias statistics for %s\n\n", funcname);
02241 fprintf (file, "Total alias queries:\t%u\n", alias_stats.alias_queries);
02242 fprintf (file, "Total alias mayalias results:\t%u\n",
02243 alias_stats.alias_mayalias);
02244 fprintf (file, "Total alias noalias results:\t%u\n",
02245 alias_stats.alias_noalias);
02246 fprintf (file, "Total simple queries:\t%u\n",
02247 alias_stats.simple_queries);
02248 fprintf (file, "Total simple resolved:\t%u\n",
02249 alias_stats.simple_resolved);
02250 fprintf (file, "Total TBAA queries:\t%u\n",
02251 alias_stats.tbaa_queries);
02252 fprintf (file, "Total TBAA resolved:\t%u\n",
02253 alias_stats.tbaa_resolved);
02254 }
02255
02256
02257
02258
02259 void
02260 dump_alias_info (FILE *file)
02261 {
02262 size_t i;
02263 const char *funcname
02264 = lang_hooks.decl_printable_name (current_function_decl, 2);
02265
02266 fprintf (file, "\nFlow-insensitive alias information for %s\n\n", funcname);
02267
02268 fprintf (file, "Aliased symbols\n\n");
02269 for (i = 0; i < num_referenced_vars; i++)
02270 {
02271 tree var = referenced_var (i);
02272 if (may_be_aliased (var))
02273 dump_variable (file, var);
02274 }
02275
02276 fprintf (file, "\nDereferenced pointers\n\n");
02277 for (i = 0; i < num_referenced_vars; i++)
02278 {
02279 tree var = referenced_var (i);
02280 var_ann_t ann = var_ann (var);
02281 if (ann->type_mem_tag)
02282 dump_variable (file, var);
02283 }
02284
02285 fprintf (file, "\nType memory tags\n\n");
02286 for (i = 0; i < num_referenced_vars; i++)
02287 {
02288 tree var = referenced_var (i);
02289 var_ann_t ann = var_ann (var);
02290 if (ann->mem_tag_kind == TYPE_TAG)
02291 dump_variable (file, var);
02292 }
02293
02294 fprintf (file, "\n\nFlow-sensitive alias information for %s\n\n", funcname);
02295
02296 fprintf (file, "SSA_NAME pointers\n\n");
02297 for (i = 1; i < num_ssa_names; i++)
02298 {
02299 tree ptr = ssa_name (i);
02300 struct ptr_info_def *pi;
02301
02302 if (ptr == NULL_TREE)
02303 continue;
02304
02305 pi = SSA_NAME_PTR_INFO (ptr);
02306 if (!SSA_NAME_IN_FREE_LIST (ptr)
02307 && pi
02308 && pi->name_mem_tag)
02309 dump_points_to_info_for (file, ptr);
02310 }
02311
02312 fprintf (file, "\nName memory tags\n\n");
02313 for (i = 0; i < num_referenced_vars; i++)
02314 {
02315 tree var = referenced_var (i);
02316 var_ann_t ann = var_ann (var);
02317 if (ann->mem_tag_kind == NAME_TAG)
02318 dump_variable (file, var);
02319 }
02320
02321 fprintf (file, "\n");
02322 }
02323
02324
02325
02326
02327 void
02328 debug_alias_info (void)
02329 {
02330 dump_alias_info (stderr);
02331 }
02332
02333
02334
02335
02336
02337 struct ptr_info_def *
02338 get_ptr_info (tree t)
02339 {
02340 struct ptr_info_def *pi;
02341
02342 gcc_assert (POINTER_TYPE_P (TREE_TYPE (t)));
02343
02344 pi = SSA_NAME_PTR_INFO (t);
02345 if (pi == NULL)
02346 {
02347 pi = ggc_alloc (sizeof (*pi));
02348 memset ((void *)pi, 0, sizeof (*pi));
02349 SSA_NAME_PTR_INFO (t) = pi;
02350 }
02351
02352 return pi;
02353 }
02354
02355
02356
02357
02358 void
02359 dump_points_to_info_for (FILE *file, tree ptr)
02360 {
02361 struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr);
02362
02363 print_generic_expr (file, ptr, dump_flags);
02364
02365 if (pi)
02366 {
02367 if (pi->name_mem_tag)
02368 {
02369 fprintf (file, ", name memory tag: ");
02370 print_generic_expr (file, pi->name_mem_tag, dump_flags);
02371 }
02372
02373 if (pi->is_dereferenced)
02374 fprintf (file, ", is dereferenced");
02375
02376 if (pi->value_escapes_p)
02377 fprintf (file, ", its value escapes");
02378
02379 if (pi->pt_anything)
02380 fprintf (file, ", points-to anything");
02381
02382 if (pi->pt_malloc)
02383 fprintf (file, ", points-to malloc");
02384
02385 if (pi->pt_null)
02386 fprintf (file, ", points-to NULL");
02387
02388 if (pi->pt_vars)
02389 {
02390 unsigned ix;
02391 bitmap_iterator bi;
02392
02393 fprintf (file, ", points-to vars: { ");
02394 EXECUTE_IF_SET_IN_BITMAP (pi->pt_vars, 0, ix, bi)
02395 {
02396 print_generic_expr (file, referenced_var (ix), dump_flags);
02397 fprintf (file, " ");
02398 }
02399 fprintf (file, "}");
02400 }
02401 }
02402
02403 fprintf (file, "\n");
02404 }
02405
02406
02407
02408
02409 void
02410 debug_points_to_info_for (tree var)
02411 {
02412 dump_points_to_info_for (stderr, var);
02413 }
02414
02415
02416
02417
02418
02419 void
02420 dump_points_to_info (FILE *file)
02421 {
02422 basic_block bb;
02423 block_stmt_iterator si;
02424 size_t i;
02425 ssa_op_iter iter;
02426 const char *fname =
02427 lang_hooks.decl_printable_name (current_function_decl, 2);
02428
02429 fprintf (file, "\n\nPointed-to sets for pointers in %s\n\n", fname);
02430
02431
02432
02433
02434 for (i = 0; i < num_referenced_vars; i++)
02435 {
02436 tree var = referenced_var (i);
02437 if (POINTER_TYPE_P (TREE_TYPE (var)))
02438 {
02439 var_ann_t ann = var_ann (var);
02440 if (ann->default_def)
02441 dump_points_to_info_for (file, ann->default_def);
02442 }
02443 }
02444
02445
02446 FOR_EACH_BB (bb)
02447 {
02448 tree phi;
02449
02450 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
02451 {
02452 tree ptr = PHI_RESULT (phi);
02453 if (POINTER_TYPE_P (TREE_TYPE (ptr)))
02454 dump_points_to_info_for (file, ptr);
02455 }
02456
02457 for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
02458 {
02459 tree stmt = bsi_stmt (si);
02460 tree def;
02461 FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF)
02462 if (POINTER_TYPE_P (TREE_TYPE (def)))
02463 dump_points_to_info_for (file, def);
02464 }
02465 }
02466
02467 fprintf (file, "\n");
02468 }
02469
02470
02471
02472
02473 void
02474 debug_points_to_info (void)
02475 {
02476 dump_points_to_info (stderr);
02477 }
02478
02479
02480
02481 void
02482 dump_may_aliases_for (FILE *file, tree var)
02483 {
02484 varray_type aliases;
02485
02486 if (TREE_CODE (var) == SSA_NAME)
02487 var = SSA_NAME_VAR (var);
02488
02489 aliases = var_ann (var)->may_aliases;
02490 if (aliases)
02491 {
02492 size_t i;
02493 fprintf (file, "{ ");
02494 for (i = 0; i < VARRAY_ACTIVE_SIZE (aliases); i++)
02495 {
02496 print_generic_expr (file, VARRAY_TREE (aliases, i), dump_flags);
02497 fprintf (file, " ");
02498 }
02499 fprintf (file, "}");
02500 }
02501 }
02502
02503
02504
02505
02506 void
02507 debug_may_aliases_for (tree var)
02508 {
02509 dump_may_aliases_for (stderr, var);
02510 }
02511
02512
02513
02514 bool
02515 may_be_aliased (tree var)
02516 {
02517
02518 if (TREE_ADDRESSABLE (var))
02519 return true;
02520
02521
02522
02523 if (DECL_EXTERNAL (var) || TREE_PUBLIC (var))
02524 return true;
02525
02526
02527
02528
02529 if (!TREE_STATIC (var))
02530 return false;
02531
02532
02533
02534
02535
02536 if (flag_unit_at_a_time)
02537 return false;
02538 if (decl_function_context (var) == current_function_decl)
02539 return false;
02540
02541 return true;
02542 }