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 "ggc.h"
00027 #include "obstack.h"
00028 #include "bitmap.h"
00029 #include "flags.h"
00030 #include "rtl.h"
00031 #include "tm_p.h"
00032 #include "hard-reg-set.h"
00033 #include "basic-block.h"
00034 #include "output.h"
00035 #include "errors.h"
00036 #include "diagnostic.h"
00037 #include "tree.h"
00038 #include "c-common.h"
00039 #include "tree-flow.h"
00040 #include "tree-inline.h"
00041 #include "varray.h"
00042 #include "c-tree.h"
00043 #include "tree-gimple.h"
00044 #include "hashtab.h"
00045 #include "function.h"
00046 #include "cgraph.h"
00047 #include "tree-pass.h"
00048 #include "timevar.h"
00049 #include "alloc-pool.h"
00050 #include "splay-tree.h"
00051 #include "params.h"
00052 #include "tree-ssa-structalias.h"
00053 #include "cgraph.h"
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164 static GTY ((if_marked ("tree_map_marked_p"), param_is (struct tree_map)))
00165 htab_t heapvar_for_stmt;
00166
00167
00168 tree nonlocal_all;
00169
00170 static bool use_field_sensitive = true;
00171 static int in_ipa_mode = 0;
00172 static bitmap_obstack predbitmap_obstack;
00173 static bitmap_obstack ptabitmap_obstack;
00174 static bitmap_obstack iteration_obstack;
00175
00176 static unsigned int create_variable_info_for (tree, const char *);
00177 static void build_constraint_graph (void);
00178
00179 DEF_VEC_P(constraint_t);
00180 DEF_VEC_ALLOC_P(constraint_t,heap);
00181
00182 #define EXECUTE_IF_IN_NONNULL_BITMAP(a, b, c, d) \
00183 if (a) \
00184 EXECUTE_IF_SET_IN_BITMAP (a, b, c, d)
00185
00186 static struct constraint_stats
00187 {
00188 unsigned int total_vars;
00189 unsigned int collapsed_vars;
00190 unsigned int unified_vars_static;
00191 unsigned int unified_vars_dynamic;
00192 unsigned int iterations;
00193 unsigned int num_edges;
00194 } stats;
00195
00196 struct variable_info
00197 {
00198
00199 unsigned int id;
00200
00201
00202 const char *name;
00203
00204
00205 tree decl;
00206
00207
00208 unsigned HOST_WIDE_INT offset;
00209
00210
00211 unsigned HOST_WIDE_INT size;
00212
00213
00214 unsigned HOST_WIDE_INT fullsize;
00215
00216
00217 struct variable_info *next;
00218
00219
00220
00221 unsigned int node;
00222
00223
00224
00225 unsigned int address_taken:1;
00226
00227
00228
00229 unsigned int indirect_target:1;
00230
00231
00232
00233
00234
00235 unsigned int directly_dereferenced:1;
00236
00237
00238
00239 unsigned int is_artificial_var:1;
00240
00241
00242
00243 unsigned int is_special_var:1;
00244
00245
00246 unsigned int is_unknown_size_var:1;
00247
00248
00249 unsigned int has_union:1;
00250
00251
00252 unsigned int is_heap_var:1;
00253
00254
00255 bitmap solution;
00256
00257
00258 bitmap variables;
00259
00260
00261
00262 VEC(constraint_t,heap) *complex;
00263
00264
00265
00266
00267 struct variable_info *collapsed_to;
00268 };
00269 typedef struct variable_info *varinfo_t;
00270
00271 static varinfo_t first_vi_for_offset (varinfo_t, unsigned HOST_WIDE_INT);
00272
00273
00274 static alloc_pool variable_info_pool;
00275
00276 DEF_VEC_P(varinfo_t);
00277
00278 DEF_VEC_ALLOC_P(varinfo_t, heap);
00279
00280
00281
00282 static VEC(varinfo_t,heap) *varmap;
00283
00284
00285
00286 static inline varinfo_t
00287 get_varinfo (unsigned int n)
00288 {
00289 return VEC_index(varinfo_t, varmap, n);
00290 }
00291
00292
00293
00294 static inline varinfo_t
00295 get_varinfo_fc (unsigned int n)
00296 {
00297 varinfo_t v = VEC_index(varinfo_t, varmap, n);
00298
00299 if (v->collapsed_to)
00300 return v->collapsed_to;
00301 return v;
00302 }
00303
00304
00305 static varinfo_t var_anything;
00306 static tree anything_tree;
00307 static unsigned int anything_id;
00308
00309
00310 static varinfo_t var_nothing;
00311 static tree nothing_tree;
00312 static unsigned int nothing_id;
00313
00314
00315 static varinfo_t var_readonly;
00316 static tree readonly_tree;
00317 static unsigned int readonly_id;
00318
00319
00320
00321 static varinfo_t var_integer;
00322 static tree integer_tree;
00323 static unsigned int integer_id;
00324
00325
00326
00327 static varinfo_t var_escaped_vars;
00328 static tree escaped_vars_tree;
00329 static unsigned int escaped_vars_id;
00330
00331
00332
00333 static unsigned int nonlocal_vars_id;
00334
00335
00336
00337 static tree
00338 heapvar_lookup (tree from)
00339 {
00340 struct tree_map *h, in;
00341 in.from = from;
00342
00343 h = htab_find_with_hash (heapvar_for_stmt, &in, htab_hash_pointer (from));
00344 if (h)
00345 return h->to;
00346 return NULL_TREE;
00347 }
00348
00349
00350
00351
00352 static void
00353 heapvar_insert (tree from, tree to)
00354 {
00355 struct tree_map *h;
00356 void **loc;
00357
00358 h = ggc_alloc (sizeof (struct tree_map));
00359 h->hash = htab_hash_pointer (from);
00360 h->from = from;
00361 h->to = to;
00362 loc = htab_find_slot_with_hash (heapvar_for_stmt, h, h->hash, INSERT);
00363 *(struct tree_map **) loc = h;
00364 }
00365
00366
00367
00368
00369 static varinfo_t
00370 new_var_info (tree t, unsigned int id, const char *name, unsigned int node)
00371 {
00372 varinfo_t ret = pool_alloc (variable_info_pool);
00373
00374 ret->id = id;
00375 ret->name = name;
00376 ret->decl = t;
00377 ret->node = node;
00378 ret->address_taken = false;
00379 ret->indirect_target = false;
00380 ret->directly_dereferenced = false;
00381 ret->is_artificial_var = false;
00382 ret->is_heap_var = false;
00383 ret->is_special_var = false;
00384 ret->is_unknown_size_var = false;
00385 ret->has_union = false;
00386 ret->solution = BITMAP_ALLOC (&ptabitmap_obstack);
00387 ret->variables = BITMAP_ALLOC (&ptabitmap_obstack);
00388 ret->complex = NULL;
00389 ret->next = NULL;
00390 ret->collapsed_to = NULL;
00391 return ret;
00392 }
00393
00394 typedef enum {SCALAR, DEREF, ADDRESSOF} constraint_expr_type;
00395
00396
00397
00398 struct constraint_expr
00399 {
00400
00401 constraint_expr_type type;
00402
00403
00404 unsigned int var;
00405
00406
00407
00408
00409
00410
00411 unsigned HOST_WIDE_INT offset;
00412 };
00413
00414 typedef struct constraint_expr ce_s;
00415 DEF_VEC_O(ce_s);
00416 DEF_VEC_ALLOC_O(ce_s, heap);
00417 static void get_constraint_for (tree, VEC(ce_s, heap) **);
00418 static void do_deref (VEC (ce_s, heap) **);
00419
00420
00421
00422
00423
00424
00425
00426 struct constraint
00427 {
00428 struct constraint_expr lhs;
00429 struct constraint_expr rhs;
00430 };
00431
00432
00433
00434 static VEC(constraint_t,heap) *constraints;
00435 static alloc_pool constraint_pool;
00436
00437
00438
00439
00440
00441
00442
00443 struct constraint_edge
00444 {
00445 unsigned int dest;
00446 bitmap weights;
00447 };
00448
00449 typedef struct constraint_edge *constraint_edge_t;
00450 static alloc_pool constraint_edge_pool;
00451
00452
00453
00454 static constraint_edge_t
00455 new_constraint_edge (unsigned int dest)
00456 {
00457 constraint_edge_t ret = pool_alloc (constraint_edge_pool);
00458 ret->dest = dest;
00459 ret->weights = NULL;
00460 return ret;
00461 }
00462
00463 DEF_VEC_P(constraint_edge_t);
00464 DEF_VEC_ALLOC_P(constraint_edge_t,heap);
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478 struct constraint_graph
00479 {
00480 bitmap *zero_weight_succs;
00481 bitmap *zero_weight_preds;
00482 VEC(constraint_edge_t,heap) **succs;
00483 VEC(constraint_edge_t,heap) **preds;
00484 };
00485
00486 typedef struct constraint_graph *constraint_graph_t;
00487
00488 static constraint_graph_t graph;
00489 static int graph_size;
00490
00491
00492
00493 static constraint_t
00494 new_constraint (const struct constraint_expr lhs,
00495 const struct constraint_expr rhs)
00496 {
00497 constraint_t ret = pool_alloc (constraint_pool);
00498 ret->lhs = lhs;
00499 ret->rhs = rhs;
00500 return ret;
00501 }
00502
00503
00504
00505 void
00506 dump_constraint (FILE *file, constraint_t c)
00507 {
00508 if (c->lhs.type == ADDRESSOF)
00509 fprintf (file, "&");
00510 else if (c->lhs.type == DEREF)
00511 fprintf (file, "*");
00512 fprintf (file, "%s", get_varinfo_fc (c->lhs.var)->name);
00513 if (c->lhs.offset != 0)
00514 fprintf (file, " + " HOST_WIDE_INT_PRINT_DEC, c->lhs.offset);
00515 fprintf (file, " = ");
00516 if (c->rhs.type == ADDRESSOF)
00517 fprintf (file, "&");
00518 else if (c->rhs.type == DEREF)
00519 fprintf (file, "*");
00520 fprintf (file, "%s", get_varinfo_fc (c->rhs.var)->name);
00521 if (c->rhs.offset != 0)
00522 fprintf (file, " + " HOST_WIDE_INT_PRINT_DEC, c->rhs.offset);
00523 fprintf (file, "\n");
00524 }
00525
00526
00527
00528 void
00529 debug_constraint (constraint_t c)
00530 {
00531 dump_constraint (stderr, c);
00532 }
00533
00534
00535
00536 void
00537 dump_constraints (FILE *file)
00538 {
00539 int i;
00540 constraint_t c;
00541 for (i = 0; VEC_iterate (constraint_t, constraints, i, c); i++)
00542 dump_constraint (file, c);
00543 }
00544
00545
00546
00547 void
00548 debug_constraints (void)
00549 {
00550 dump_constraints (stderr);
00551 }
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583 static bool
00584 constraint_expr_equal (struct constraint_expr a, struct constraint_expr b)
00585 {
00586 return a.type == b.type && a.var == b.var && a.offset == b.offset;
00587 }
00588
00589
00590
00591
00592
00593 static bool
00594 constraint_expr_less (struct constraint_expr a, struct constraint_expr b)
00595 {
00596 if (a.type == b.type)
00597 {
00598 if (a.var == b.var)
00599 return a.offset < b.offset;
00600 else
00601 return a.var < b.var;
00602 }
00603 else
00604 return a.type < b.type;
00605 }
00606
00607
00608
00609
00610 static bool
00611 constraint_less (const constraint_t a, const constraint_t b)
00612 {
00613 if (constraint_expr_less (a->lhs, b->lhs))
00614 return true;
00615 else if (constraint_expr_less (b->lhs, a->lhs))
00616 return false;
00617 else
00618 return constraint_expr_less (a->rhs, b->rhs);
00619 }
00620
00621
00622
00623 static bool
00624 constraint_equal (struct constraint a, struct constraint b)
00625 {
00626 return constraint_expr_equal (a.lhs, b.lhs)
00627 && constraint_expr_equal (a.rhs, b.rhs);
00628 }
00629
00630
00631
00632
00633 static constraint_t
00634 constraint_vec_find (VEC(constraint_t,heap) *vec,
00635 struct constraint lookfor)
00636 {
00637 unsigned int place;
00638 constraint_t found;
00639
00640 if (vec == NULL)
00641 return NULL;
00642
00643 place = VEC_lower_bound (constraint_t, vec, &lookfor, constraint_less);
00644 if (place >= VEC_length (constraint_t, vec))
00645 return NULL;
00646 found = VEC_index (constraint_t, vec, place);
00647 if (!constraint_equal (*found, lookfor))
00648 return NULL;
00649 return found;
00650 }
00651
00652
00653
00654 static void
00655 constraint_set_union (VEC(constraint_t,heap) **to,
00656 VEC(constraint_t,heap) **from)
00657 {
00658 int i;
00659 constraint_t c;
00660
00661 for (i = 0; VEC_iterate (constraint_t, *from, i, c); i++)
00662 {
00663 if (constraint_vec_find (*to, *c) == NULL)
00664 {
00665 unsigned int place = VEC_lower_bound (constraint_t, *to, c,
00666 constraint_less);
00667 VEC_safe_insert (constraint_t, heap, *to, place, c);
00668 }
00669 }
00670 }
00671
00672
00673
00674
00675 static void
00676 solution_set_add (bitmap set, unsigned HOST_WIDE_INT offset)
00677 {
00678 bitmap result = BITMAP_ALLOC (&iteration_obstack);
00679 unsigned int i;
00680 bitmap_iterator bi;
00681
00682 EXECUTE_IF_SET_IN_BITMAP (set, 0, i, bi)
00683 {
00684
00685
00686
00687
00688 if ((get_varinfo (i)->offset + offset) < get_varinfo (i)->fullsize)
00689 {
00690 unsigned HOST_WIDE_INT fieldoffset = get_varinfo (i)->offset + offset;
00691 varinfo_t v = first_vi_for_offset (get_varinfo (i), fieldoffset);
00692 if (!v)
00693 continue;
00694 bitmap_set_bit (result, v->id);
00695 }
00696 else if (get_varinfo (i)->is_artificial_var
00697 || get_varinfo (i)->has_union
00698 || get_varinfo (i)->is_unknown_size_var)
00699 {
00700 bitmap_set_bit (result, i);
00701 }
00702 }
00703
00704 bitmap_copy (set, result);
00705 BITMAP_FREE (result);
00706 }
00707
00708
00709
00710
00711 static bool
00712 set_union_with_increment (bitmap to, bitmap from, unsigned HOST_WIDE_INT inc)
00713 {
00714 if (inc == 0)
00715 return bitmap_ior_into (to, from);
00716 else
00717 {
00718 bitmap tmp;
00719 bool res;
00720
00721 tmp = BITMAP_ALLOC (&iteration_obstack);
00722 bitmap_copy (tmp, from);
00723 solution_set_add (tmp, inc);
00724 res = bitmap_ior_into (to, tmp);
00725 BITMAP_FREE (tmp);
00726 return res;
00727 }
00728 }
00729
00730
00731
00732 static void
00733 insert_into_complex (unsigned int var, constraint_t c)
00734 {
00735 varinfo_t vi = get_varinfo (var);
00736 unsigned int place = VEC_lower_bound (constraint_t, vi->complex, c,
00737 constraint_less);
00738 VEC_safe_insert (constraint_t, heap, vi->complex, place, c);
00739 }
00740
00741
00742
00743
00744 static bool
00745 constraint_edge_equal (struct constraint_edge a, struct constraint_edge b)
00746 {
00747 return a.dest == b.dest;
00748 }
00749
00750
00751
00752 static bool
00753 constraint_edge_less (const constraint_edge_t a, const constraint_edge_t b)
00754 {
00755 if (a->dest < b->dest)
00756 return true;
00757 return false;
00758 }
00759
00760
00761
00762
00763 static constraint_edge_t
00764 constraint_edge_vec_find (VEC(constraint_edge_t,heap) *vec,
00765 struct constraint_edge lookfor)
00766 {
00767 unsigned int place;
00768 constraint_edge_t edge = NULL;
00769
00770 place = VEC_lower_bound (constraint_edge_t, vec, &lookfor,
00771 constraint_edge_less);
00772 if (place >= VEC_length (constraint_edge_t, vec))
00773 return NULL;
00774 edge = VEC_index (constraint_edge_t, vec, place);
00775 if (!constraint_edge_equal (*edge, lookfor))
00776 return NULL;
00777 return edge;
00778 }
00779
00780
00781
00782
00783 static void
00784 condense_varmap_nodes (unsigned int to, unsigned int src)
00785 {
00786 varinfo_t tovi = get_varinfo (to);
00787 varinfo_t srcvi = get_varinfo (src);
00788 unsigned int i;
00789 constraint_t c;
00790 bitmap_iterator bi;
00791
00792
00793 srcvi->node = to;
00794 EXECUTE_IF_SET_IN_BITMAP (srcvi->variables, 0, i, bi)
00795 get_varinfo (i)->node = to;
00796
00797
00798 bitmap_set_bit (tovi->variables, src);
00799 bitmap_ior_into (tovi->variables, srcvi->variables);
00800 bitmap_clear (srcvi->variables);
00801
00802
00803 for (i = 0; VEC_iterate (constraint_t, srcvi->complex, i, c); i++)
00804 {
00805
00806
00807
00808 if (c->rhs.type == DEREF)
00809 c->rhs.var = to;
00810 else
00811 c->lhs.var = to;
00812 }
00813 constraint_set_union (&tovi->complex, &srcvi->complex);
00814 VEC_free (constraint_t, heap, srcvi->complex);
00815 srcvi->complex = NULL;
00816 }
00817
00818
00819
00820
00821 static void
00822 erase_graph_self_edge (constraint_graph_t graph, unsigned int src)
00823 {
00824 VEC(constraint_edge_t,heap) *predvec = graph->preds[src];
00825 VEC(constraint_edge_t,heap) *succvec = graph->succs[src];
00826 struct constraint_edge edge;
00827 unsigned int place;
00828
00829 edge.dest = src;
00830
00831
00832 place = VEC_lower_bound (constraint_edge_t, succvec, &edge,
00833 constraint_edge_less);
00834
00835
00836 #ifdef ENABLE_CHECKING
00837 {
00838 constraint_edge_t tmp = VEC_index (constraint_edge_t, succvec, place);
00839 gcc_assert (constraint_edge_equal (*tmp, edge));
00840 }
00841 #endif
00842 VEC_ordered_remove (constraint_edge_t, succvec, place);
00843
00844
00845 place = VEC_lower_bound (constraint_edge_t, predvec, &edge,
00846 constraint_edge_less);
00847
00848
00849 #ifdef ENABLE_CHECKING
00850 {
00851 constraint_edge_t tmp = VEC_index (constraint_edge_t, predvec, place);
00852 gcc_assert (constraint_edge_equal (*tmp, edge));
00853 }
00854 #endif
00855 VEC_ordered_remove (constraint_edge_t, predvec, place);
00856 }
00857
00858
00859
00860 static void
00861 clear_edges_for_node (constraint_graph_t graph, unsigned int node)
00862 {
00863 VEC(constraint_edge_t,heap) *succvec = graph->succs[node];
00864 VEC(constraint_edge_t,heap) *predvec = graph->preds[node];
00865 bitmap_iterator bi;
00866 unsigned int j;
00867 constraint_edge_t c = NULL;
00868 int i;
00869
00870
00871
00872 EXECUTE_IF_IN_NONNULL_BITMAP (graph->zero_weight_succs[node], 0, j, bi)
00873 if (j != node)
00874 bitmap_clear_bit (graph->zero_weight_preds[j], node);
00875
00876 for (i = 0; VEC_iterate (constraint_edge_t, succvec, i, c); i++)
00877 if (c->dest != node)
00878 {
00879 unsigned int place;
00880 struct constraint_edge lookfor;
00881 constraint_edge_t result;
00882
00883 lookfor.dest = node;
00884 place = VEC_lower_bound (constraint_edge_t, graph->preds[c->dest],
00885 &lookfor, constraint_edge_less);
00886 result = VEC_ordered_remove (constraint_edge_t,
00887 graph->preds[c->dest], place);
00888 pool_free (constraint_edge_pool, result);
00889 }
00890
00891
00892
00893 EXECUTE_IF_IN_NONNULL_BITMAP (graph->zero_weight_preds[node], 0, j, bi)
00894 if (j != node)
00895 bitmap_clear_bit (graph->zero_weight_succs[j], node);
00896
00897 for (i =0; VEC_iterate (constraint_edge_t, predvec, i, c); i++)
00898 if (c->dest != node)
00899 {
00900 unsigned int place;
00901 struct constraint_edge lookfor;
00902 constraint_edge_t result;
00903
00904 lookfor.dest = node;
00905 place = VEC_lower_bound (constraint_edge_t, graph->succs[c->dest],
00906 &lookfor, constraint_edge_less);
00907 result = VEC_ordered_remove (constraint_edge_t,
00908 graph->succs[c->dest], place);
00909 pool_free (constraint_edge_pool, result);
00910
00911 }
00912
00913 if (graph->zero_weight_preds[node])
00914 {
00915 BITMAP_FREE (graph->zero_weight_preds[node]);
00916 graph->zero_weight_preds[node] = NULL;
00917 }
00918
00919 if (graph->zero_weight_succs[node])
00920 {
00921 BITMAP_FREE (graph->zero_weight_succs[node]);
00922 graph->zero_weight_succs[node] = NULL;
00923 }
00924
00925 VEC_free (constraint_edge_t, heap, graph->preds[node]);
00926 VEC_free (constraint_edge_t, heap, graph->succs[node]);
00927 graph->preds[node] = NULL;
00928 graph->succs[node] = NULL;
00929 }
00930
00931 static bool edge_added = false;
00932
00933
00934
00935 static bool
00936 add_graph_edge (constraint_graph_t graph, unsigned int src, unsigned int dest)
00937 {
00938 unsigned int place;
00939 VEC(constraint_edge_t,heap) *vec;
00940 struct constraint_edge newe;
00941 newe.dest = dest;
00942
00943 vec = graph->preds[src];
00944 place = VEC_lower_bound (constraint_edge_t, vec, &newe,
00945 constraint_edge_less);
00946 if (place == VEC_length (constraint_edge_t, vec)
00947 || VEC_index (constraint_edge_t, vec, place)->dest != dest)
00948 {
00949 constraint_edge_t edge = new_constraint_edge (dest);
00950
00951 VEC_safe_insert (constraint_edge_t, heap, graph->preds[src],
00952 place, edge);
00953 edge = new_constraint_edge (src);
00954
00955 place = VEC_lower_bound (constraint_edge_t, graph->succs[dest],
00956 edge, constraint_edge_less);
00957 VEC_safe_insert (constraint_edge_t, heap, graph->succs[dest],
00958 place, edge);
00959 edge_added = true;
00960 stats.num_edges++;
00961 return true;
00962 }
00963 else
00964 return false;
00965 }
00966
00967
00968
00969
00970 static bitmap *
00971 get_graph_weights (constraint_graph_t graph, unsigned int src,
00972 unsigned int dest)
00973 {
00974 constraint_edge_t edge;
00975 VEC(constraint_edge_t,heap) *vec;
00976 struct constraint_edge lookfor;
00977
00978 lookfor.dest = dest;
00979
00980 vec = graph->preds[src];
00981 edge = constraint_edge_vec_find (vec, lookfor);
00982 gcc_assert (edge != NULL);
00983 return &edge->weights;
00984 }
00985
00986
00987
00988
00989
00990 static bitmap
00991 allocate_graph_weights (constraint_graph_t graph, unsigned int src,
00992 unsigned int dest)
00993 {
00994 bitmap result;
00995 constraint_edge_t edge;
00996 VEC(constraint_edge_t,heap) *vec;
00997 struct constraint_edge lookfor;
00998
00999 result = BITMAP_ALLOC (&ptabitmap_obstack);
01000
01001
01002 lookfor.dest = dest;
01003 vec = graph->preds[src];
01004 edge = constraint_edge_vec_find (vec, lookfor);
01005 gcc_assert (edge != NULL);
01006 edge->weights = result;
01007
01008
01009 lookfor.dest = src;
01010 vec = graph->succs[dest];
01011 edge = constraint_edge_vec_find (vec, lookfor);
01012 gcc_assert (edge != NULL);
01013 edge->weights = result;
01014
01015 return result;
01016 }
01017
01018
01019
01020
01021 static void
01022 merge_graph_nodes (constraint_graph_t graph, unsigned int to,
01023 unsigned int from)
01024 {
01025 VEC(constraint_edge_t,heap) *succvec = graph->succs[from];
01026 VEC(constraint_edge_t,heap) *predvec = graph->preds[from];
01027 int i;
01028 constraint_edge_t c;
01029 unsigned int j;
01030 bitmap_iterator bi;
01031
01032
01033 if (graph->zero_weight_preds[from])
01034 {
01035 if (!graph->zero_weight_preds[to])
01036 graph->zero_weight_preds[to] = BITMAP_ALLOC (&predbitmap_obstack);
01037
01038 EXECUTE_IF_SET_IN_BITMAP (graph->zero_weight_preds[from], 0, j, bi)
01039 {
01040 if (j != to)
01041 {
01042 bitmap_clear_bit (graph->zero_weight_succs[j], from);
01043 bitmap_set_bit (graph->zero_weight_succs[j], to);
01044 }
01045 }
01046 bitmap_ior_into (graph->zero_weight_preds[to],
01047 graph->zero_weight_preds[from]);
01048 }
01049
01050
01051 if (graph->zero_weight_succs[from])
01052 {
01053 if (!graph->zero_weight_succs[to])
01054 graph->zero_weight_succs[to] = BITMAP_ALLOC (&ptabitmap_obstack);
01055 EXECUTE_IF_SET_IN_BITMAP (graph->zero_weight_succs[from], 0, j, bi)
01056 {
01057 bitmap_clear_bit (graph->zero_weight_preds[j], from);
01058 bitmap_set_bit (graph->zero_weight_preds[j], to);
01059 }
01060 bitmap_ior_into (graph->zero_weight_succs[to],
01061 graph->zero_weight_succs[from]);
01062 }
01063
01064
01065 for (i = 0; VEC_iterate (constraint_edge_t, predvec, i, c); i++)
01066 {
01067 unsigned int d = c->dest;
01068 bitmap temp;
01069 bitmap *weights;
01070
01071 if (c->dest == from)
01072 d = to;
01073
01074 add_graph_edge (graph, to, d);
01075
01076 temp = *(get_graph_weights (graph, from, c->dest));
01077 if (temp)
01078 {
01079 weights = get_graph_weights (graph, to, d);
01080 if (!*weights)
01081 *weights = allocate_graph_weights (graph, to, d);
01082
01083 bitmap_ior_into (*weights, temp);
01084 }
01085
01086 }
01087
01088
01089 for (i = 0; VEC_iterate (constraint_edge_t, succvec, i, c); i++)
01090 {
01091 unsigned int d = c->dest;
01092 bitmap temp;
01093 bitmap *weights;
01094
01095 if (c->dest == from)
01096 d = to;
01097
01098 add_graph_edge (graph, d, to);
01099
01100 temp = *(get_graph_weights (graph, c->dest, from));
01101 if (temp)
01102 {
01103 weights = get_graph_weights (graph, d, to);
01104 if (!*weights)
01105 *weights = allocate_graph_weights (graph, d, to);
01106 bitmap_ior_into (*weights, temp);
01107 }
01108 }
01109 clear_edges_for_node (graph, from);
01110 }
01111
01112
01113
01114
01115
01116 static bool
01117 int_add_graph_edge (constraint_graph_t graph, unsigned int to,
01118 unsigned int from, unsigned HOST_WIDE_INT weight)
01119 {
01120 if (to == from && weight == 0)
01121 {
01122 return false;
01123 }
01124 else
01125 {
01126 bool r = false;
01127
01128 if (weight == 0)
01129 {
01130 if (!graph->zero_weight_preds[to])
01131 graph->zero_weight_preds[to] = BITMAP_ALLOC (&predbitmap_obstack);
01132 if (!graph->zero_weight_succs[from])
01133 graph->zero_weight_succs[from] = BITMAP_ALLOC (&ptabitmap_obstack);
01134 if (!bitmap_bit_p (graph->zero_weight_succs[from], to))
01135 {
01136 edge_added = true;
01137 r = true;
01138 stats.num_edges++;
01139 bitmap_set_bit (graph->zero_weight_preds[to], from);
01140 bitmap_set_bit (graph->zero_weight_succs[from], to);
01141 }
01142 }
01143 else
01144 {
01145 bitmap *weights;
01146
01147 r = add_graph_edge (graph, to, from);
01148 weights = get_graph_weights (graph, to, from);
01149
01150 if (!*weights)
01151 {
01152 r = true;
01153 *weights = allocate_graph_weights (graph, to, from);
01154 bitmap_set_bit (*weights, weight);
01155 }
01156 else
01157 {
01158 r |= !bitmap_bit_p (*weights, weight);
01159 bitmap_set_bit (*weights, weight);
01160 }
01161 }
01162
01163 return r;
01164 }
01165 }
01166
01167
01168
01169
01170 static bool
01171 valid_graph_edge (constraint_graph_t graph, unsigned int src,
01172 unsigned int dest)
01173 {
01174 struct constraint_edge lookfor;
01175 lookfor.dest = src;
01176
01177 return (graph->zero_weight_succs[dest]
01178 && bitmap_bit_p (graph->zero_weight_succs[dest], src))
01179 || constraint_edge_vec_find (graph->succs[dest], lookfor) != NULL;
01180 }
01181
01182
01183
01184 static bool
01185 valid_weighted_graph_edge (constraint_graph_t graph, unsigned int src,
01186 unsigned int dest)
01187 {
01188 struct constraint_edge lookfor;
01189 lookfor.dest = src;
01190
01191 return graph->preds[src]
01192 && constraint_edge_vec_find (graph->succs[dest], lookfor) != NULL;
01193 }
01194
01195
01196
01197
01198 static void
01199 build_constraint_graph (void)
01200 {
01201 int i = 0;
01202 constraint_t c;
01203
01204 graph = XNEW (struct constraint_graph);
01205 graph_size = VEC_length (varinfo_t, varmap) + 1;
01206 graph->succs = XCNEWVEC (VEC(constraint_edge_t,heap) *, graph_size);
01207 graph->preds = XCNEWVEC (VEC(constraint_edge_t,heap) *, graph_size);
01208 graph->zero_weight_succs = XCNEWVEC (bitmap, graph_size);
01209 graph->zero_weight_preds = XCNEWVEC (bitmap, graph_size);
01210
01211 for (i = 0; VEC_iterate (constraint_t, constraints, i, c); i++)
01212 {
01213 struct constraint_expr lhs = c->lhs;
01214 struct constraint_expr rhs = c->rhs;
01215 unsigned int lhsvar = get_varinfo_fc (lhs.var)->id;
01216 unsigned int rhsvar = get_varinfo_fc (rhs.var)->id;
01217
01218 if (lhs.type == DEREF)
01219 {
01220
01221 if (rhs.type == ADDRESSOF || rhsvar > anything_id)
01222 insert_into_complex (lhsvar, c);
01223 }
01224 else if (rhs.type == DEREF)
01225 {
01226
01227 if (!(get_varinfo (lhsvar)->is_special_var))
01228 insert_into_complex (rhsvar, c);
01229 }
01230 else if (rhs.type == ADDRESSOF)
01231 {
01232
01233 bitmap_set_bit (get_varinfo (lhsvar)->solution, rhsvar);
01234 }
01235 else if (lhsvar > anything_id)
01236 {
01237
01238
01239 if (lhsvar != rhsvar || rhs.offset != 0 || lhs.offset != 0)
01240 {
01241
01242 int_add_graph_edge (graph, lhs.var, rhs.var, rhs.offset);
01243 }
01244
01245 }
01246 }
01247 }
01248
01249
01250
01251 static unsigned int changed_count;
01252 static sbitmap changed;
01253
01254 DEF_VEC_I(unsigned);
01255 DEF_VEC_ALLOC_I(unsigned,heap);
01256
01257
01258
01259
01260 struct scc_info
01261 {
01262 sbitmap visited;
01263 sbitmap in_component;
01264 int current_index;
01265 unsigned int *visited_index;
01266 VEC(unsigned,heap) *scc_stack;
01267 VEC(unsigned,heap) *unification_queue;
01268 };
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282 static void
01283 scc_visit (constraint_graph_t graph, struct scc_info *si, unsigned int n)
01284 {
01285 unsigned int i;
01286 bitmap_iterator bi;
01287
01288 gcc_assert (get_varinfo (n)->node == n);
01289 SET_BIT (si->visited, n);
01290 RESET_BIT (si->in_component, n);
01291 si->visited_index[n] = si->current_index ++;
01292
01293
01294 EXECUTE_IF_IN_NONNULL_BITMAP (graph->zero_weight_succs[n], 0, i, bi)
01295 {
01296 unsigned int w = i;
01297 if (!TEST_BIT (si->visited, w))
01298 scc_visit (graph, si, w);
01299 if (!TEST_BIT (si->in_component, w))
01300 {
01301 unsigned int t = get_varinfo (w)->node;
01302 unsigned int nnode = get_varinfo (n)->node;
01303 if (si->visited_index[t] < si->visited_index[nnode])
01304 get_varinfo (n)->node = t;
01305 }
01306 }
01307
01308
01309 if (get_varinfo (n)->node == n)
01310 {
01311 unsigned int t = si->visited_index[n];
01312 SET_BIT (si->in_component, n);
01313 while (VEC_length (unsigned, si->scc_stack) != 0
01314 && t < si->visited_index[VEC_last (unsigned, si->scc_stack)])
01315 {
01316 unsigned int w = VEC_pop (unsigned, si->scc_stack);
01317 get_varinfo (w)->node = n;
01318 SET_BIT (si->in_component, w);
01319
01320 VEC_safe_push (unsigned, heap, si->unification_queue, w);
01321 }
01322 }
01323 else
01324 VEC_safe_push (unsigned, heap, si->scc_stack, n);
01325 }
01326
01327
01328
01329
01330 static void
01331 collapse_nodes (constraint_graph_t graph, unsigned int to, unsigned int from)
01332 {
01333 bitmap tosol, fromsol;
01334
01335 condense_varmap_nodes (to, from);
01336 tosol = get_varinfo (to)->solution;
01337 fromsol = get_varinfo (from)->solution;
01338 bitmap_ior_into (tosol, fromsol);
01339 merge_graph_nodes (graph, to, from);
01340
01341 if (valid_graph_edge (graph, to, to))
01342 {
01343 if (graph->zero_weight_preds[to])
01344 {
01345 bitmap_clear_bit (graph->zero_weight_preds[to], to);
01346 bitmap_clear_bit (graph->zero_weight_succs[to], to);
01347 }
01348 if (valid_weighted_graph_edge (graph, to, to))
01349 {
01350 bitmap weights = *(get_graph_weights (graph, to, to));
01351 if (!weights || bitmap_empty_p (weights))
01352 erase_graph_self_edge (graph, to);
01353 }
01354 }
01355 BITMAP_FREE (fromsol);
01356 get_varinfo (to)->address_taken |= get_varinfo (from)->address_taken;
01357 get_varinfo (to)->indirect_target |= get_varinfo (from)->indirect_target;
01358 }
01359
01360
01361
01362
01363
01364
01365
01366
01367 static void
01368 process_unification_queue (constraint_graph_t graph, struct scc_info *si,
01369 bool update_changed)
01370 {
01371 size_t i = 0;
01372 bitmap tmp = BITMAP_ALLOC (update_changed ? &iteration_obstack : NULL);
01373 bitmap_clear (tmp);
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398 while (i != VEC_length (unsigned, si->unification_queue))
01399 {
01400 unsigned int tounify = VEC_index (unsigned, si->unification_queue, i);
01401 unsigned int n = get_varinfo (tounify)->node;
01402
01403 if (dump_file && (dump_flags & TDF_DETAILS))
01404 fprintf (dump_file, "Unifying %s to %s\n",
01405 get_varinfo (tounify)->name,
01406 get_varinfo (n)->name);
01407 if (update_changed)
01408 stats.unified_vars_dynamic++;
01409 else
01410 stats.unified_vars_static++;
01411 bitmap_ior_into (tmp, get_varinfo (tounify)->solution);
01412 merge_graph_nodes (graph, n, tounify);
01413 condense_varmap_nodes (n, tounify);
01414
01415 if (update_changed && TEST_BIT (changed, tounify))
01416 {
01417 RESET_BIT (changed, tounify);
01418 if (!TEST_BIT (changed, n))
01419 SET_BIT (changed, n);
01420 else
01421 {
01422 gcc_assert (changed_count > 0);
01423 changed_count--;
01424 }
01425 }
01426
01427 bitmap_clear (get_varinfo (tounify)->solution);
01428 ++i;
01429
01430
01431
01432
01433 if (i == VEC_length (unsigned, si->unification_queue)
01434 || get_varinfo (VEC_index (unsigned, si->unification_queue, i))->node != n)
01435 {
01436
01437
01438 if (bitmap_ior_into (get_varinfo (n)->solution, tmp))
01439 {
01440 if (update_changed && !TEST_BIT (changed, n))
01441 {
01442 SET_BIT (changed, n);
01443 changed_count++;
01444 }
01445 }
01446 bitmap_clear (tmp);
01447
01448 if (valid_graph_edge (graph, n, n))
01449 {
01450 if (graph->zero_weight_succs[n])
01451 {
01452 if (graph->zero_weight_preds[n])
01453 bitmap_clear_bit (graph->zero_weight_preds[n], n);
01454 bitmap_clear_bit (graph->zero_weight_succs[n], n);
01455 }
01456 if (valid_weighted_graph_edge (graph, n, n))
01457 {
01458 bitmap weights = *(get_graph_weights (graph, n, n));
01459 if (!weights || bitmap_empty_p (weights))
01460 erase_graph_self_edge (graph, n);
01461 }
01462 }
01463 }
01464 }
01465 BITMAP_FREE (tmp);
01466 }
01467
01468
01469
01470
01471 struct topo_info
01472 {
01473
01474 sbitmap visited;
01475
01476
01477 VEC(unsigned,heap) *topo_order;
01478 };
01479
01480
01481
01482
01483 static struct topo_info *
01484 init_topo_info (void)
01485 {
01486 size_t size = VEC_length (varinfo_t, varmap);
01487 struct topo_info *ti = XNEW (struct topo_info);
01488 ti->visited = sbitmap_alloc (size);
01489 sbitmap_zero (ti->visited);
01490 ti->topo_order = VEC_alloc (unsigned, heap, 1);
01491 return ti;
01492 }
01493
01494
01495
01496
01497 static void
01498 free_topo_info (struct topo_info *ti)
01499 {
01500 sbitmap_free (ti->visited);
01501 VEC_free (unsigned, heap, ti->topo_order);
01502 free (ti);
01503 }
01504
01505
01506
01507
01508 static void
01509 topo_visit (constraint_graph_t graph, struct topo_info *ti,
01510 unsigned int n)
01511 {
01512 VEC(constraint_edge_t,heap) *succs = graph->succs[n];
01513 bitmap temp;
01514 bitmap_iterator bi;
01515 constraint_edge_t c;
01516 int i;
01517 unsigned int j;
01518
01519 SET_BIT (ti->visited, n);
01520 if (VEC_length (constraint_edge_t, succs) != 0)
01521 {
01522 temp = BITMAP_ALLOC (&iteration_obstack);
01523 if (graph->zero_weight_succs[n])
01524 bitmap_ior_into (temp, graph->zero_weight_succs[n]);
01525 for (i = 0; VEC_iterate (constraint_edge_t, succs, i, c); i++)
01526 bitmap_set_bit (temp, c->dest);
01527 }
01528 else
01529 temp = graph->zero_weight_succs[n];
01530
01531 if (temp)
01532 EXECUTE_IF_SET_IN_BITMAP (temp, 0, j, bi)
01533 {
01534 if (!TEST_BIT (ti->visited, j))
01535 topo_visit (graph, ti, j);
01536 }
01537 VEC_safe_push (unsigned, heap, ti->topo_order, n);
01538 }
01539
01540
01541
01542 static bool
01543 type_safe (unsigned int n, unsigned HOST_WIDE_INT *offset)
01544 {
01545 varinfo_t ninfo = get_varinfo (n);
01546
01547
01548
01549
01550 if (ninfo->is_special_var
01551 || ninfo->is_artificial_var
01552 || ninfo->is_unknown_size_var)
01553 {
01554 *offset = 0;
01555 return true;
01556 }
01557 return (get_varinfo (n)->offset + *offset) < get_varinfo (n)->fullsize;
01558 }
01559
01560
01561
01562 static void
01563 do_da_constraint (constraint_graph_t graph ATTRIBUTE_UNUSED,
01564 constraint_t c, bitmap delta)
01565 {
01566 unsigned int rhs = c->rhs.var;
01567 unsigned int j;
01568 bitmap_iterator bi;
01569
01570
01571 EXECUTE_IF_SET_IN_BITMAP (delta, 0, j, bi)
01572 {
01573 unsigned HOST_WIDE_INT offset = c->lhs.offset;
01574 if (type_safe (j, &offset) && !(get_varinfo (j)->is_special_var))
01575 {
01576
01577 varinfo_t v;
01578 unsigned int t;
01579 bitmap sol;
01580 unsigned HOST_WIDE_INT fieldoffset = get_varinfo (j)->offset + offset;
01581
01582 v = first_vi_for_offset (get_varinfo (j), fieldoffset);
01583 if (!v)
01584 continue;
01585 t = v->node;
01586 sol = get_varinfo (t)->solution;
01587 if (!bitmap_bit_p (sol, rhs))
01588 {
01589 bitmap_set_bit (sol, rhs);
01590 if (!TEST_BIT (changed, t))
01591 {
01592 SET_BIT (changed, t);
01593 changed_count++;
01594 }
01595 }
01596 }
01597 else if (0 && dump_file && !(get_varinfo (j)->is_special_var))
01598 fprintf (dump_file, "Untypesafe usage in do_da_constraint.\n");
01599
01600 }
01601 }
01602
01603
01604
01605
01606 static void
01607 do_sd_constraint (constraint_graph_t graph, constraint_t c,
01608 bitmap delta)
01609 {
01610 unsigned int lhs = get_varinfo (c->lhs.var)->node;
01611 bool flag = false;
01612 bitmap sol = get_varinfo (lhs)->solution;
01613 unsigned int j;
01614 bitmap_iterator bi;
01615
01616 if (bitmap_bit_p (delta, anything_id))
01617 {
01618 flag = !bitmap_bit_p (sol, anything_id);
01619 if (flag)
01620 bitmap_set_bit (sol, anything_id);
01621 goto done;
01622 }
01623
01624
01625 EXECUTE_IF_SET_IN_BITMAP (delta, 0, j, bi)
01626 {
01627 unsigned HOST_WIDE_INT roffset = c->rhs.offset;
01628 if (type_safe (j, &roffset))
01629 {
01630 varinfo_t v;
01631 unsigned HOST_WIDE_INT fieldoffset = get_varinfo (j)->offset + roffset;
01632 unsigned int t;
01633
01634 v = first_vi_for_offset (get_varinfo (j), fieldoffset);
01635 if (!v)
01636 continue;
01637 t = v->node;
01638
01639
01640
01641 if (get_varinfo (t) ->is_special_var)
01642 flag |= bitmap_ior_into (sol, get_varinfo (t)->solution);
01643 else if (int_add_graph_edge (graph, lhs, t, 0))
01644 flag |= bitmap_ior_into (sol, get_varinfo (t)->solution);
01645 }
01646 else if (0 && dump_file && !(get_varinfo (j)->is_special_var))
01647 fprintf (dump_file, "Untypesafe usage in do_sd_constraint\n");
01648
01649 }
01650
01651 done:
01652
01653 if (flag)
01654 {
01655 get_varinfo (lhs)->solution = sol;
01656 if (!TEST_BIT (changed, lhs))
01657 {
01658 SET_BIT (changed, lhs);
01659 changed_count++;
01660 }
01661 }
01662 }
01663
01664
01665
01666 static void
01667 do_ds_constraint (constraint_graph_t graph, constraint_t c, bitmap delta)
01668 {
01669 unsigned int rhs = get_varinfo (c->rhs.var)->node;
01670 unsigned HOST_WIDE_INT roff = c->rhs.offset;
01671 bitmap sol = get_varinfo (rhs)->solution;
01672 unsigned int j;
01673 bitmap_iterator bi;
01674
01675 if (bitmap_bit_p (sol, anything_id))
01676 {
01677 EXECUTE_IF_SET_IN_BITMAP (delta, 0, j, bi)
01678 {
01679 varinfo_t jvi = get_varinfo (j);
01680 unsigned int t;
01681 unsigned int loff = c->lhs.offset;
01682 unsigned HOST_WIDE_INT fieldoffset = jvi->offset + loff;
01683 varinfo_t v;
01684
01685 v = first_vi_for_offset (get_varinfo (j), fieldoffset);
01686 if (!v)
01687 continue;
01688 t = v->node;
01689
01690 if (!bitmap_bit_p (get_varinfo (t)->solution, anything_id))
01691 {
01692 bitmap_set_bit (get_varinfo (t)->solution, anything_id);
01693 if (!TEST_BIT (changed, t))
01694 {
01695 SET_BIT (changed, t);
01696 changed_count++;
01697 }
01698 }
01699 }
01700 return;
01701 }
01702
01703
01704
01705 EXECUTE_IF_SET_IN_BITMAP (delta, 0, j, bi)
01706 {
01707 unsigned HOST_WIDE_INT loff = c->lhs.offset;
01708 if (type_safe (j, &loff) && !(get_varinfo(j)->is_special_var))
01709 {
01710 varinfo_t v;
01711 unsigned int t;
01712 unsigned HOST_WIDE_INT fieldoffset = get_varinfo (j)->offset + loff;
01713
01714 v = first_vi_for_offset (get_varinfo (j), fieldoffset);
01715 if (!v)
01716 continue;
01717 t = v->node;
01718 if (int_add_graph_edge (graph, t, rhs, roff))
01719 {
01720 bitmap tmp = get_varinfo (t)->solution;
01721 if (set_union_with_increment (tmp, sol, roff))
01722 {
01723 get_varinfo (t)->solution = tmp;
01724 if (t == rhs)
01725 sol = get_varinfo (rhs)->solution;
01726 if (!TEST_BIT (changed, t))
01727 {
01728 SET_BIT (changed, t);
01729 changed_count++;
01730 }
01731 }
01732 }
01733 }
01734 else if (0 && dump_file && !(get_varinfo (j)->is_special_var))
01735 fprintf (dump_file, "Untypesafe usage in do_ds_constraint\n");
01736 }
01737 }
01738
01739
01740
01741
01742 static void
01743 do_complex_constraint (constraint_graph_t graph, constraint_t c, bitmap delta)
01744 {
01745 if (c->lhs.type == DEREF)
01746 {
01747 if (c->rhs.type == ADDRESSOF)
01748 {
01749
01750 do_da_constraint (graph, c, delta);
01751 }
01752 else
01753 {
01754
01755 do_ds_constraint (graph, c, delta);
01756 }
01757 }
01758 else
01759 {
01760
01761 if (!(get_varinfo (c->lhs.var)->is_special_var))
01762 do_sd_constraint (graph, c, delta);
01763 }
01764 }
01765
01766
01767
01768 static struct scc_info *
01769 init_scc_info (void)
01770 {
01771 struct scc_info *si = XNEW (struct scc_info);
01772 size_t size = VEC_length (varinfo_t, varmap);
01773
01774 si->current_index = 0;
01775 si->visited = sbitmap_alloc (size);
01776 sbitmap_zero (si->visited);
01777 si->in_component = sbitmap_alloc (size);
01778 sbitmap_ones (si->in_component);
01779 si->visited_index = XCNEWVEC (unsigned int, size + 1);
01780 si->scc_stack = VEC_alloc (unsigned, heap, 1);
01781 si->unification_queue = VEC_alloc (unsigned, heap, 1);
01782 return si;
01783 }
01784
01785
01786
01787 static void
01788 free_scc_info (struct scc_info *si)
01789 {
01790 sbitmap_free (si->visited);
01791 sbitmap_free (si->in_component);
01792 free (si->visited_index);
01793 VEC_free (unsigned, heap, si->scc_stack);
01794 VEC_free (unsigned, heap, si->unification_queue);
01795 free(si);
01796 }
01797
01798
01799
01800
01801
01802
01803
01804 static void
01805 find_and_collapse_graph_cycles (constraint_graph_t graph, bool update_changed)
01806 {
01807 unsigned int i;
01808 unsigned int size = VEC_length (varinfo_t, varmap);
01809 struct scc_info *si = init_scc_info ();
01810
01811 for (i = 0; i != size; ++i)
01812 if (!TEST_BIT (si->visited, i) && get_varinfo (i)->node == i)
01813 scc_visit (graph, si, i);
01814
01815 process_unification_queue (graph, si, update_changed);
01816 free_scc_info (si);
01817 }
01818
01819
01820
01821
01822 static void
01823 compute_topo_order (constraint_graph_t graph,
01824 struct topo_info *ti)
01825 {
01826 unsigned int i;
01827 unsigned int size = VEC_length (varinfo_t, varmap);
01828
01829 for (i = 0; i != size; ++i)
01830 if (!TEST_BIT (ti->visited, i) && get_varinfo (i)->node == i)
01831 topo_visit (graph, ti, i);
01832 }
01833
01834
01835
01836 static bool
01837 bitmap_other_than_zero_bit_set (bitmap b)
01838 {
01839 unsigned int i;
01840 bitmap_iterator bi;
01841
01842 if (bitmap_empty_p (b))
01843 return false;
01844 EXECUTE_IF_SET_IN_BITMAP (b, 1, i, bi)
01845 return true;
01846 return false;
01847 }
01848
01849
01850
01851
01852
01853
01854
01855
01856
01857
01858
01859 static void
01860 perform_var_substitution (constraint_graph_t graph)
01861 {
01862 struct topo_info *ti = init_topo_info ();
01863
01864 bitmap_obstack_initialize (&iteration_obstack);
01865
01866
01867 compute_topo_order (graph, ti);
01868
01869 while (VEC_length (unsigned, ti->topo_order) != 0)
01870 {
01871 unsigned int i = VEC_pop (unsigned, ti->topo_order);
01872 unsigned int pred;
01873 varinfo_t vi = get_varinfo (i);
01874 bool okay_to_elim = false;
01875 unsigned int root = VEC_length (varinfo_t, varmap);
01876 VEC(constraint_edge_t,heap) *predvec = graph->preds[i];
01877 constraint_edge_t ce = NULL;
01878 bitmap tmp;
01879 unsigned int k;
01880 bitmap_iterator bi;
01881
01882
01883
01884 if (vi->address_taken || vi->indirect_target)
01885 continue;
01886
01887
01888 EXECUTE_IF_IN_NONNULL_BITMAP (graph->zero_weight_preds[i], 0, k, bi)
01889 {
01890 unsigned int w;
01891 w = get_varinfo (k)->node;
01892
01893
01894
01895 if (!okay_to_elim)
01896 {
01897 root = w;
01898 okay_to_elim = true;
01899 }
01900 else if (w != root)
01901 {
01902 okay_to_elim = false;
01903 break;
01904 }
01905
01906
01907
01908
01909
01910
01911
01912 tmp = BITMAP_ALLOC (NULL);
01913 bitmap_and_compl (tmp, get_varinfo (i)->solution,
01914 get_varinfo (w)->solution);
01915 if (!bitmap_empty_p (tmp))
01916 {
01917 okay_to_elim = false;
01918 BITMAP_FREE (tmp);
01919 break;
01920 }
01921 BITMAP_FREE (tmp);
01922 }
01923
01924 if (okay_to_elim)
01925 for (pred = 0;
01926 VEC_iterate (constraint_edge_t, predvec, pred, ce);
01927 pred++)
01928 {
01929 bitmap weight;
01930 unsigned int w;
01931 weight = *(get_graph_weights (graph, i, ce->dest));
01932
01933
01934
01935 if (weight && bitmap_other_than_zero_bit_set (weight))
01936 {
01937 okay_to_elim = false;
01938 break;
01939 }
01940 w = get_varinfo (ce->dest)->node;
01941
01942
01943
01944 if (!okay_to_elim)
01945 {
01946 root = w;
01947 okay_to_elim = true;
01948 }
01949 else if (w != root)
01950 {
01951 okay_to_elim = false;
01952 break;
01953 }
01954
01955
01956
01957
01958
01959
01960
01961 tmp = BITMAP_ALLOC (NULL);
01962 bitmap_and_compl (tmp, get_varinfo (i)->solution,
01963 get_varinfo (w)->solution);
01964 if (!bitmap_empty_p (tmp))
01965 {
01966 okay_to_elim = false;
01967 BITMAP_FREE (tmp);
01968 break;
01969 }
01970 BITMAP_FREE (tmp);
01971 }
01972
01973
01974
01975 if (root != get_varinfo (i)->node && okay_to_elim)
01976 {
01977
01978 get_varinfo (i)->node = root;
01979 collapse_nodes (graph, root, i);
01980 if (dump_file && (dump_flags & TDF_DETAILS))
01981 fprintf (dump_file, "Collapsing %s into %s\n",
01982 get_varinfo (i)->name,
01983 get_varinfo (root)->name);
01984 stats.collapsed_vars++;
01985 }
01986 }
01987
01988 bitmap_obstack_release (&iteration_obstack);
01989 free_topo_info (ti);
01990 }
01991
01992
01993
01994
01995
01996
01997
01998
01999 static void
02000 solve_graph (constraint_graph_t graph)
02001 {
02002 unsigned int size = VEC_length (varinfo_t, varmap);
02003 unsigned int i;
02004
02005 changed_count = size;
02006 changed = sbitmap_alloc (size);
02007 sbitmap_ones (changed);
02008
02009
02010
02011 for (i = 0; i < size; i++)
02012 if (get_varinfo (i)->node != i)
02013 changed_count--;
02014
02015 while (changed_count > 0)
02016 {
02017 unsigned int i;
02018 struct topo_info *ti = init_topo_info ();
02019 stats.iterations++;
02020
02021 bitmap_obstack_initialize (&iteration_obstack);
02022
02023 if (edge_added)
02024 {
02025
02026
02027
02028 if (stats.iterations > 1)
02029 find_and_collapse_graph_cycles (graph, true);
02030
02031 edge_added = false;
02032 }
02033
02034 compute_topo_order (graph, ti);
02035
02036 while (VEC_length (unsigned, ti->topo_order) != 0)
02037 {
02038 i = VEC_pop (unsigned, ti->topo_order);
02039 gcc_assert (get_varinfo (i)->node == i);
02040
02041
02042
02043 if (TEST_BIT (changed, i))
02044 {
02045 unsigned int j;
02046 constraint_t c;
02047 constraint_edge_t e = NULL;
02048 bitmap solution;
02049 bitmap_iterator bi;
02050 VEC(constraint_t,heap) *complex = get_varinfo (i)->complex;
02051 VEC(constraint_edge_t,heap) *succs;
02052 bool solution_empty;
02053
02054 RESET_BIT (changed, i);
02055 changed_count--;
02056
02057 solution = get_varinfo (i)->solution;
02058 solution_empty = bitmap_empty_p (solution);
02059
02060
02061 for (j = 0; VEC_iterate (constraint_t, complex, j, c); j++)
02062 {
02063
02064
02065
02066
02067 if (!solution_empty || c->lhs.type != DEREF)
02068 do_complex_constraint (graph, c, solution);
02069 }
02070
02071 solution_empty = bitmap_empty_p (solution);
02072
02073 if (!solution_empty)
02074 {
02075
02076 succs = graph->succs[i];
02077
02078 EXECUTE_IF_IN_NONNULL_BITMAP (graph->zero_weight_succs[i],
02079 0, j, bi)
02080 {
02081 bitmap tmp = get_varinfo (j)->solution;
02082 bool flag = false;
02083
02084 flag = set_union_with_increment (tmp, solution, 0);
02085
02086 if (flag)
02087 {
02088 get_varinfo (j)->solution = tmp;
02089 if (!TEST_BIT (changed, j))
02090 {
02091 SET_BIT (changed, j);
02092 changed_count++;
02093 }
02094 }
02095 }
02096 for (j = 0; VEC_iterate (constraint_edge_t, succs, j, e); j++)
02097 {
02098 bitmap tmp = get_varinfo (e->dest)->solution;
02099 bool flag = false;
02100 unsigned int k;
02101 bitmap weights = e->weights;
02102 bitmap_iterator bi;
02103
02104 gcc_assert (weights && !bitmap_empty_p (weights));
02105 EXECUTE_IF_SET_IN_BITMAP (weights, 0, k, bi)
02106 flag |= set_union_with_increment (tmp, solution, k);
02107
02108 if (flag)
02109 {
02110 get_varinfo (e->dest)->solution = tmp;
02111 if (!TEST_BIT (changed, e->dest))
02112 {
02113 SET_BIT (changed, e->dest);
02114 changed_count++;
02115 }
02116 }
02117 }
02118 }
02119 }
02120 }
02121 free_topo_info (ti);
02122 bitmap_obstack_release (&iteration_obstack);
02123 }
02124
02125 sbitmap_free (changed);
02126 }
02127
02128
02129
02130
02131
02132 static htab_t id_for_tree;
02133
02134 typedef struct tree_id
02135 {
02136 tree t;
02137 unsigned int id;
02138 } *tree_id_t;
02139
02140
02141
02142 static hashval_t
02143 tree_id_hash (const void *p)
02144 {
02145 const tree_id_t ta = (tree_id_t) p;
02146 return htab_hash_pointer (ta->t);
02147 }
02148
02149
02150
02151 static int
02152 tree_id_eq (const void *p1, const void *p2)
02153 {
02154 const tree_id_t ta1 = (tree_id_t) p1;
02155 const tree_id_t ta2 = (tree_id_t) p2;
02156 return ta1->t == ta2->t;
02157 }
02158
02159
02160
02161 static void
02162 insert_id_for_tree (tree t, int id)
02163 {
02164 void **slot;
02165 struct tree_id finder;
02166 tree_id_t new_pair;
02167
02168 finder.t = t;
02169 slot = htab_find_slot (id_for_tree, &finder, INSERT);
02170 gcc_assert (*slot == NULL);
02171 new_pair = XNEW (struct tree_id);
02172 new_pair->t = t;
02173 new_pair->id = id;
02174 *slot = (void *)new_pair;
02175 }
02176
02177
02178
02179
02180
02181 static bool
02182 lookup_id_for_tree (tree t, unsigned int *id)
02183 {
02184 tree_id_t pair;
02185 struct tree_id finder;
02186
02187 finder.t = t;
02188 pair = htab_find (id_for_tree, &finder);
02189 if (pair == NULL)
02190 return false;
02191 *id = pair->id;
02192 return true;
02193 }
02194
02195
02196
02197 static const char *
02198 alias_get_name (tree decl)
02199 {
02200 const char *res = get_name (decl);
02201 char *temp;
02202 int num_printed = 0;
02203
02204 if (res != NULL)
02205 return res;
02206
02207 res = "NULL";
02208 if (!dump_file)
02209 return res;
02210
02211 if (TREE_CODE (decl) == SSA_NAME)
02212 {
02213 num_printed = asprintf (&temp, "%s_%u",
02214 alias_get_name (SSA_NAME_VAR (decl)),
02215 SSA_NAME_VERSION (decl));
02216 }
02217 else if (DECL_P (decl))
02218 {
02219 num_printed = asprintf (&temp, "D.%u", DECL_UID (decl));
02220 }
02221 if (num_printed > 0)
02222 {
02223 res = ggc_strdup (temp);
02224 free (temp);
02225 }
02226 return res;
02227 }
02228
02229
02230
02231
02232 static unsigned int
02233 get_id_for_tree (tree t)
02234 {
02235 tree_id_t pair;
02236 struct tree_id finder;
02237
02238 finder.t = t;
02239 pair = htab_find (id_for_tree, &finder);
02240 if (pair == NULL)
02241 return create_variable_info_for (t, alias_get_name (t));
02242
02243 return pair->id;
02244 }
02245
02246
02247
02248 static struct constraint_expr
02249 get_constraint_exp_from_ssa_var (tree t)
02250 {
02251 struct constraint_expr cexpr;
02252
02253 gcc_assert (SSA_VAR_P (t) || DECL_P (t));
02254
02255
02256
02257 if (TREE_CODE (t) == SSA_NAME
02258 && TREE_CODE (SSA_NAME_VAR (t)) == PARM_DECL
02259 && default_def (SSA_NAME_VAR (t)) == t)
02260 return get_constraint_exp_from_ssa_var (SSA_NAME_VAR (t));
02261
02262 cexpr.type = SCALAR;
02263
02264 cexpr.var = get_id_for_tree (t);
02265
02266
02267 if (cexpr.var == anything_id && TREE_READONLY (t))
02268 {
02269 cexpr.type = ADDRESSOF;
02270 cexpr.var = readonly_id;
02271 }
02272
02273 cexpr.offset = 0;
02274 return cexpr;
02275 }
02276
02277
02278
02279
02280 static void
02281 process_constraint (constraint_t t)
02282 {
02283 struct constraint_expr rhs = t->rhs;
02284 struct constraint_expr lhs = t->lhs;
02285
02286 gcc_assert (rhs.var < VEC_length (varinfo_t, varmap));
02287 gcc_assert (lhs.var < VEC_length (varinfo_t, varmap));
02288
02289 if (lhs.type == DEREF)
02290 get_varinfo (lhs.var)->directly_dereferenced = true;
02291 if (rhs.type == DEREF)
02292 get_varinfo (rhs.var)->directly_dereferenced = true;
02293
02294
02295 if (lhs.var == anything_id && rhs.var == anything_id)
02296 return;
02297
02298
02299 else if (lhs.var == anything_id && lhs.type == ADDRESSOF)
02300 {
02301 rhs = t->lhs;
02302 t->lhs = t->rhs;
02303 t->rhs = rhs;
02304 process_constraint (t);
02305 }
02306
02307 else if (rhs.type == DEREF && lhs.type == DEREF && rhs.var != anything_id)
02308 {
02309
02310 tree rhsdecl = get_varinfo (rhs.var)->decl;
02311 tree pointertype = TREE_TYPE (rhsdecl);
02312 tree pointedtotype = TREE_TYPE (pointertype);
02313 tree tmpvar = create_tmp_var_raw (pointedtotype, "doubledereftmp");
02314 struct constraint_expr tmplhs = get_constraint_exp_from_ssa_var (tmpvar);
02315
02316
02317
02318
02319 gcc_assert (!AGGREGATE_TYPE_P (pointedtotype)
02320 || get_varinfo (rhs.var)->is_unknown_size_var);
02321
02322 process_constraint (new_constraint (tmplhs, rhs));
02323 process_constraint (new_constraint (lhs, tmplhs));
02324 }
02325 else if (rhs.type == ADDRESSOF)
02326 {
02327 varinfo_t vi;
02328 gcc_assert (rhs.offset == 0);
02329
02330
02331
02332 if (lhs.var != escaped_vars_id)
02333 for (vi = get_varinfo (rhs.var); vi != NULL; vi = vi->next)
02334 vi->address_taken = true;
02335
02336 VEC_safe_push (constraint_t, heap, constraints, t);
02337 }
02338 else
02339 {
02340 if (lhs.type != DEREF && rhs.type == DEREF)
02341 get_varinfo (lhs.var)->indirect_target = true;
02342 VEC_safe_push (constraint_t, heap, constraints, t);
02343 }
02344 }
02345
02346
02347
02348
02349 static bool
02350 could_have_pointers (tree t)
02351 {
02352 tree type = TREE_TYPE (t);
02353
02354 if (POINTER_TYPE_P (type) || AGGREGATE_TYPE_P (type)
02355 || TREE_CODE (type) == COMPLEX_TYPE)
02356 return true;
02357 return false;
02358 }
02359
02360
02361
02362
02363 static unsigned HOST_WIDE_INT
02364 bitpos_of_field (const tree fdecl)
02365 {
02366
02367 if (TREE_CODE (DECL_FIELD_OFFSET (fdecl)) != INTEGER_CST
02368 || TREE_CODE (DECL_FIELD_BIT_OFFSET (fdecl)) != INTEGER_CST)
02369 return -1;
02370
02371 return (tree_low_cst (DECL_FIELD_OFFSET (fdecl), 1) * 8)
02372 + tree_low_cst (DECL_FIELD_BIT_OFFSET (fdecl), 1);
02373 }
02374
02375
02376
02377
02378
02379 static bool
02380 offset_overlaps_with_access (const unsigned HOST_WIDE_INT fieldpos,
02381 const unsigned HOST_WIDE_INT fieldsize,
02382 const unsigned HOST_WIDE_INT accesspos,
02383 const unsigned HOST_WIDE_INT accesssize)
02384 {
02385 if (fieldpos == accesspos && fieldsize == accesssize)
02386 return true;
02387 if (accesspos >= fieldpos && accesspos < (fieldpos + fieldsize))
02388 return true;
02389 if (accesspos < fieldpos && (accesspos + accesssize > fieldpos))
02390 return true;
02391
02392 return false;
02393 }
02394
02395
02396
02397 static void
02398 get_constraint_for_component_ref (tree t, VEC(ce_s, heap) **results)
02399 {
02400 tree orig_t = t;
02401 HOST_WIDE_INT bitsize = -1;
02402 HOST_WIDE_INT bitmaxsize = -1;
02403 HOST_WIDE_INT bitpos;
02404 tree forzero;
02405 struct constraint_expr *result;
02406 unsigned int beforelength = VEC_length (ce_s, *results);
02407
02408
02409
02410 forzero = t;
02411 while (!SSA_VAR_P (forzero) && !CONSTANT_CLASS_P (forzero))
02412 forzero = TREE_OPERAND (forzero, 0);
02413
02414 if (CONSTANT_CLASS_P (forzero) && integer_zerop (forzero))
02415 {
02416 struct constraint_expr temp;
02417
02418 temp.offset = 0;
02419 temp.var = integer_id;
02420 temp.type = SCALAR;
02421 VEC_safe_push (ce_s, heap, *results, &temp);
02422 return;
02423 }
02424
02425 t = get_ref_base_and_extent (t, &bitpos, &bitsize, &bitmaxsize);
02426
02427
02428
02429 if (TREE_CODE (t) == STRING_CST)
02430 return;
02431
02432 get_constraint_for (t, results);
02433 result = VEC_last (ce_s, *results);
02434 result->offset = bitpos;
02435
02436 gcc_assert (beforelength + 1 == VEC_length (ce_s, *results));
02437
02438
02439 if (TREE_CODE (t) != ADDR_EXPR && result->type == ADDRESSOF)
02440 result->type = SCALAR;
02441
02442 if (result->type == SCALAR)
02443 {
02444
02445
02446
02447
02448
02449 if (result->offset < get_varinfo (result->var)->fullsize
02450 && bitmaxsize != 0)
02451 {
02452
02453
02454
02455
02456 varinfo_t curr;
02457 for (curr = get_varinfo (result->var); curr; curr = curr->next)
02458 {
02459 if (offset_overlaps_with_access (curr->offset, curr->size,
02460 result->offset, bitmaxsize))
02461 {
02462 result->var = curr->id;
02463 break;
02464 }
02465 }
02466
02467
02468
02469
02470 gcc_assert (curr || ref_contains_array_ref (orig_t));
02471 }
02472 else if (bitmaxsize == 0)
02473 {
02474 if (dump_file && (dump_flags & TDF_DETAILS))
02475 fprintf (dump_file, "Access to zero-sized part of variable,"
02476 "ignoring\n");
02477 }
02478 else
02479 if (dump_file && (dump_flags & TDF_DETAILS))
02480 fprintf (dump_file, "Access to past the end of variable, ignoring\n");
02481
02482 result->offset = 0;
02483 }
02484 }
02485
02486
02487
02488
02489
02490
02491
02492
02493 static void
02494 do_deref (VEC (ce_s, heap) **constraints)
02495 {
02496 struct constraint_expr *c;
02497 unsigned int i = 0;
02498 for (i = 0; VEC_iterate (ce_s, *constraints, i, c); i++)
02499 {
02500 if (c->type == SCALAR)
02501 c->type = DEREF;
02502 else if (c->type == ADDRESSOF)
02503 c->type = SCALAR;
02504 else if (c->type == DEREF)
02505 {
02506 tree tmpvar = create_tmp_var_raw (ptr_type_node, "dereftmp");
02507 struct constraint_expr tmplhs = get_constraint_exp_from_ssa_var (tmpvar);
02508 process_constraint (new_constraint (tmplhs, *c));
02509 c->var = tmplhs.var;
02510 }
02511 else
02512 gcc_unreachable ();
02513 }
02514 }
02515
02516
02517
02518
02519 static tree
02520 create_nonlocal_var (tree type)
02521 {
02522 tree nonlocal = create_tmp_var_raw (type, "NONLOCAL");
02523
02524 if (referenced_vars)
02525 add_referenced_var (nonlocal);
02526
02527 DECL_EXTERNAL (nonlocal) = 1;
02528 return nonlocal;
02529 }
02530
02531
02532
02533 static void
02534 get_constraint_for (tree t, VEC (ce_s, heap) **results)
02535 {
02536 struct constraint_expr temp;
02537
02538
02539
02540
02541
02542
02543
02544
02545
02546 if (TREE_CODE (t) == INTEGER_CST
02547 && !POINTER_TYPE_P (TREE_TYPE (t)))
02548 {
02549 temp.var = integer_id;
02550 temp.type = SCALAR;
02551 temp.offset = 0;
02552 VEC_safe_push (ce_s, heap, *results, &temp);
02553 return;
02554 }
02555 else if (TREE_CODE (t) == INTEGER_CST
02556 && integer_zerop (t))
02557 {
02558 temp.var = nothing_id;
02559 temp.type = ADDRESSOF;
02560 temp.offset = 0;
02561 VEC_safe_push (ce_s, heap, *results, &temp);
02562 return;
02563 }
02564
02565 switch (TREE_CODE_CLASS (TREE_CODE (t)))
02566 {
02567 case tcc_expression:
02568 {
02569 switch (TREE_CODE (t))
02570 {
02571 case ADDR_EXPR:
02572 {
02573 struct constraint_expr *c;
02574 unsigned int i;
02575 tree exp = TREE_OPERAND (t, 0);
02576 tree pttype = TREE_TYPE (TREE_TYPE (t));
02577
02578 get_constraint_for (exp, results);
02579
02580
02581 if ((handled_component_p (exp)
02582 && ref_contains_array_ref (exp))
02583 || TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE)
02584 {
02585 struct constraint_expr *origrhs;
02586 varinfo_t origvar;
02587 struct constraint_expr tmp;
02588
02589 if (VEC_length (ce_s, *results) == 0)
02590 return;
02591
02592 gcc_assert (VEC_length (ce_s, *results) == 1);
02593 origrhs = VEC_last (ce_s, *results);
02594 tmp = *origrhs;
02595 VEC_pop (ce_s, *results);
02596 origvar = get_varinfo (origrhs->var);
02597 for (; origvar; origvar = origvar->next)
02598 {
02599 tmp.var = origvar->id;
02600 VEC_safe_push (ce_s, heap, *results, &tmp);
02601 }
02602 }
02603 else if (VEC_length (ce_s, *results) == 1
02604 && (AGGREGATE_TYPE_P (pttype)
02605 || TREE_CODE (pttype) == COMPLEX_TYPE))
02606 {
02607 struct constraint_expr *origrhs;
02608 varinfo_t origvar;
02609 struct constraint_expr tmp;
02610
02611 gcc_assert (VEC_length (ce_s, *results) == 1);
02612 origrhs = VEC_last (ce_s, *results);
02613 tmp = *origrhs;
02614 VEC_pop (ce_s, *results);
02615 origvar = get_varinfo (origrhs->var);
02616 for (; origvar; origvar = origvar->next)
02617 {
02618 tmp.var = origvar->id;
02619 VEC_safe_push (ce_s, heap, *results, &tmp);
02620 }
02621 }
02622
02623 for (i = 0; VEC_iterate (ce_s, *results, i, c); i++)
02624 {
02625 if (c->type == DEREF)
02626 c->type = SCALAR;
02627 else
02628 c->type = ADDRESSOF;
02629 }
02630 return;
02631 }
02632 break;
02633 case CALL_EXPR:
02634
02635
02636
02637 if (call_expr_flags (t) & (ECF_MALLOC | ECF_MAY_BE_ALLOCA))
02638 {
02639 varinfo_t vi;
02640 tree heapvar = heapvar_lookup (t);
02641
02642 if (heapvar == NULL)
02643 {
02644 heapvar = create_tmp_var_raw (ptr_type_node, "HEAP");
02645 DECL_EXTERNAL (heapvar) = 1;
02646 if (referenced_vars)
02647 add_referenced_var (heapvar);
02648 heapvar_insert (t, heapvar);
02649 }
02650
02651 temp.var = create_variable_info_for (heapvar,
02652 alias_get_name (heapvar));
02653
02654 vi = get_varinfo (temp.var);
02655 vi->is_artificial_var = 1;
02656 vi->is_heap_var = 1;
02657 temp.type = ADDRESSOF;
02658 temp.offset = 0;
02659 VEC_safe_push (ce_s, heap, *results, &temp);
02660 return;
02661 }
02662 else
02663 {
02664 temp.var = escaped_vars_id;
02665 temp.type = SCALAR;
02666 temp.offset = 0;
02667 VEC_safe_push (ce_s, heap, *results, &temp);
02668 return;
02669 }
02670 break;
02671 default:
02672 {
02673 temp.type = ADDRESSOF;
02674 temp.var = anything_id;
02675 temp.offset = 0;
02676 VEC_safe_push (ce_s, heap, *results, &temp);
02677 return;
02678 }
02679 }
02680 }
02681 case tcc_reference:
02682 {
02683 switch (TREE_CODE (t))
02684 {
02685 case INDIRECT_REF:
02686 {
02687 get_constraint_for (TREE_OPERAND (t, 0), results);
02688 do_deref (results);
02689 return;
02690 }
02691 case ARRAY_REF:
02692 case ARRAY_RANGE_REF:
02693 case COMPONENT_REF:
02694 get_constraint_for_component_ref (t, results);
02695 return;
02696 default:
02697 {
02698 temp.type = ADDRESSOF;
02699 temp.var = anything_id;
02700 temp.offset = 0;
02701 VEC_safe_push (ce_s, heap, *results, &temp);
02702 return;
02703 }
02704 }
02705 }
02706 case tcc_unary:
02707 {
02708 switch (TREE_CODE (t))
02709 {
02710 case NOP_EXPR:
02711 case CONVERT_EXPR:
02712 case NON_LVALUE_EXPR:
02713 {
02714 tree op = TREE_OPERAND (t, 0);
02715
02716
02717
02718 if (!(POINTER_TYPE_P (TREE_TYPE (t))
02719 && ! POINTER_TYPE_P (TREE_TYPE (op))))
02720 {
02721 get_constraint_for (op, results);
02722 return;
02723 }
02724
02725
02726 }
02727 default:
02728 {
02729 temp.type = ADDRESSOF;
02730 temp.var = anything_id;
02731 temp.offset = 0;
02732 VEC_safe_push (ce_s, heap, *results, &temp);
02733 return;
02734 }
02735 }
02736 }
02737 case tcc_exceptional:
02738 {
02739 switch (TREE_CODE (t))
02740 {
02741 case PHI_NODE:
02742 {
02743 get_constraint_for (PHI_RESULT (t), results);
02744 return;
02745 }
02746 break;
02747 case SSA_NAME:
02748 {
02749 struct constraint_expr temp;
02750 temp = get_constraint_exp_from_ssa_var (t);
02751 VEC_safe_push (ce_s, heap, *results, &temp);
02752 return;
02753 }
02754 break;
02755 default:
02756 {
02757 temp.type = ADDRESSOF;
02758 temp.var = anything_id;
02759 temp.offset = 0;
02760 VEC_safe_push (ce_s, heap, *results, &temp);
02761 return;
02762 }
02763 }
02764 }
02765 case tcc_declaration:
02766 {
02767 struct constraint_expr temp;
02768 temp = get_constraint_exp_from_ssa_var (t);
02769 VEC_safe_push (ce_s, heap, *results, &temp);
02770 return;
02771 }
02772 default:
02773 {
02774 temp.type = ADDRESSOF;
02775 temp.var = anything_id;
02776 temp.offset = 0;
02777 VEC_safe_push (ce_s, heap, *results, &temp);
02778 return;
02779 }
02780 }
02781 }
02782
02783
02784
02785
02786
02787
02788
02789
02790
02791
02792
02793
02794
02795 static bool
02796 do_simple_structure_copy (const struct constraint_expr lhs,
02797 const struct constraint_expr rhs,
02798 const unsigned HOST_WIDE_INT size)
02799 {
02800 varinfo_t p = get_varinfo (lhs.var);
02801 unsigned HOST_WIDE_INT pstart, last;
02802 pstart = p->offset;
02803 last = p->offset + size;
02804 for (; p && p->offset < last; p = p->next)
02805 {
02806 varinfo_t q;
02807 struct constraint_expr templhs = lhs;
02808 struct constraint_expr temprhs = rhs;
02809 unsigned HOST_WIDE_INT fieldoffset;
02810
02811 templhs.var = p->id;
02812 q = get_varinfo (temprhs.var);
02813 fieldoffset = p->offset - pstart;
02814 q = first_vi_for_offset (q, q->offset + fieldoffset);
02815 if (!q)
02816 return false;
02817 temprhs.var = q->id;
02818 process_constraint (new_constraint (templhs, temprhs));
02819 }
02820 return true;
02821 }
02822
02823
02824
02825
02826
02827
02828
02829
02830
02831
02832
02833 static void
02834 do_rhs_deref_structure_copy (const struct constraint_expr lhs,
02835 const struct constraint_expr rhs,
02836 const unsigned HOST_WIDE_INT size)
02837 {
02838 varinfo_t p = get_varinfo (lhs.var);
02839 unsigned HOST_WIDE_INT pstart,last;
02840 pstart = p->offset;
02841 last = p->offset + size;
02842
02843 for (; p && p->offset < last; p = p->next)
02844 {
02845 varinfo_t q;
02846 struct constraint_expr templhs = lhs;
02847 struct constraint_expr temprhs = rhs;
02848 unsigned HOST_WIDE_INT fieldoffset;
02849
02850
02851 if (templhs.type == SCALAR)
02852 templhs.var = p->id;
02853 else
02854 templhs.offset = p->offset;
02855
02856 q = get_varinfo (temprhs.var);
02857 fieldoffset = p->offset - pstart;
02858 temprhs.offset += fieldoffset;
02859 process_constraint (new_constraint (templhs, temprhs));
02860 }
02861 }
02862
02863
02864
02865
02866
02867
02868
02869
02870
02871
02872 static void
02873 do_lhs_deref_structure_copy (const struct constraint_expr lhs,
02874 const struct constraint_expr rhs,
02875 const unsigned HOST_WIDE_INT size)
02876 {
02877 varinfo_t p = get_varinfo (rhs.var);
02878 unsigned HOST_WIDE_INT pstart,last;
02879 pstart = p->offset;
02880 last = p->offset + size;
02881
02882 for (; p && p->offset < last; p = p->next)
02883 {
02884 varinfo_t q;
02885 struct constraint_expr templhs = lhs;
02886 struct constraint_expr temprhs = rhs;
02887 unsigned HOST_WIDE_INT fieldoffset;
02888
02889
02890 if (temprhs.type == SCALAR)
02891 temprhs.var = p->id;
02892 else
02893 temprhs.offset = p->offset;
02894
02895 q = get_varinfo (templhs.var);
02896 fieldoffset = p->offset - pstart;
02897 templhs.offset += fieldoffset;
02898 process_constraint (new_constraint (templhs, temprhs));
02899 }
02900 }
02901
02902
02903
02904
02905
02906
02907 static unsigned int
02908 collapse_rest_of_var (unsigned int var)
02909 {
02910 varinfo_t currvar = get_varinfo (var);
02911 varinfo_t field;
02912
02913 for (field = currvar->next; field; field = field->next)
02914 {
02915 if (dump_file)
02916 fprintf (dump_file, "Type safety: Collapsing var %s into %s\n",
02917 field->name, currvar->name);
02918
02919 gcc_assert (!field->collapsed_to);
02920 field->collapsed_to = currvar;
02921 }
02922
02923 currvar->next = NULL;
02924 currvar->size = currvar->fullsize - currvar->offset;
02925
02926 return currvar->id;
02927 }
02928
02929
02930
02931
02932 static void
02933 do_structure_copy (tree lhsop, tree rhsop)
02934 {
02935 struct constraint_expr lhs, rhs, tmp;
02936 VEC (ce_s, heap) *lhsc = NULL, *rhsc = NULL;
02937 varinfo_t p;
02938 unsigned HOST_WIDE_INT lhssize;
02939 unsigned HOST_WIDE_INT rhssize;
02940
02941 get_constraint_for (lhsop, &lhsc);
02942 get_constraint_for (rhsop, &rhsc);
02943 gcc_assert (VEC_length (ce_s, lhsc) == 1);
02944 gcc_assert (VEC_length (ce_s, rhsc) == 1);
02945 lhs = *(VEC_last (ce_s, lhsc));
02946 rhs = *(VEC_last (ce_s, rhsc));
02947
02948 VEC_free (ce_s, heap, lhsc);
02949 VEC_free (ce_s, heap, rhsc);
02950
02951
02952 if (lhs.var <= integer_id && !(get_varinfo (rhs.var)->is_special_var))
02953 {
02954 tmp = lhs;
02955 lhs = rhs;
02956 rhs = tmp;
02957 }
02958
02959
02960
02961
02962
02963 if (rhs.type == ADDRESSOF && !(get_varinfo (rhs.var)->is_special_var))
02964 {
02965 rhs.type = ADDRESSOF;
02966 rhs.var = anything_id;
02967 }
02968
02969
02970
02971 if (rhs.var <= integer_id)
02972 {
02973 for (p = get_varinfo (lhs.var); p; p = p->next)
02974 {
02975 struct constraint_expr templhs = lhs;
02976 struct constraint_expr temprhs = rhs;
02977
02978 if (templhs.type == SCALAR )
02979 templhs.var = p->id;
02980 else
02981 templhs.offset += p->offset;
02982 process_constraint (new_constraint (templhs, temprhs));
02983 }
02984 }
02985 else
02986 {
02987 tree rhstype = TREE_TYPE (rhsop);
02988 tree lhstype = TREE_TYPE (lhsop);
02989 tree rhstypesize;
02990 tree lhstypesize;
02991
02992 lhstypesize = DECL_P (lhsop) ? DECL_SIZE (lhsop) : TYPE_SIZE (lhstype);
02993 rhstypesize = DECL_P (rhsop) ? DECL_SIZE (rhsop) : TYPE_SIZE (rhstype);
02994
02995
02996
02997
02998
02999
03000
03001 if ((rhs.type == DEREF && TREE_CODE (rhstypesize) != INTEGER_CST)
03002 || (lhs.type == DEREF && TREE_CODE (lhstypesize) != INTEGER_CST))
03003 {
03004 rhs.var = anything_id;
03005 rhs.type = ADDRESSOF;
03006 rhs.offset = 0;
03007 process_constraint (new_constraint (lhs, rhs));
03008 return;
03009 }
03010
03011
03012
03013
03014 if (get_varinfo (rhs.var)->is_unknown_size_var)
03015 rhssize = ~0;
03016 else
03017 rhssize = TREE_INT_CST_LOW (rhstypesize);
03018
03019 if (get_varinfo (lhs.var)->is_unknown_size_var)
03020 lhssize = ~0;
03021 else
03022 lhssize = TREE_INT_CST_LOW (lhstypesize);
03023
03024
03025 if (rhs.type == SCALAR && lhs.type == SCALAR)
03026 {
03027 if (!do_simple_structure_copy (lhs, rhs, MIN (lhssize, rhssize)))
03028 {
03029 lhs.var = collapse_rest_of_var (lhs.var);
03030 rhs.var = collapse_rest_of_var (rhs.var);
03031 lhs.offset = 0;
03032 rhs.offset = 0;
03033 lhs.type = SCALAR;
03034 rhs.type = SCALAR;
03035 process_constraint (new_constraint (lhs, rhs));
03036 }
03037 }
03038 else if (lhs.type != DEREF && rhs.type == DEREF)
03039 do_rhs_deref_structure_copy (lhs, rhs, MIN (lhssize, rhssize));
03040 else if (lhs.type == DEREF && rhs.type != DEREF)
03041 do_lhs_deref_structure_copy (lhs, rhs, MIN (lhssize, rhssize));
03042 else
03043 {
03044 tree pointedtotype = lhstype;
03045 tree tmpvar;
03046
03047 gcc_assert (rhs.type == DEREF && lhs.type == DEREF);
03048 tmpvar = create_tmp_var_raw (pointedtotype, "structcopydereftmp");
03049 do_structure_copy (tmpvar, rhsop);
03050 do_structure_copy (lhsop, tmpvar);
03051 }
03052 }
03053 }
03054
03055
03056
03057
03058
03059
03060 static void
03061 update_alias_info (tree stmt, struct alias_info *ai)
03062 {
03063 bitmap addr_taken;
03064 use_operand_p use_p;
03065 ssa_op_iter iter;
03066 enum escape_type stmt_escape_type = is_escape_site (stmt);
03067 tree op;
03068
03069 if (stmt_escape_type == ESCAPE_TO_CALL
03070 || stmt_escape_type == ESCAPE_TO_PURE_CONST)
03071 {
03072 ai->num_calls_found++;
03073 if (stmt_escape_type == ESCAPE_TO_PURE_CONST)
03074 ai->num_pure_const_calls_found++;
03075 }
03076
03077
03078 addr_taken = addresses_taken (stmt);
03079 if (addr_taken)
03080 {
03081 bitmap_ior_into (addressable_vars, addr_taken);
03082
03083
03084
03085 if (stmt_escape_type != NO_ESCAPE)
03086 {
03087 bitmap_iterator bi;
03088 unsigned i;
03089
03090 EXECUTE_IF_SET_IN_BITMAP (addr_taken, 0, i, bi)
03091 {
03092 tree rvar = referenced_var (i);
03093 if (!unmodifiable_var_p (rvar))
03094 mark_call_clobbered (rvar, stmt_escape_type);
03095 }
03096 }
03097 }
03098
03099
03100
03101
03102
03103 FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, iter, SSA_OP_USE)
03104 {
03105 tree op, var;
03106 var_ann_t v_ann;
03107 struct ptr_info_def *pi;
03108 bool is_store, is_potential_deref;
03109 unsigned num_uses, num_derefs;
03110
03111 op = USE_FROM_PTR (use_p);
03112
03113
03114
03115 if (TREE_CODE (op) == ADDR_EXPR)
03116 {
03117 gcc_assert (TREE_CODE (stmt) == PHI_NODE);
03118
03119
03120
03121
03122
03123
03124
03125
03126 add_to_addressable_set (TREE_OPERAND (op, 0), &addressable_vars);
03127 continue;
03128 }
03129
03130
03131 if (TREE_CODE (op) != SSA_NAME)
03132 continue;
03133
03134 var = SSA_NAME_VAR (op);
03135 v_ann = var_ann (var);
03136
03137
03138
03139 gcc_assert (!may_be_aliased (var));
03140
03141
03142 if (!POINTER_TYPE_P (TREE_TYPE (op)))
03143 continue;
03144
03145 pi = get_ptr_info (op);
03146
03147
03148 if (!TEST_BIT (ai->ssa_names_visited, SSA_NAME_VERSION (op)))
03149 {
03150 SET_BIT (ai->ssa_names_visited, SSA_NAME_VERSION (op));
03151 VEC_safe_push (tree, heap, ai->processed_ptrs, op);
03152 }
03153
03154
03155
03156 if (TREE_CODE (stmt) == PHI_NODE)
03157 continue;
03158
03159
03160
03161 count_uses_and_derefs (op, stmt, &num_uses, &num_derefs, &is_store);
03162
03163
03164
03165
03166
03167
03168
03169
03170
03171
03172
03173
03174
03175
03176
03177
03178
03179
03180
03181
03182
03183
03184 is_potential_deref = false;
03185 if (TREE_CODE (stmt) == MODIFY_EXPR
03186 && TREE_CODE (TREE_OPERAND (stmt, 1)) == ADDR_EXPR
03187 && !is_gimple_val (TREE_OPERAND (stmt, 1)))
03188 {
03189
03190
03191 tree rhs = TREE_OPERAND (stmt, 1);
03192 tree base = get_base_address (TREE_OPERAND (rhs, 0));
03193 if (TREE_CODE (base) == INDIRECT_REF
03194 && TREE_OPERAND (base, 0) == op)
03195 is_potential_deref = true;
03196 }
03197
03198 if (num_derefs > 0 || is_potential_deref)
03199 {
03200
03201
03202
03203
03204 pi->is_dereferenced = 1;
03205
03206
03207
03208 NUM_REFERENCES_INC (v_ann);
03209
03210
03211
03212
03213 if (is_store)
03214 bitmap_set_bit (ai->dereferenced_ptrs_store, DECL_UID (var));
03215 else
03216 bitmap_set_bit (ai->dereferenced_ptrs_load, DECL_UID (var));
03217 }
03218
03219 if (stmt_escape_type != NO_ESCAPE && num_derefs < num_uses)
03220 {
03221
03222
03223
03224
03225 pi->value_escapes_p = 1;
03226 pi->escape_mask |= stmt_escape_type;
03227
03228
03229
03230
03231 if (get_call_expr_in (stmt)
03232 || stmt_escape_type == ESCAPE_STORED_IN_GLOBAL)
03233 {
03234 bitmap_set_bit (ai->dereferenced_ptrs_store, DECL_UID (var));
03235 pi->is_dereferenced = 1;
03236 }
03237 }
03238 }
03239
03240 if (TREE_CODE (stmt) == PHI_NODE)
03241 return;
03242
03243
03244
03245
03246 FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_DEF)
03247 {
03248 tree var = SSA_NAME_VAR (op);
03249 var_ann_t ann = var_ann (var);
03250 bitmap_set_bit (ai->written_vars, DECL_UID (var));
03251 if (may_be_aliased (var))
03252 NUM_REFERENCES_INC (ann);
03253
03254 }
03255
03256
03257 FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_VIRTUAL_DEFS)
03258 {
03259 tree var = DECL_P (op) ? op : SSA_NAME_VAR (op);
03260 bitmap_set_bit (ai->written_vars, DECL_UID (var));
03261 }
03262 }
03263
03264
03265
03266
03267
03268
03269
03270
03271
03272
03273
03274
03275
03276
03277
03278
03279
03280
03281
03282
03283 static bool
03284 handle_ptr_arith (VEC (ce_s, heap) *lhsc, tree expr)
03285 {
03286 tree op0, op1;
03287 struct constraint_expr *c, *c2;
03288 unsigned int i = 0;
03289 unsigned int j = 0;
03290 VEC (ce_s, heap) *temp = NULL;
03291 unsigned int rhsoffset = 0;
03292
03293 if (TREE_CODE (expr) != PLUS_EXPR
03294 && TREE_CODE (expr) != MINUS_EXPR)
03295 return false;
03296
03297 op0 = TREE_OPERAND (expr, 0);
03298 op1 = TREE_OPERAND (expr, 1);
03299
03300 get_constraint_for (op0, &temp);
03301 if (POINTER_TYPE_P (TREE_TYPE (op0))
03302 && TREE_CODE (op1) == INTEGER_CST
03303 && TREE_CODE (expr) == PLUS_EXPR)
03304 {
03305 rhsoffset = TREE_INT_CST_LOW (op1) * BITS_PER_UNIT;
03306 }
03307 else
03308 return false;
03309
03310 for (i = 0; VEC_iterate (ce_s, lhsc, i, c); i++)
03311 for (j = 0; VEC_iterate (ce_s, temp, j, c2); j++)
03312 {
03313 if (c2->type == ADDRESSOF && rhsoffset != 0)
03314 {
03315 varinfo_t temp = get_varinfo (c2->var);
03316
03317
03318
03319 temp = first_vi_for_offset (temp, rhsoffset);
03320 if (temp == NULL)
03321 continue;
03322 c2->var = temp->id;
03323 c2->offset = 0;
03324 }
03325 else
03326 c2->offset = rhsoffset;
03327 process_constraint (new_constraint (*c, *c2));
03328 }
03329
03330 VEC_free (ce_s, heap, temp);
03331
03332 return true;
03333 }
03334
03335
03336
03337
03338
03339
03340
03341 static void
03342 find_func_aliases (tree origt)
03343 {
03344 tree t = origt;
03345 VEC(ce_s, heap) *lhsc = NULL;
03346 VEC(ce_s, heap) *rhsc = NULL;
03347 struct constraint_expr *c;
03348
03349 if (TREE_CODE (t) == RETURN_EXPR && TREE_OPERAND (t, 0))
03350 t = TREE_OPERAND (t, 0);
03351
03352
03353 if (TREE_CODE (t) == PHI_NODE)
03354 {
03355 gcc_assert (!AGGREGATE_TYPE_P (TREE_TYPE (PHI_RESULT (t))));
03356
03357
03358
03359 if (could_have_pointers (PHI_RESULT (t)))
03360 {
03361 int i;
03362 unsigned int j;
03363
03364
03365
03366 get_constraint_for (PHI_RESULT (t), &lhsc);
03367 for (i = 0; i < PHI_NUM_ARGS (t); i++)
03368 {
03369 tree rhstype;
03370 tree strippedrhs = PHI_ARG_DEF (t, i);
03371
03372 STRIP_NOPS (strippedrhs);
03373 rhstype = TREE_TYPE (strippedrhs);
03374 get_constraint_for (PHI_ARG_DEF (t, i), &rhsc);
03375
03376 for (j = 0; VEC_iterate (ce_s, lhsc, j, c); j++)
03377 {
03378 struct constraint_expr *c2;
03379 while (VEC_length (ce_s, rhsc) > 0)
03380 {
03381 c2 = VEC_last (ce_s, rhsc);
03382 process_constraint (new_constraint (*c, *c2));
03383 VEC_pop (ce_s, rhsc);
03384 }
03385 }
03386 }
03387 }
03388 }
03389
03390
03391
03392
03393 else if (in_ipa_mode
03394 && ((TREE_CODE (t) == MODIFY_EXPR
03395 && TREE_CODE (TREE_OPERAND (t, 1)) == CALL_EXPR
03396 && !(call_expr_flags (TREE_OPERAND (t, 1))
03397 & (ECF_MALLOC | ECF_MAY_BE_ALLOCA)))
03398 || (TREE_CODE (t) == CALL_EXPR
03399 && !(call_expr_flags (t)
03400 & (ECF_MALLOC | ECF_MAY_BE_ALLOCA)))))
03401 {
03402 tree lhsop;
03403 tree rhsop;
03404 unsigned int varid;
03405 tree arglist;
03406 varinfo_t fi;
03407 int i = 1;
03408 tree decl;
03409 if (TREE_CODE (t) == MODIFY_EXPR)
03410 {
03411 lhsop = TREE_OPERAND (t, 0);
03412 rhsop = TREE_OPERAND (t, 1);
03413 }
03414 else
03415 {
03416 lhsop = NULL;
03417 rhsop = t;
03418 }
03419 decl = get_callee_fndecl (rhsop);
03420
03421
03422
03423
03424 if (decl)
03425 {
03426 varid = get_id_for_tree (decl);
03427 }
03428 else
03429 {
03430 decl = TREE_OPERAND (rhsop, 0);
03431 varid = get_id_for_tree (decl);
03432 }
03433
03434
03435
03436 fi = get_varinfo (varid);
03437 arglist = TREE_OPERAND (rhsop, 1);
03438
03439 for (;arglist; arglist = TREE_CHAIN (arglist))
03440 {
03441 tree arg = TREE_VALUE (arglist);
03442 struct constraint_expr lhs ;
03443 struct constraint_expr *rhsp;
03444
03445 get_constraint_for (arg, &rhsc);
03446 if (TREE_CODE (decl) != FUNCTION_DECL)
03447 {
03448 lhs.type = DEREF;
03449 lhs.var = fi->id;
03450 lhs.offset = i;
03451 }
03452 else
03453 {
03454 lhs.type = SCALAR;
03455 lhs.var = first_vi_for_offset (fi, i)->id;
03456 lhs.offset = 0;
03457 }
03458 while (VEC_length (ce_s, rhsc) != 0)
03459 {
03460 rhsp = VEC_last (ce_s, rhsc);
03461 process_constraint (new_constraint (lhs, *rhsp));
03462 VEC_pop (ce_s, rhsc);
03463 }
03464 i++;
03465 }
03466
03467 if (lhsop)
03468 {
03469 struct constraint_expr rhs;
03470 struct constraint_expr *lhsp;
03471 unsigned int j = 0;
03472
03473 get_constraint_for (lhsop, &lhsc);
03474 if (TREE_CODE (decl) != FUNCTION_DECL)
03475 {
03476 rhs.type = DEREF;
03477 rhs.var = fi->id;
03478 rhs.offset = i;
03479 }
03480 else
03481 {
03482 rhs.type = SCALAR;
03483 rhs.var = first_vi_for_offset (fi, i)->id;
03484 rhs.offset = 0;
03485 }
03486 for (j = 0; VEC_iterate (ce_s, lhsc, j, lhsp); j++)
03487 process_constraint (new_constraint (*lhsp, rhs));
03488 }
03489 }
03490
03491 else if (TREE_CODE (t) == MODIFY_EXPR)
03492 {
03493 tree lhsop = TREE_OPERAND (t, 0);
03494 tree rhsop = TREE_OPERAND (t, 1);
03495 int i;
03496
03497 if ((AGGREGATE_TYPE_P (TREE_TYPE (lhsop))
03498 || TREE_CODE (TREE_TYPE (lhsop)) == COMPLEX_TYPE)
03499 && (AGGREGATE_TYPE_P (TREE_TYPE (rhsop))
03500 || TREE_CODE (TREE_TYPE (lhsop)) == COMPLEX_TYPE))
03501 {
03502 do_structure_copy (lhsop, rhsop);
03503 }
03504 else
03505 {
03506
03507
03508 if (could_have_pointers (lhsop)
03509 || TREE_CODE (rhsop) == CALL_EXPR)
03510 {
03511 get_constraint_for (lhsop, &lhsc);
03512 switch (TREE_CODE_CLASS (TREE_CODE (rhsop)))
03513 {
03514
03515
03516
03517 case tcc_reference:
03518 case tcc_declaration:
03519 case tcc_constant:
03520 case tcc_exceptional:
03521 case tcc_expression:
03522 case tcc_unary:
03523 {
03524 unsigned int j;
03525
03526 get_constraint_for (rhsop, &rhsc);
03527 for (j = 0; VEC_iterate (ce_s, lhsc, j, c); j++)
03528 {
03529 struct constraint_expr *c2;
03530 unsigned int k;
03531
03532 for (k = 0; VEC_iterate (ce_s, rhsc, k, c2); k++)
03533 process_constraint (new_constraint (*c, *c2));
03534 }
03535
03536 }
03537 break;
03538
03539 case tcc_binary:
03540 {
03541
03542
03543
03544
03545 if (handle_ptr_arith (lhsc, rhsop))
03546 break;
03547 }
03548
03549
03550
03551
03552
03553
03554 default:
03555 for (i = 0; i < TREE_CODE_LENGTH (TREE_CODE (rhsop)); i++)
03556 {
03557 tree op = TREE_OPERAND (rhsop, i);
03558 unsigned int j;
03559
03560 gcc_assert (VEC_length (ce_s, rhsc) == 0);
03561 get_constraint_for (op, &rhsc);
03562 for (j = 0; VEC_iterate (ce_s, lhsc, j, c); j++)
03563 {
03564 struct constraint_expr *c2;
03565 while (VEC_length (ce_s, rhsc) > 0)
03566 {
03567 c2 = VEC_last (ce_s, rhsc);
03568 process_constraint (new_constraint (*c, *c2));
03569 VEC_pop (ce_s, rhsc);
03570 }
03571 }
03572 }
03573 }
03574 }
03575 }
03576 }
03577
03578
03579
03580
03581
03582 mark_stmt_modified (origt);
03583 VEC_free (ce_s, heap, rhsc);
03584 VEC_free (ce_s, heap, lhsc);
03585 }
03586
03587
03588
03589
03590
03591
03592
03593
03594 static varinfo_t
03595 first_vi_for_offset (varinfo_t start, unsigned HOST_WIDE_INT offset)
03596 {
03597 varinfo_t curr = start;
03598 while (curr)
03599 {
03600
03601
03602
03603
03604 if (offset >= curr->offset && offset < (curr->offset + curr->size))
03605 return curr;
03606 curr = curr->next;
03607 }
03608 return NULL;
03609 }
03610
03611
03612
03613
03614
03615 static void
03616 insert_into_field_list (varinfo_t base, varinfo_t field)
03617 {
03618 varinfo_t prev = base;
03619 varinfo_t curr = base->next;
03620
03621 field->next = curr;
03622 prev->next = field;
03623 }
03624
03625
03626
03627
03628 static void
03629 insert_into_field_list_sorted (varinfo_t base, varinfo_t field)
03630 {
03631 varinfo_t prev = base;
03632 varinfo_t curr = base->next;
03633
03634 if (curr == NULL)
03635 {
03636 prev->next = field;
03637 field->next = NULL;
03638 }
03639 else
03640 {
03641 while (curr)
03642 {
03643 if (field->offset <= curr->offset)
03644 break;
03645 prev = curr;
03646 curr = curr->next;
03647 }
03648 field->next = prev->next;
03649 prev->next = field;
03650 }
03651 }
03652
03653
03654
03655 static int
03656 fieldoff_compare (const void *pa, const void *pb)
03657 {
03658 const fieldoff_s *foa = (const fieldoff_s *)pa;
03659 const fieldoff_s *fob = (const fieldoff_s *)pb;
03660 HOST_WIDE_INT foasize, fobsize;
03661
03662 if (foa->offset != fob->offset)
03663 return foa->offset - fob->offset;
03664
03665 foasize = TREE_INT_CST_LOW (foa->size);
03666 fobsize = TREE_INT_CST_LOW (fob->size);
03667 return foasize - fobsize;
03668 }
03669
03670
03671 void
03672 sort_fieldstack (VEC(fieldoff_s,heap) *fieldstack)
03673 {
03674 qsort (VEC_address (fieldoff_s, fieldstack),
03675 VEC_length (fieldoff_s, fieldstack),
03676 sizeof (fieldoff_s),
03677 fieldoff_compare);
03678 }
03679
03680
03681
03682
03683
03684
03685
03686
03687
03688 int
03689 push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
03690 HOST_WIDE_INT offset, bool *has_union)
03691 {
03692 tree field;
03693 int count = 0;
03694
03695 if (TREE_CODE (type) == COMPLEX_TYPE)
03696 {
03697 fieldoff_s *real_part, *img_part;
03698 real_part = VEC_safe_push (fieldoff_s, heap, *fieldstack, NULL);
03699 real_part->type = TREE_TYPE (type);
03700 real_part->size = TYPE_SIZE (TREE_TYPE (type));
03701 real_part->offset = offset;
03702 real_part->decl = NULL_TREE;
03703
03704 img_part = VEC_safe_push (fieldoff_s, heap, *fieldstack, NULL);
03705 img_part->type = TREE_TYPE (type);
03706 img_part->size = TYPE_SIZE (TREE_TYPE (type));
03707 img_part->offset = offset + TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (type)));
03708 img_part->decl = NULL_TREE;
03709
03710 return 2;
03711 }
03712
03713 if (TREE_CODE (type) == ARRAY_TYPE)
03714 {
03715 tree sz = TYPE_SIZE (type);
03716 tree elsz = TYPE_SIZE (TREE_TYPE (type));
03717 HOST_WIDE_INT nr;
03718 int i;
03719
03720 if (! sz
03721 || ! host_integerp (sz, 1)
03722 || TREE_INT_CST_LOW (sz) == 0
03723 || ! elsz
03724 || ! host_integerp (elsz, 1)
03725 || TREE_INT_CST_LOW (elsz) == 0)
03726 return 0;
03727
03728 nr = TREE_INT_CST_LOW (sz) / TREE_INT_CST_LOW (elsz);
03729 if (nr > SALIAS_MAX_ARRAY_ELEMENTS)
03730 return 0;
03731
03732 for (i = 0; i < nr; ++i)
03733 {
03734 bool push = false;
03735 int pushed = 0;
03736
03737 if (has_union
03738 && (TREE_CODE (TREE_TYPE (type)) == QUAL_UNION_TYPE
03739 || TREE_CODE (TREE_TYPE (type)) == UNION_TYPE))
03740 *has_union = true;
03741
03742 if (!AGGREGATE_TYPE_P (TREE_TYPE (type)))
03743 push = true;
03744 else if (!(pushed = push_fields_onto_fieldstack
03745 (TREE_TYPE (type), fieldstack,
03746 offset + i * TREE_INT_CST_LOW (elsz), has_union)))
03747
03748
03749
03750 push = true;
03751
03752 if (push)
03753 {
03754 fieldoff_s *pair;
03755
03756 pair = VEC_safe_push (fieldoff_s, heap, *fieldstack, NULL);
03757 pair->type = TREE_TYPE (type);
03758 pair->size = elsz;
03759 pair->decl = NULL_TREE;
03760 pair->offset = offset + i * TREE_INT_CST_LOW (elsz);
03761 count++;
03762 }
03763 else
03764 count += pushed;
03765 }
03766
03767 return count;
03768 }
03769
03770 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
03771 if (TREE_CODE (field) == FIELD_DECL)
03772 {
03773 bool push = false;
03774 int pushed = 0;
03775
03776 if (has_union
03777 && (TREE_CODE (TREE_TYPE (field)) == QUAL_UNION_TYPE
03778 || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE))
03779 *has_union = true;
03780
03781 if (!var_can_have_subvars (field))
03782 push = true;
03783 else if (!(pushed = push_fields_onto_fieldstack
03784 (TREE_TYPE (field), fieldstack,
03785 offset + bitpos_of_field (field), has_union))
03786 && DECL_SIZE (field)
03787 && !integer_zerop (DECL_SIZE (field)))
03788
03789
03790
03791 push = true;
03792
03793 if (push)
03794 {
03795 fieldoff_s *pair;
03796
03797 pair = VEC_safe_push (fieldoff_s, heap, *fieldstack, NULL);
03798 pair->type = TREE_TYPE (field);
03799 pair->size = DECL_SIZE (field);
03800 pair->decl = field;
03801 pair->offset = offset + bitpos_of_field (field);
03802 count++;
03803 }
03804 else
03805 count += pushed;
03806 }
03807
03808 return count;
03809 }
03810
03811
03812 static void
03813 make_constraint_from_escaped (varinfo_t vi)
03814 {
03815 struct constraint_expr lhs, rhs;
03816
03817 lhs.var = vi->id;
03818 lhs.offset = 0;
03819 lhs.type = SCALAR;
03820
03821 rhs.var = escaped_vars_id;
03822 rhs.offset = 0;
03823 rhs.type = SCALAR;
03824 process_constraint (new_constraint (lhs, rhs));
03825 }
03826
03827
03828
03829
03830 static void
03831 make_constraint_to_escaped (struct constraint_expr rhs)
03832 {
03833 struct constraint_expr lhs;
03834
03835 lhs.var = escaped_vars_id;
03836 lhs.offset = 0;
03837 lhs.type = SCALAR;
03838
03839 process_constraint (new_constraint (lhs, rhs));
03840 }
03841
03842
03843
03844
03845 static unsigned int
03846 count_num_arguments (tree decl, bool *is_varargs)
03847 {
03848 unsigned int i = 0;
03849 tree t;
03850
03851 for (t = TYPE_ARG_TYPES (TREE_TYPE (decl));
03852 t;
03853 t = TREE_CHAIN (t))
03854 {
03855 if (TREE_VALUE (t) == void_type_node)
03856 break;
03857 i++;
03858 }
03859
03860 if (!t)
03861 *is_varargs = true;
03862 return i;
03863 }
03864
03865
03866
03867
03868 static unsigned int
03869 create_function_info_for (tree decl, const char *name)
03870 {
03871 unsigned int index = VEC_length (varinfo_t, varmap);
03872 varinfo_t vi;
03873 tree arg;
03874 unsigned int i;
03875 bool is_varargs = false;
03876
03877
03878
03879 vi = new_var_info (decl, index, name, index);
03880 vi->decl = decl;
03881 vi->offset = 0;
03882 vi->has_union = 0;
03883 vi->size = 1;
03884 vi->fullsize = count_num_arguments (decl, &is_varargs) + 1;
03885 insert_id_for_tree (vi->decl, index);
03886 VEC_safe_push (varinfo_t, heap, varmap, vi);
03887
03888 stats.total_vars++;
03889
03890
03891
03892
03893 if (is_varargs)
03894 {
03895 vi->fullsize = ~0;
03896 vi->size = ~0;
03897 vi->is_unknown_size_var = true;
03898 return index;
03899 }
03900
03901
03902 arg = DECL_ARGUMENTS (decl);
03903
03904
03905 for (i = 1; i < vi->fullsize; i++)
03906 {
03907 varinfo_t argvi;
03908 const char *newname;
03909 char *tempname;
03910 unsigned int newindex;
03911 tree argdecl = decl;
03912
03913 if (arg)
03914 argdecl = arg;
03915
03916 newindex = VEC_length (varinfo_t, varmap);
03917 asprintf (&tempname, "%s.arg%d", name, i-1);
03918 newname = ggc_strdup (tempname);
03919 free (tempname);
03920
03921 argvi = new_var_info (argdecl, newindex,newname, newindex);
03922 argvi->decl = argdecl;
03923 VEC_safe_push (varinfo_t, heap, varmap, argvi);
03924 argvi->offset = i;
03925 argvi->size = 1;
03926 argvi->fullsize = vi->fullsize;
03927 argvi->has_union = false;
03928 insert_into_field_list_sorted (vi, argvi);
03929 stats.total_vars ++;
03930 if (arg)
03931 {
03932 insert_id_for_tree (arg, newindex);
03933 arg = TREE_CHAIN (arg);
03934 }
03935 }
03936
03937
03938 if (DECL_RESULT (decl) != NULL
03939 || !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
03940 {
03941 varinfo_t resultvi;
03942 const char *newname;
03943 char *tempname;
03944 unsigned int newindex;
03945 tree resultdecl = decl;
03946
03947 vi->fullsize ++;
03948
03949 if (DECL_RESULT (decl))
03950 resultdecl = DECL_RESULT (decl);
03951
03952 newindex = VEC_length (varinfo_t, varmap);
03953 asprintf (&tempname, "%s.result", name);
03954 newname = ggc_strdup (tempname);
03955 free (tempname);
03956
03957 resultvi = new_var_info (resultdecl, newindex, newname, newindex);
03958 resultvi->decl = resultdecl;
03959 VEC_safe_push (varinfo_t, heap, varmap, resultvi);
03960 resultvi->offset = i;
03961 resultvi->size = 1;
03962 resultvi->fullsize = vi->fullsize;
03963 resultvi->has_union = false;
03964 insert_into_field_list_sorted (vi, resultvi);
03965 stats.total_vars ++;
03966 if (DECL_RESULT (decl))
03967 insert_id_for_tree (DECL_RESULT (decl), newindex);
03968 }
03969 return index;
03970 }
03971
03972
03973
03974
03975
03976 static bool
03977 check_for_overlaps (VEC (fieldoff_s,heap) *fieldstack)
03978 {
03979 fieldoff_s *fo = NULL;
03980 unsigned int i;
03981 HOST_WIDE_INT lastoffset = -1;
03982
03983 for (i = 0; VEC_iterate (fieldoff_s, fieldstack, i, fo); i++)
03984 {
03985 if (fo->offset == lastoffset)
03986 return true;
03987 lastoffset = fo->offset;
03988 }
03989 return false;
03990 }
03991
03992
03993
03994
03995
03996 static tree
03997 find_global_initializers (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
03998 void *viv)
03999 {
04000 varinfo_t vi = (varinfo_t)viv;
04001 tree t = *tp;
04002
04003 switch (TREE_CODE (t))
04004 {
04005
04006
04007
04008 case INDIRECT_REF:
04009 case ADDR_EXPR:
04010 {
04011 struct constraint_expr *c;
04012 size_t i;
04013
04014 VEC(ce_s, heap) *rhsc = NULL;
04015 get_constraint_for (t, &rhsc);
04016 for (i = 0; VEC_iterate (ce_s, rhsc, i, c); i++)
04017 {
04018 struct constraint_expr lhs;
04019
04020 lhs.var = vi->id;
04021 lhs.type = SCALAR;
04022 lhs.offset = 0;
04023 process_constraint (new_constraint (lhs, *c));
04024 }
04025
04026 VEC_free (ce_s, heap, rhsc);
04027 }
04028 break;
04029 case VAR_DECL:
04030
04031
04032 if (referenced_vars)
04033 {
04034 get_var_ann (t);
04035 if (referenced_var_check_and_insert (t))
04036 mark_sym_for_renaming (t);
04037 }
04038 break;
04039 default:
04040 break;
04041 }
04042 return NULL_TREE;
04043 }
04044
04045
04046
04047
04048
04049 static unsigned int
04050 create_variable_info_for (tree decl, const char *name)
04051 {
04052 unsigned int index = VEC_length (varinfo_t, varmap);
04053 varinfo_t vi;
04054 tree decltype = TREE_TYPE (decl);
04055 tree declsize = DECL_P (decl) ? DECL_SIZE (decl) : TYPE_SIZE (decltype);
04056 bool notokay = false;
04057 bool hasunion;
04058 bool is_global = DECL_P (decl) ? is_global_var (decl) : false;
04059 VEC (fieldoff_s,heap) *fieldstack = NULL;
04060
04061 if (TREE_CODE (decl) == FUNCTION_DECL && in_ipa_mode)
04062 return create_function_info_for (decl, name);
04063
04064 hasunion = TREE_CODE (decltype) == UNION_TYPE
04065 || TREE_CODE (decltype) == QUAL_UNION_TYPE;
04066 if (var_can_have_subvars (decl) && use_field_sensitive && !hasunion)
04067 {
04068 push_fields_onto_fieldstack (decltype, &fieldstack, 0, &hasunion);
04069 if (hasunion)
04070 {
04071 VEC_free (fieldoff_s, heap, fieldstack);
04072 notokay = true;
04073 }
04074 }
04075
04076
04077
04078
04079
04080 vi = new_var_info (decl, index, name, index);
04081 vi->decl = decl;
04082 vi->offset = 0;
04083 vi->has_union = hasunion;
04084 if (!declsize
04085 || TREE_CODE (declsize) != INTEGER_CST
04086 || TREE_CODE (decltype) == UNION_TYPE
04087 || TREE_CODE (decltype) == QUAL_UNION_TYPE)
04088 {
04089 vi->is_unknown_size_var = true;
04090 vi->fullsize = ~0;
04091 vi->size = ~0;
04092 }
04093 else
04094 {
04095 vi->fullsize = TREE_INT_CST_LOW (declsize);
04096 vi->size = vi->fullsize;
04097 }
04098
04099 insert_id_for_tree (vi->decl, index);
04100 VEC_safe_push (varinfo_t, heap, varmap, vi);
04101 if (is_global && (!flag_whole_program || !in_ipa_mode))
04102 {
04103 make_constraint_from_escaped (vi);
04104
04105
04106
04107 if (may_be_aliased (vi->decl))
04108 {
04109 struct constraint_expr rhs;
04110 rhs.var = index;
04111 rhs.type = ADDRESSOF;
04112 rhs.offset = 0;
04113 make_constraint_to_escaped (rhs);
04114 }
04115
04116 if (TREE_CODE (decl) != FUNCTION_DECL && DECL_INITIAL (decl))
04117 {
04118 walk_tree_without_duplicates (&DECL_INITIAL (decl),
04119 find_global_initializers,
04120 (void *)vi);
04121 }
04122 }
04123
04124 stats.total_vars++;
04125 if (use_field_sensitive
04126 && !notokay
04127 && !vi->is_unknown_size_var
04128 && var_can_have_subvars (decl)
04129 && VEC_length (fieldoff_s, fieldstack) <= MAX_FIELDS_FOR_FIELD_SENSITIVE)
04130 {
04131 unsigned int newindex = VEC_length (varinfo_t, varmap);
04132 fieldoff_s *fo = NULL;
04133 unsigned int i;
04134
04135 for (i = 0; !notokay && VEC_iterate (fieldoff_s, fieldstack, i, fo); i++)
04136 {
04137 if (! fo->size
04138 || TREE_CODE (fo->size) != INTEGER_CST
04139 || fo->offset < 0)
04140 {
04141 notokay = true;
04142 break;
04143 }
04144 }
04145
04146
04147
04148
04149
04150 if (!notokay)
04151 {
04152 sort_fieldstack (fieldstack);
04153
04154
04155
04156
04157 notokay = check_for_overlaps (fieldstack);
04158 }
04159
04160
04161 if (VEC_length (fieldoff_s, fieldstack) != 0)
04162 fo = VEC_index (fieldoff_s, fieldstack, 0);
04163
04164 if (fo == NULL || notokay)
04165 {
04166 vi->is_unknown_size_var = 1;
04167 vi->fullsize = ~0;
04168 vi->size = ~0;
04169 VEC_free (fieldoff_s, heap, fieldstack);
04170 return index;
04171 }
04172
04173 vi->size = TREE_INT_CST_LOW (fo->size);
04174 vi->offset = fo->offset;
04175 for (i = VEC_length (fieldoff_s, fieldstack) - 1;
04176 i >= 1 && VEC_iterate (fieldoff_s, fieldstack, i, fo);
04177 i--)
04178 {
04179 varinfo_t newvi;
04180 const char *newname = "NULL";
04181 char *tempname;
04182
04183 newindex = VEC_length (varinfo_t, varmap);
04184 if (dump_file)
04185 {
04186 if (fo->decl)
04187 asprintf (&tempname, "%s.%s",
04188 vi->name, alias_get_name (fo->decl));
04189 else
04190 asprintf (&tempname, "%s." HOST_WIDE_INT_PRINT_DEC,
04191 vi->name, fo->offset);
04192 newname = ggc_strdup (tempname);
04193 free (tempname);
04194 }
04195 newvi = new_var_info (decl, newindex, newname, newindex);
04196 newvi->offset = fo->offset;
04197 newvi->size = TREE_INT_CST_LOW (fo->size);
04198 newvi->fullsize = vi->fullsize;
04199 insert_into_field_list (vi, newvi);
04200 VEC_safe_push (varinfo_t, heap, varmap, newvi);
04201 if (is_global && (!flag_whole_program || !in_ipa_mode))
04202 {
04203
04204
04205 if (may_be_aliased (vi->decl))
04206 {
04207 struct constraint_expr rhs;
04208
04209 rhs.var = newindex;
04210 rhs.type = ADDRESSOF;
04211 rhs.offset = 0;
04212 make_constraint_to_escaped (rhs);
04213 }
04214 make_constraint_from_escaped (newvi);
04215 }
04216
04217 stats.total_vars++;
04218 }
04219 VEC_free (fieldoff_s, heap, fieldstack);
04220 }
04221 return index;
04222 }
04223
04224
04225
04226 void
04227 dump_solution_for_var (FILE *file, unsigned int var)
04228 {
04229 varinfo_t vi = get_varinfo (var);
04230 unsigned int i;
04231 bitmap_iterator bi;
04232
04233 fprintf (file, "%s = { ", vi->name);
04234 EXECUTE_IF_SET_IN_BITMAP (get_varinfo (vi->node)->solution, 0, i, bi)
04235 {
04236 fprintf (file, "%s ", get_varinfo (i)->name);
04237 }
04238 fprintf (file, "}\n");
04239 }
04240
04241
04242
04243 void
04244 debug_solution_for_var (unsigned int var)
04245 {
04246 dump_solution_for_var (stdout, var);
04247 }
04248
04249
04250
04251
04252 static void
04253 intra_create_variable_infos (void)
04254 {
04255 tree t;
04256 struct constraint_expr lhs, rhs;
04257 varinfo_t nonlocal_vi;
04258
04259
04260
04261 for (t = DECL_ARGUMENTS (current_function_decl); t; t = TREE_CHAIN (t))
04262 {
04263 varinfo_t p;
04264 unsigned int arg_id;
04265
04266 if (!could_have_pointers (t))
04267 continue;
04268
04269 arg_id = get_id_for_tree (t);
04270
04271
04272
04273
04274 if (POINTER_TYPE_P (TREE_TYPE (t))
04275 && flag_argument_noalias > 2)
04276 {
04277 varinfo_t vi;
04278 tree heapvar = heapvar_lookup (t);
04279 unsigned int id;
04280
04281 lhs.offset = 0;
04282 lhs.type = SCALAR;
04283 lhs.var = get_id_for_tree (t);
04284
04285 if (heapvar == NULL_TREE)
04286 {
04287 heapvar = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (t)),
04288 "PARM_NOALIAS");
04289 DECL_EXTERNAL (heapvar) = 1;
04290 if (referenced_vars)
04291 add_referenced_var (heapvar);
04292 heapvar_insert (t, heapvar);
04293 }
04294 id = get_id_for_tree (heapvar);
04295 vi = get_varinfo (id);
04296 vi->is_artificial_var = 1;
04297 vi->is_heap_var = 1;
04298 rhs.var = id;
04299 rhs.type = ADDRESSOF;
04300 rhs.offset = 0;
04301 for (p = get_varinfo (lhs.var); p; p = p->next)
04302 {
04303 struct constraint_expr temp = lhs;
04304 temp.var = p->id;
04305 process_constraint (new_constraint (temp, rhs));
04306 }
04307 }
04308 else
04309 {
04310 for (p = get_varinfo (arg_id); p; p = p->next)
04311 make_constraint_from_escaped (p);
04312 }
04313 }
04314 if (!nonlocal_all)
04315 nonlocal_all = create_nonlocal_var (void_type_node);
04316
04317
04318
04319 nonlocal_vars_id = create_variable_info_for (nonlocal_all,
04320 get_name (nonlocal_all));
04321 nonlocal_vi = get_varinfo (nonlocal_vars_id);
04322 nonlocal_vi->is_artificial_var = 1;
04323 nonlocal_vi->is_heap_var = 1;
04324 nonlocal_vi->is_unknown_size_var = 1;
04325 nonlocal_vi->directly_dereferenced = true;
04326
04327 rhs.var = nonlocal_vars_id;
04328 rhs.type = ADDRESSOF;
04329 rhs.offset = 0;
04330
04331 lhs.var = escaped_vars_id;
04332 lhs.type = SCALAR;
04333 lhs.offset = 0;
04334
04335 process_constraint (new_constraint (lhs, rhs));
04336 }
04337
04338
04339
04340
04341
04342
04343 static void
04344 set_uids_in_ptset (tree ptr, bitmap into, bitmap from)
04345 {
04346 unsigned int i;
04347 bitmap_iterator bi;
04348 subvar_t sv;
04349 unsigned HOST_WIDE_INT ptr_alias_set = get_alias_set (TREE_TYPE (ptr));
04350
04351 EXECUTE_IF_SET_IN_BITMAP (from, 0, i, bi)
04352 {
04353 varinfo_t vi = get_varinfo (i);
04354 unsigned HOST_WIDE_INT var_alias_set;
04355
04356
04357
04358 if (vi->is_artificial_var && !vi->is_heap_var)
04359 continue;
04360
04361 if (vi->has_union && get_subvars_for_var (vi->decl) != NULL)
04362 {
04363
04364
04365 for (sv = get_subvars_for_var (vi->decl); sv; sv = sv->next)
04366 bitmap_set_bit (into, DECL_UID (sv->var));
04367 }
04368 else if (TREE_CODE (vi->decl) == VAR_DECL
04369 || TREE_CODE (vi->decl) == PARM_DECL)
04370 {
04371 if (var_can_have_subvars (vi->decl)
04372 && get_subvars_for_var (vi->decl))
04373 {
04374
04375
04376 tree sft = get_subvar_at (vi->decl, vi->offset);
04377 if (sft)
04378 {
04379 var_alias_set = get_alias_set (sft);
04380 if (!vi->directly_dereferenced
04381 || alias_sets_conflict_p (ptr_alias_set, var_alias_set))
04382 bitmap_set_bit (into, DECL_UID (sft));
04383 }
04384 }
04385 else
04386 {
04387
04388
04389 if (vi->is_artificial_var)
04390 bitmap_set_bit (into, DECL_UID (vi->decl));
04391 else
04392 {
04393 var_alias_set = get_alias_set (vi->decl);
04394 if (!vi->directly_dereferenced
04395 || alias_sets_conflict_p (ptr_alias_set, var_alias_set))
04396 bitmap_set_bit (into, DECL_UID (vi->decl));
04397 }
04398 }
04399 }
04400 }
04401 }
04402
04403
04404 static bool have_alias_info = false;
04405
04406
04407
04408
04409 bool
04410 find_what_p_points_to (tree p)
04411 {
04412 unsigned int id = 0;
04413 tree lookup_p = p;
04414
04415 if (!have_alias_info)
04416 return false;
04417
04418
04419
04420 if (TREE_CODE (p) == SSA_NAME
04421 && TREE_CODE (SSA_NAME_VAR (p)) == PARM_DECL
04422 && default_def (SSA_NAME_VAR (p)) == p)
04423 lookup_p = SSA_NAME_VAR (p);
04424
04425 if (lookup_id_for_tree (lookup_p, &id))
04426 {
04427 varinfo_t vi = get_varinfo (id);
04428
04429 if (vi->is_artificial_var)
04430 return false;
04431
04432
04433 if (vi->size != vi->fullsize)
04434 {
04435
04436
04437
04438 if (!var_can_have_subvars (vi->decl)
04439 || get_subvars_for_var (vi->decl) == NULL)
04440 return false;
04441 }
04442 else
04443 {
04444 struct ptr_info_def *pi = get_ptr_info (p);
04445 unsigned int i;
04446 bitmap_iterator bi;
04447
04448
04449
04450 vi = get_varinfo (vi->node);
04451
04452
04453
04454 EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, i, bi)
04455 {
04456 varinfo_t vi = get_varinfo (i);
04457
04458 if (vi->is_artificial_var)
04459 {
04460
04461
04462
04463 if (vi->id == nothing_id)
04464 pi->pt_null = 1;
04465 else if (vi->id == anything_id)
04466 pi->pt_anything = 1;
04467 else if (vi->id == readonly_id)
04468 pi->pt_anything = 1;
04469 else if (vi->id == integer_id)
04470 pi->pt_anything = 1;
04471 else if (vi->is_heap_var)
04472 pi->pt_global_mem = 1;
04473 }
04474 }
04475
04476 if (pi->pt_anything)
04477 return false;
04478
04479 if (!pi->pt_vars)
04480 pi->pt_vars = BITMAP_GGC_ALLOC ();
04481
04482 set_uids_in_ptset (vi->decl, pi->pt_vars, vi->solution);
04483
04484 if (bitmap_empty_p (pi->pt_vars))
04485 pi->pt_vars = NULL;
04486
04487 return true;
04488 }
04489 }
04490
04491 return false;
04492 }
04493
04494
04495
04496
04497
04498 void
04499 dump_sa_points_to_info (FILE *outfile)
04500 {
04501 unsigned int i;
04502
04503 fprintf (outfile, "\nPoints-to sets\n\n");
04504
04505 if (dump_flags & TDF_STATS)
04506 {
04507 fprintf (outfile, "Stats:\n");
04508 fprintf (outfile, "Total vars: %d\n", stats.total_vars);
04509 fprintf (outfile, "Statically unified vars: %d\n",
04510 stats.unified_vars_static);
04511 fprintf (outfile, "Collapsed vars: %d\n", stats.collapsed_vars);
04512 fprintf (outfile, "Dynamically unified vars: %d\n",
04513 stats.unified_vars_dynamic);
04514 fprintf (outfile, "Iterations: %d\n", stats.iterations);
04515 fprintf (outfile, "Number of edges: %d\n", stats.num_edges);
04516 }
04517
04518 for (i = 0; i < VEC_length (varinfo_t, varmap); i++)
04519 dump_solution_for_var (outfile, i);
04520 }
04521
04522
04523
04524
04525 void
04526 debug_sa_points_to_info (void)
04527 {
04528 dump_sa_points_to_info (stderr);
04529 }
04530
04531
04532
04533
04534
04535 static void
04536 init_base_vars (void)
04537 {
04538 struct constraint_expr lhs, rhs;
04539
04540
04541
04542 nothing_tree = create_tmp_var_raw (void_type_node, "NULL");
04543 var_nothing = new_var_info (nothing_tree, 0, "NULL", 0);
04544 insert_id_for_tree (nothing_tree, 0);
04545 var_nothing->is_artificial_var = 1;
04546 var_nothing->offset = 0;
04547 var_nothing->size = ~0;
04548 var_nothing->fullsize = ~0;
04549 var_nothing->is_special_var = 1;
04550 nothing_id = 0;
04551 VEC_safe_push (varinfo_t, heap, varmap, var_nothing);
04552
04553
04554
04555 anything_tree = create_tmp_var_raw (void_type_node, "ANYTHING");
04556 var_anything = new_var_info (anything_tree, 1, "ANYTHING", 1);
04557 insert_id_for_tree (anything_tree, 1);
04558 var_anything->is_artificial_var = 1;
04559 var_anything->size = ~0;
04560 var_anything->offset = 0;
04561 var_anything->next = NULL;
04562 var_anything->fullsize = ~0;
04563 var_anything->is_special_var = 1;
04564 anything_id = 1;
04565
04566
04567
04568
04569 VEC_safe_push (varinfo_t, heap, varmap, var_anything);
04570 lhs.type = SCALAR;
04571 lhs.var = anything_id;
04572 lhs.offset = 0;
04573 rhs.type = ADDRESSOF;
04574 rhs.var = anything_id;
04575 rhs.offset = 0;
04576 var_anything->address_taken = true;
04577
04578
04579
04580
04581 VEC_safe_push (constraint_t, heap, constraints, new_constraint (lhs, rhs));
04582
04583
04584
04585 readonly_tree = create_tmp_var_raw (void_type_node, "READONLY");
04586 var_readonly = new_var_info (readonly_tree, 2, "READONLY", 2);
04587 var_readonly->is_artificial_var = 1;
04588 var_readonly->offset = 0;
04589 var_readonly->size = ~0;
04590 var_readonly->fullsize = ~0;
04591 var_readonly->next = NULL;
04592 var_readonly->is_special_var = 1;
04593 insert_id_for_tree (readonly_tree, 2);
04594 readonly_id = 2;
04595 VEC_safe_push (varinfo_t, heap, varmap, var_readonly);
04596
04597
04598
04599
04600
04601 lhs.type = SCALAR;
04602 lhs.var = readonly_id;
04603 lhs.offset = 0;
04604 rhs.type = ADDRESSOF;
04605 rhs.var = anything_id;
04606 rhs.offset = 0;
04607
04608 process_constraint (new_constraint (lhs, rhs));
04609
04610
04611
04612 integer_tree = create_tmp_var_raw (void_type_node, "INTEGER");
04613 var_integer = new_var_info (integer_tree, 3, "INTEGER", 3);
04614 insert_id_for_tree (integer_tree, 3);
04615 var_integer->is_artificial_var = 1;
04616 var_integer->size = ~0;
04617 var_integer->fullsize = ~0;
04618 var_integer->offset = 0;
04619 var_integer->next = NULL;
04620 var_integer->is_special_var = 1;
04621 integer_id = 3;
04622 VEC_safe_push (varinfo_t, heap, varmap, var_integer);
04623
04624
04625
04626 lhs.type = SCALAR;
04627 lhs.var = integer_id;
04628 lhs.offset = 0;
04629 rhs.type = ADDRESSOF;
04630 rhs.var = anything_id;
04631 rhs.offset = 0;
04632 process_constraint (new_constraint (lhs, rhs));
04633
04634
04635
04636 escaped_vars_tree = create_tmp_var_raw (void_type_node, "ESCAPED_VARS");
04637 var_escaped_vars = new_var_info (escaped_vars_tree, 4, "ESCAPED_VARS", 4);
04638 insert_id_for_tree (escaped_vars_tree, 4);
04639 var_escaped_vars->is_artificial_var = 1;
04640 var_escaped_vars->size = ~0;
04641 var_escaped_vars->fullsize = ~0;
04642 var_escaped_vars->offset = 0;
04643 var_escaped_vars->next = NULL;
04644 escaped_vars_id = 4;
04645 VEC_safe_push (varinfo_t, heap, varmap, var_escaped_vars);
04646
04647
04648 lhs.type = SCALAR;
04649 lhs.var = escaped_vars_id;
04650 lhs.offset = 0;
04651 rhs.type = DEREF;
04652 rhs.var = escaped_vars_id;
04653 rhs.offset = 0;
04654 process_constraint (new_constraint (lhs, rhs));
04655
04656 }
04657
04658
04659
04660 static void
04661 init_alias_vars (void)
04662 {
04663 bitmap_obstack_initialize (&ptabitmap_obstack);
04664 bitmap_obstack_initialize (&predbitmap_obstack);
04665
04666 constraint_pool = create_alloc_pool ("Constraint pool",
04667 sizeof (struct constraint), 30);
04668 variable_info_pool = create_alloc_pool ("Variable info pool",
04669 sizeof (struct variable_info), 30);
04670 constraint_edge_pool = create_alloc_pool ("Constraint edges",
04671 sizeof (struct constraint_edge), 30);
04672
04673 constraints = VEC_alloc (constraint_t, heap, 8);
04674 varmap = VEC_alloc (varinfo_t, heap, 8);
04675 id_for_tree = htab_create (10, tree_id_hash, tree_id_eq, free);
04676 memset (&stats, 0, sizeof (stats));
04677
04678 init_base_vars ();
04679 }
04680
04681
04682
04683
04684 static void
04685 find_escape_constraints (tree stmt)
04686 {
04687 enum escape_type stmt_escape_type = is_escape_site (stmt);
04688 tree rhs;
04689 VEC(ce_s, heap) *rhsc = NULL;
04690 struct constraint_expr *c;
04691 size_t i;
04692
04693 if (stmt_escape_type == NO_ESCAPE)
04694 return;
04695
04696 if (TREE_CODE (stmt) == RETURN_EXPR)
04697 {
04698
04699
04700 if (!TREE_OPERAND (stmt, 0))
04701 return;
04702 if (TREE_CODE (TREE_OPERAND (stmt, 0)) == MODIFY_EXPR)
04703 rhs = TREE_OPERAND (TREE_OPERAND (stmt, 0), 1);
04704 else
04705 rhs = TREE_OPERAND (stmt, 0);
04706
04707 get_constraint_for (rhs, &rhsc);
04708 for (i = 0; VEC_iterate (ce_s, rhsc, i, c); i++)
04709 make_constraint_to_escaped (*c);
04710 VEC_free (ce_s, heap, rhsc);
04711 return;
04712 }
04713 else if (TREE_CODE (stmt) == ASM_EXPR)
04714 {
04715
04716 tree arg;
04717
04718 for (arg = ASM_INPUTS (stmt); arg; arg = TREE_CHAIN (arg))
04719 {
04720 rhsc = NULL;
04721 get_constraint_for (TREE_VALUE (arg), &rhsc);
04722 for (i = 0; VEC_iterate (ce_s, rhsc, i, c); i++)
04723 make_constraint_to_escaped (*c);
04724 VEC_free (ce_s, heap, rhsc);
04725 }
04726 return;
04727 }
04728 else if (TREE_CODE (stmt) == CALL_EXPR
04729 || (TREE_CODE (stmt) == MODIFY_EXPR
04730 && TREE_CODE (TREE_OPERAND (stmt, 1)) == CALL_EXPR))
04731 {
04732
04733 tree arg;
04734
04735 if (TREE_CODE (stmt) == MODIFY_EXPR)
04736 stmt = TREE_OPERAND (stmt, 1);
04737 for (arg = TREE_OPERAND (stmt, 1); arg; arg = TREE_CHAIN (arg))
04738 {
04739 if (POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arg))))
04740 {
04741 rhsc = NULL;
04742 get_constraint_for (TREE_VALUE (arg), &rhsc);
04743 for (i = 0; VEC_iterate (ce_s, rhsc, i, c); i++)
04744 make_constraint_to_escaped (*c);
04745 VEC_free (ce_s, heap, rhsc);
04746 }
04747 }
04748 return;
04749 }
04750 else
04751 {
04752 gcc_assert (TREE_CODE (stmt) == MODIFY_EXPR);
04753 }
04754
04755 gcc_assert (stmt_escape_type == ESCAPE_BAD_CAST
04756 || stmt_escape_type == ESCAPE_STORED_IN_GLOBAL
04757 || stmt_escape_type == ESCAPE_UNKNOWN);
04758 rhs = TREE_OPERAND (stmt, 1);
04759
04760
04761
04762
04763 if (TREE_CODE (rhs) == NOP_EXPR
04764 || TREE_CODE (rhs) == CONVERT_EXPR
04765 || TREE_CODE (rhs) == NON_LVALUE_EXPR)
04766 {
04767 get_constraint_for (TREE_OPERAND (rhs, 0), &rhsc);
04768 }
04769 else if (CONSTANT_CLASS_P (rhs))
04770 return;
04771 else
04772 {
04773 get_constraint_for (rhs, &rhsc);
04774 }
04775 for (i = 0; VEC_iterate (ce_s, rhsc, i, c); i++)
04776 make_constraint_to_escaped (*c);
04777 VEC_free (ce_s, heap, rhsc);
04778 }
04779
04780
04781
04782
04783 void
04784 compute_points_to_sets (struct alias_info *ai)
04785 {
04786 basic_block bb;
04787
04788 timevar_push (TV_TREE_PTA);
04789
04790 init_alias_vars ();
04791
04792 intra_create_variable_infos ();
04793
04794
04795 FOR_EACH_BB (bb)
04796 {
04797 block_stmt_iterator bsi;
04798 tree phi;
04799
04800 for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
04801 {
04802 if (is_gimple_reg (PHI_RESULT (phi)))
04803 {
04804 find_func_aliases (phi);
04805
04806
04807
04808
04809 update_alias_info (phi, ai);
04810 }
04811 }
04812
04813 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
04814 {
04815 tree stmt = bsi_stmt (bsi);
04816
04817 find_func_aliases (stmt);
04818 find_escape_constraints (stmt);
04819
04820
04821
04822
04823 update_alias_info (stmt, ai);
04824 }
04825 }
04826
04827 build_constraint_graph ();
04828
04829 if (dump_file)
04830 {
04831 fprintf (dump_file, "Points-to analysis\n\nConstraints:\n\n");
04832 dump_constraints (dump_file);
04833 }
04834
04835 if (dump_file)
04836 fprintf (dump_file,
04837 "\nCollapsing static cycles and doing variable "
04838 "substitution:\n");
04839
04840 find_and_collapse_graph_cycles (graph, false);
04841 perform_var_substitution (graph);
04842
04843 if (dump_file)
04844 fprintf (dump_file, "\nSolving graph:\n");
04845
04846 solve_graph (graph);
04847
04848 if (dump_file)
04849 dump_sa_points_to_info (dump_file);
04850
04851 have_alias_info = true;
04852
04853 timevar_pop (TV_TREE_PTA);
04854 }
04855
04856
04857
04858
04859 void
04860 delete_points_to_sets (void)
04861 {
04862 varinfo_t v;
04863 int i;
04864
04865 htab_delete (id_for_tree);
04866 bitmap_obstack_release (&ptabitmap_obstack);
04867 bitmap_obstack_release (&predbitmap_obstack);
04868 VEC_free (constraint_t, heap, constraints);
04869
04870 for (i = 0; VEC_iterate (varinfo_t, varmap, i, v); i++)
04871 {
04872
04873 if (i >= graph_size)
04874 break;
04875
04876 VEC_free (constraint_edge_t, heap, graph->succs[i]);
04877 VEC_free (constraint_edge_t, heap, graph->preds[i]);
04878 VEC_free (constraint_t, heap, v->complex);
04879 }
04880 free (graph->zero_weight_preds);
04881 free (graph->zero_weight_succs);
04882 free (graph->succs);
04883 free (graph->preds);
04884 free (graph);
04885
04886 VEC_free (varinfo_t, heap, varmap);
04887 free_alloc_pool (variable_info_pool);
04888 free_alloc_pool (constraint_pool);
04889 free_alloc_pool (constraint_edge_pool);
04890
04891 have_alias_info = false;
04892 }
04893
04894
04895 static bool
04896 gate_ipa_pta (void)
04897 {
04898 return (flag_unit_at_a_time != 0
04899 && flag_ipa_pta
04900
04901 && !(errorcount || sorrycount));
04902 }
04903
04904
04905 static unsigned int
04906 ipa_pta_execute (void)
04907 {
04908 struct cgraph_node *node;
04909 in_ipa_mode = 1;
04910 init_alias_heapvars ();
04911 init_alias_vars ();
04912
04913 for (node = cgraph_nodes; node; node = node->next)
04914 {
04915 if (!node->analyzed || cgraph_is_master_clone (node))
04916 {
04917 unsigned int varid;
04918
04919 varid = create_function_info_for (node->decl,
04920 cgraph_node_name (node));
04921 if (node->local.externally_visible)
04922 {
04923 varinfo_t fi = get_varinfo (varid);
04924 for (; fi; fi = fi->next)
04925 make_constraint_from_escaped (fi);
04926 }
04927 }
04928 }
04929 for (node = cgraph_nodes; node; node = node->next)
04930 {
04931 if (node->analyzed && cgraph_is_master_clone (node))
04932 {
04933 struct function *cfun = DECL_STRUCT_FUNCTION (node->decl);
04934 basic_block bb;
04935 tree old_func_decl = current_function_decl;
04936 if (dump_file)
04937 fprintf (dump_file,
04938 "Generating constraints for %s\n",
04939 cgraph_node_name (node));
04940 push_cfun (cfun);
04941 current_function_decl = node->decl;
04942
04943 FOR_EACH_BB_FN (bb, cfun)
04944 {
04945 block_stmt_iterator bsi;
04946 tree phi;
04947
04948 for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
04949 {
04950 if (is_gimple_reg (PHI_RESULT (phi)))
04951 {
04952 find_func_aliases (phi);
04953 }
04954 }
04955
04956 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
04957 {
04958 tree stmt = bsi_stmt (bsi);
04959 find_func_aliases (stmt);
04960 }
04961 }
04962 current_function_decl = old_func_decl;
04963 pop_cfun ();
04964 }
04965 else
04966 {
04967
04968 }
04969 }
04970
04971 build_constraint_graph ();
04972
04973 if (dump_file)
04974 {
04975 fprintf (dump_file, "Points-to analysis\n\nConstraints:\n\n");
04976 dump_constraints (dump_file);
04977 }
04978
04979 if (dump_file)
04980 fprintf (dump_file,
04981 "\nCollapsing static cycles and doing variable "
04982 "substitution:\n");
04983
04984 find_and_collapse_graph_cycles (graph, false);
04985 perform_var_substitution (graph);
04986
04987 if (dump_file)
04988 fprintf (dump_file, "\nSolving graph:\n");
04989
04990 solve_graph (graph);
04991
04992 if (dump_file)
04993 dump_sa_points_to_info (dump_file);
04994 in_ipa_mode = 0;
04995 delete_alias_heapvars ();
04996 delete_points_to_sets ();
04997 return 0;
04998 }
04999
05000 struct tree_opt_pass pass_ipa_pta =
05001 {
05002 "pta",
05003 gate_ipa_pta,
05004 ipa_pta_execute,
05005 NULL,
05006 NULL,
05007 0,
05008 TV_IPA_PTA,
05009 0,
05010 0,
05011 0,
05012 0,
05013 0,
05014 0
05015 };
05016
05017
05018 void
05019 init_alias_heapvars (void)
05020 {
05021 heapvar_for_stmt = htab_create_ggc (11, tree_map_hash, tree_map_eq,
05022 NULL);
05023 nonlocal_all = NULL_TREE;
05024 }
05025
05026 void
05027 delete_alias_heapvars (void)
05028 {
05029 nonlocal_all = NULL_TREE;
05030 htab_delete (heapvar_for_stmt);
05031 }
05032
05033
05034 #include "gt-tree-ssa-structalias.h"