OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [tree-ssa-structalias.c] - Blame information for rev 290

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 280 jeremybenn
/* Tree based points-to analysis
2
   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010
3
   Free Software Foundation, Inc.
4
   Contributed by Daniel Berlin <dberlin@dberlin.org>
5
 
6
   This file is part of GCC.
7
 
8
   GCC is free software; you can redistribute it and/or modify
9
   under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 3 of the License, or
11
   (at your option) any later version.
12
 
13
   GCC is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
 
18
   You should have received a copy of the GNU General Public License
19
   along with GCC; see the file COPYING3.  If not see
20
   <http://www.gnu.org/licenses/>.  */
21
 
22
#include "config.h"
23
#include "system.h"
24
#include "coretypes.h"
25
#include "tm.h"
26
#include "ggc.h"
27
#include "obstack.h"
28
#include "bitmap.h"
29
#include "flags.h"
30
#include "rtl.h"
31
#include "tm_p.h"
32
#include "hard-reg-set.h"
33
#include "basic-block.h"
34
#include "output.h"
35
#include "tree.h"
36
#include "tree-flow.h"
37
#include "tree-inline.h"
38
#include "varray.h"
39
#include "diagnostic.h"
40
#include "toplev.h"
41
#include "gimple.h"
42
#include "hashtab.h"
43
#include "function.h"
44
#include "cgraph.h"
45
#include "tree-pass.h"
46
#include "timevar.h"
47
#include "alloc-pool.h"
48
#include "splay-tree.h"
49
#include "params.h"
50
#include "cgraph.h"
51
#include "alias.h"
52
#include "pointer-set.h"
53
 
54
/* The idea behind this analyzer is to generate set constraints from the
55
   program, then solve the resulting constraints in order to generate the
56
   points-to sets.
57
 
58
   Set constraints are a way of modeling program analysis problems that
59
   involve sets.  They consist of an inclusion constraint language,
60
   describing the variables (each variable is a set) and operations that
61
   are involved on the variables, and a set of rules that derive facts
62
   from these operations.  To solve a system of set constraints, you derive
63
   all possible facts under the rules, which gives you the correct sets
64
   as a consequence.
65
 
66
   See  "Efficient Field-sensitive pointer analysis for C" by "David
67
   J. Pearce and Paul H. J. Kelly and Chris Hankin, at
68
   http://citeseer.ist.psu.edu/pearce04efficient.html
69
 
70
   Also see "Ultra-fast Aliasing Analysis using CLA: A Million Lines
71
   of C Code in a Second" by ""Nevin Heintze and Olivier Tardieu" at
72
   http://citeseer.ist.psu.edu/heintze01ultrafast.html
73
 
74
   There are three types of real constraint expressions, DEREF,
75
   ADDRESSOF, and SCALAR.  Each constraint expression consists
76
   of a constraint type, a variable, and an offset.
77
 
78
   SCALAR is a constraint expression type used to represent x, whether
79
   it appears on the LHS or the RHS of a statement.
80
   DEREF is a constraint expression type used to represent *x, whether
81
   it appears on the LHS or the RHS of a statement.
82
   ADDRESSOF is a constraint expression used to represent &x, whether
83
   it appears on the LHS or the RHS of a statement.
84
 
85
   Each pointer variable in the program is assigned an integer id, and
86
   each field of a structure variable is assigned an integer id as well.
87
 
88
   Structure variables are linked to their list of fields through a "next
89
   field" in each variable that points to the next field in offset
90
   order.
91
   Each variable for a structure field has
92
 
93
   1. "size", that tells the size in bits of that field.
94
   2. "fullsize, that tells the size in bits of the entire structure.
95
   3. "offset", that tells the offset in bits from the beginning of the
96
   structure to this field.
97
 
98
   Thus,
99
   struct f
100
   {
101
     int a;
102
     int b;
103
   } foo;
104
   int *bar;
105
 
106
   looks like
107
 
108
   foo.a -> id 1, size 32, offset 0, fullsize 64, next foo.b
109
   foo.b -> id 2, size 32, offset 32, fullsize 64, next NULL
110
   bar -> id 3, size 32, offset 0, fullsize 32, next NULL
111
 
112
 
113
  In order to solve the system of set constraints, the following is
114
  done:
115
 
116
  1. Each constraint variable x has a solution set associated with it,
117
  Sol(x).
118
 
119
  2. Constraints are separated into direct, copy, and complex.
120
  Direct constraints are ADDRESSOF constraints that require no extra
121
  processing, such as P = &Q
122
  Copy constraints are those of the form P = Q.
123
  Complex constraints are all the constraints involving dereferences
124
  and offsets (including offsetted copies).
125
 
126
  3. All direct constraints of the form P = &Q are processed, such
127
  that Q is added to Sol(P)
128
 
129
  4. All complex constraints for a given constraint variable are stored in a
130
  linked list attached to that variable's node.
131
 
132
  5. A directed graph is built out of the copy constraints. Each
133
  constraint variable is a node in the graph, and an edge from
134
  Q to P is added for each copy constraint of the form P = Q
135
 
136
  6. The graph is then walked, and solution sets are
137
  propagated along the copy edges, such that an edge from Q to P
138
  causes Sol(P) <- Sol(P) union Sol(Q).
139
 
140
  7.  As we visit each node, all complex constraints associated with
141
  that node are processed by adding appropriate copy edges to the graph, or the
142
  appropriate variables to the solution set.
143
 
144
  8. The process of walking the graph is iterated until no solution
145
  sets change.
146
 
147
  Prior to walking the graph in steps 6 and 7, We perform static
148
  cycle elimination on the constraint graph, as well
149
  as off-line variable substitution.
150
 
151
  TODO: Adding offsets to pointer-to-structures can be handled (IE not punted
152
  on and turned into anything), but isn't.  You can just see what offset
153
  inside the pointed-to struct it's going to access.
154
 
155
  TODO: Constant bounded arrays can be handled as if they were structs of the
156
  same number of elements.
157
 
158
  TODO: Modeling heap and incoming pointers becomes much better if we
159
  add fields to them as we discover them, which we could do.
160
 
161
  TODO: We could handle unions, but to be honest, it's probably not
162
  worth the pain or slowdown.  */
163
 
164
static GTY ((if_marked ("tree_map_marked_p"), param_is (struct tree_map)))
165
htab_t heapvar_for_stmt;
166
 
167
static bool use_field_sensitive = true;
168
static int in_ipa_mode = 0;
169
 
170
/* Used for predecessor bitmaps. */
171
static bitmap_obstack predbitmap_obstack;
172
 
173
/* Used for points-to sets.  */
174
static bitmap_obstack pta_obstack;
175
 
176
/* Used for oldsolution members of variables. */
177
static bitmap_obstack oldpta_obstack;
178
 
179
/* Used for per-solver-iteration bitmaps.  */
180
static bitmap_obstack iteration_obstack;
181
 
182
static unsigned int create_variable_info_for (tree, const char *);
183
typedef struct constraint_graph *constraint_graph_t;
184
static void unify_nodes (constraint_graph_t, unsigned int, unsigned int, bool);
185
 
186
struct constraint;
187
typedef struct constraint *constraint_t;
188
 
189
DEF_VEC_P(constraint_t);
190
DEF_VEC_ALLOC_P(constraint_t,heap);
191
 
192
#define EXECUTE_IF_IN_NONNULL_BITMAP(a, b, c, d)        \
193
  if (a)                                                \
194
    EXECUTE_IF_SET_IN_BITMAP (a, b, c, d)
195
 
196
static struct constraint_stats
197
{
198
  unsigned int total_vars;
199
  unsigned int nonpointer_vars;
200
  unsigned int unified_vars_static;
201
  unsigned int unified_vars_dynamic;
202
  unsigned int iterations;
203
  unsigned int num_edges;
204
  unsigned int num_implicit_edges;
205
  unsigned int points_to_sets_created;
206
} stats;
207
 
208
struct variable_info
209
{
210
  /* ID of this variable  */
211
  unsigned int id;
212
 
213
  /* True if this is a variable created by the constraint analysis, such as
214
     heap variables and constraints we had to break up.  */
215
  unsigned int is_artificial_var : 1;
216
 
217
  /* True if this is a special variable whose solution set should not be
218
     changed.  */
219
  unsigned int is_special_var : 1;
220
 
221
  /* True for variables whose size is not known or variable.  */
222
  unsigned int is_unknown_size_var : 1;
223
 
224
  /* True for (sub-)fields that represent a whole variable.  */
225
  unsigned int is_full_var : 1;
226
 
227
  /* True if this is a heap variable.  */
228
  unsigned int is_heap_var : 1;
229
 
230
  /* True if this is a variable tracking a restrict pointer source.  */
231
  unsigned int is_restrict_var : 1;
232
 
233
  /* True if this field may contain pointers.  */
234
  unsigned int may_have_pointers : 1;
235
 
236
  /* True if this represents a global variable.  */
237
  unsigned int is_global_var : 1;
238
 
239
  /* A link to the variable for the next field in this structure.  */
240
  struct variable_info *next;
241
 
242
  /* Offset of this variable, in bits, from the base variable  */
243
  unsigned HOST_WIDE_INT offset;
244
 
245
  /* Size of the variable, in bits.  */
246
  unsigned HOST_WIDE_INT size;
247
 
248
  /* Full size of the base variable, in bits.  */
249
  unsigned HOST_WIDE_INT fullsize;
250
 
251
  /* Name of this variable */
252
  const char *name;
253
 
254
  /* Tree that this variable is associated with.  */
255
  tree decl;
256
 
257
  /* Points-to set for this variable.  */
258
  bitmap solution;
259
 
260
  /* Old points-to set for this variable.  */
261
  bitmap oldsolution;
262
};
263
typedef struct variable_info *varinfo_t;
264
 
265
static varinfo_t first_vi_for_offset (varinfo_t, unsigned HOST_WIDE_INT);
266
static varinfo_t first_or_preceding_vi_for_offset (varinfo_t,
267
                                                   unsigned HOST_WIDE_INT);
268
static varinfo_t lookup_vi_for_tree (tree);
269
 
270
/* Pool of variable info structures.  */
271
static alloc_pool variable_info_pool;
272
 
273
DEF_VEC_P(varinfo_t);
274
 
275
DEF_VEC_ALLOC_P(varinfo_t, heap);
276
 
277
/* Table of variable info structures for constraint variables.
278
   Indexed directly by variable info id.  */
279
static VEC(varinfo_t,heap) *varmap;
280
 
281
/* Return the varmap element N */
282
 
283
static inline varinfo_t
284
get_varinfo (unsigned int n)
285
{
286
  return VEC_index (varinfo_t, varmap, n);
287
}
288
 
289
/* Static IDs for the special variables.  */
290
enum { nothing_id = 0, anything_id = 1, readonly_id = 2,
291
       escaped_id = 3, nonlocal_id = 4, callused_id = 5,
292
       storedanything_id = 6, integer_id = 7 };
293
 
294
struct GTY(()) heapvar_map {
295
  struct tree_map map;
296
  unsigned HOST_WIDE_INT offset;
297
};
298
 
299
static int
300
heapvar_map_eq (const void *p1, const void *p2)
301
{
302
  const struct heapvar_map *h1 = (const struct heapvar_map *)p1;
303
  const struct heapvar_map *h2 = (const struct heapvar_map *)p2;
304
  return (h1->map.base.from == h2->map.base.from
305
          && h1->offset == h2->offset);
306
}
307
 
308
static unsigned int
309
heapvar_map_hash (struct heapvar_map *h)
310
{
311
  return iterative_hash_host_wide_int (h->offset,
312
                                       htab_hash_pointer (h->map.base.from));
313
}
314
 
315
/* Lookup a heap var for FROM, and return it if we find one.  */
316
 
317
static tree
318
heapvar_lookup (tree from, unsigned HOST_WIDE_INT offset)
319
{
320
  struct heapvar_map *h, in;
321
  in.map.base.from = from;
322
  in.offset = offset;
323
  h = (struct heapvar_map *) htab_find_with_hash (heapvar_for_stmt, &in,
324
                                                  heapvar_map_hash (&in));
325
  if (h)
326
    return h->map.to;
327
  return NULL_TREE;
328
}
329
 
330
/* Insert a mapping FROM->TO in the heap var for statement
331
   hashtable.  */
332
 
333
static void
334
heapvar_insert (tree from, unsigned HOST_WIDE_INT offset, tree to)
335
{
336
  struct heapvar_map *h;
337
  void **loc;
338
 
339
  h = GGC_NEW (struct heapvar_map);
340
  h->map.base.from = from;
341
  h->offset = offset;
342
  h->map.hash = heapvar_map_hash (h);
343
  h->map.to = to;
344
  loc = htab_find_slot_with_hash (heapvar_for_stmt, h, h->map.hash, INSERT);
345
  gcc_assert (*loc == NULL);
346
  *(struct heapvar_map **) loc = h;
347
}
348
 
349
/* Return a new variable info structure consisting for a variable
350
   named NAME, and using constraint graph node NODE.  Append it
351
   to the vector of variable info structures.  */
352
 
353
static varinfo_t
354
new_var_info (tree t, const char *name)
355
{
356
  unsigned index = VEC_length (varinfo_t, varmap);
357
  varinfo_t ret = (varinfo_t) pool_alloc (variable_info_pool);
358
 
359
  ret->id = index;
360
  ret->name = name;
361
  ret->decl = t;
362
  /* Vars without decl are artificial and do not have sub-variables.  */
363
  ret->is_artificial_var = (t == NULL_TREE);
364
  ret->is_special_var = false;
365
  ret->is_unknown_size_var = false;
366
  ret->is_full_var = (t == NULL_TREE);
367
  ret->is_heap_var = false;
368
  ret->is_restrict_var = false;
369
  ret->may_have_pointers = true;
370
  ret->is_global_var = (t == NULL_TREE);
371
  if (t && DECL_P (t))
372
    ret->is_global_var = is_global_var (t);
373
  ret->solution = BITMAP_ALLOC (&pta_obstack);
374
  ret->oldsolution = BITMAP_ALLOC (&oldpta_obstack);
375
  ret->next = NULL;
376
 
377
  VEC_safe_push (varinfo_t, heap, varmap, ret);
378
 
379
  return ret;
380
}
381
 
382
typedef enum {SCALAR, DEREF, ADDRESSOF} constraint_expr_type;
383
 
384
/* An expression that appears in a constraint.  */
385
 
386
struct constraint_expr
387
{
388
  /* Constraint type.  */
389
  constraint_expr_type type;
390
 
391
  /* Variable we are referring to in the constraint.  */
392
  unsigned int var;
393
 
394
  /* Offset, in bits, of this constraint from the beginning of
395
     variables it ends up referring to.
396
 
397
     IOW, in a deref constraint, we would deref, get the result set,
398
     then add OFFSET to each member.   */
399
  HOST_WIDE_INT offset;
400
};
401
 
402
/* Use 0x8000... as special unknown offset.  */
403
#define UNKNOWN_OFFSET ((HOST_WIDE_INT)-1 << (HOST_BITS_PER_WIDE_INT-1))
404
 
405
typedef struct constraint_expr ce_s;
406
DEF_VEC_O(ce_s);
407
DEF_VEC_ALLOC_O(ce_s, heap);
408
static void get_constraint_for_1 (tree, VEC(ce_s, heap) **, bool);
409
static void get_constraint_for (tree, VEC(ce_s, heap) **);
410
static void do_deref (VEC (ce_s, heap) **);
411
 
412
/* Our set constraints are made up of two constraint expressions, one
413
   LHS, and one RHS.
414
 
415
   As described in the introduction, our set constraints each represent an
416
   operation between set valued variables.
417
*/
418
struct constraint
419
{
420
  struct constraint_expr lhs;
421
  struct constraint_expr rhs;
422
};
423
 
424
/* List of constraints that we use to build the constraint graph from.  */
425
 
426
static VEC(constraint_t,heap) *constraints;
427
static alloc_pool constraint_pool;
428
 
429
/* The constraint graph is represented as an array of bitmaps
430
   containing successor nodes.  */
431
 
432
struct constraint_graph
433
{
434
  /* Size of this graph, which may be different than the number of
435
     nodes in the variable map.  */
436
  unsigned int size;
437
 
438
  /* Explicit successors of each node. */
439
  bitmap *succs;
440
 
441
  /* Implicit predecessors of each node (Used for variable
442
     substitution). */
443
  bitmap *implicit_preds;
444
 
445
  /* Explicit predecessors of each node (Used for variable substitution).  */
446
  bitmap *preds;
447
 
448
  /* Indirect cycle representatives, or -1 if the node has no indirect
449
     cycles.  */
450
  int *indirect_cycles;
451
 
452
  /* Representative node for a node.  rep[a] == a unless the node has
453
     been unified. */
454
  unsigned int *rep;
455
 
456
  /* Equivalence class representative for a label.  This is used for
457
     variable substitution.  */
458
  int *eq_rep;
459
 
460
  /* Pointer equivalence label for a node.  All nodes with the same
461
     pointer equivalence label can be unified together at some point
462
     (either during constraint optimization or after the constraint
463
     graph is built).  */
464
  unsigned int *pe;
465
 
466
  /* Pointer equivalence representative for a label.  This is used to
467
     handle nodes that are pointer equivalent but not location
468
     equivalent.  We can unite these once the addressof constraints
469
     are transformed into initial points-to sets.  */
470
  int *pe_rep;
471
 
472
  /* Pointer equivalence label for each node, used during variable
473
     substitution.  */
474
  unsigned int *pointer_label;
475
 
476
  /* Location equivalence label for each node, used during location
477
     equivalence finding.  */
478
  unsigned int *loc_label;
479
 
480
  /* Pointed-by set for each node, used during location equivalence
481
     finding.  This is pointed-by rather than pointed-to, because it
482
     is constructed using the predecessor graph.  */
483
  bitmap *pointed_by;
484
 
485
  /* Points to sets for pointer equivalence.  This is *not* the actual
486
     points-to sets for nodes.  */
487
  bitmap *points_to;
488
 
489
  /* Bitmap of nodes where the bit is set if the node is a direct
490
     node.  Used for variable substitution.  */
491
  sbitmap direct_nodes;
492
 
493
  /* Bitmap of nodes where the bit is set if the node is address
494
     taken.  Used for variable substitution.  */
495
  bitmap address_taken;
496
 
497
  /* Vector of complex constraints for each graph node.  Complex
498
     constraints are those involving dereferences or offsets that are
499
     not 0.  */
500
  VEC(constraint_t,heap) **complex;
501
};
502
 
503
static constraint_graph_t graph;
504
 
505
/* During variable substitution and the offline version of indirect
506
   cycle finding, we create nodes to represent dereferences and
507
   address taken constraints.  These represent where these start and
508
   end.  */
509
#define FIRST_REF_NODE (VEC_length (varinfo_t, varmap))
510
#define LAST_REF_NODE (FIRST_REF_NODE + (FIRST_REF_NODE - 1))
511
 
512
/* Return the representative node for NODE, if NODE has been unioned
513
   with another NODE.
514
   This function performs path compression along the way to finding
515
   the representative.  */
516
 
517
static unsigned int
518
find (unsigned int node)
519
{
520
  gcc_assert (node < graph->size);
521
  if (graph->rep[node] != node)
522
    return graph->rep[node] = find (graph->rep[node]);
523
  return node;
524
}
525
 
526
/* Union the TO and FROM nodes to the TO nodes.
527
   Note that at some point in the future, we may want to do
528
   union-by-rank, in which case we are going to have to return the
529
   node we unified to.  */
530
 
531
static bool
532
unite (unsigned int to, unsigned int from)
533
{
534
  gcc_assert (to < graph->size && from < graph->size);
535
  if (to != from && graph->rep[from] != to)
536
    {
537
      graph->rep[from] = to;
538
      return true;
539
    }
540
  return false;
541
}
542
 
543
/* Create a new constraint consisting of LHS and RHS expressions.  */
544
 
545
static constraint_t
546
new_constraint (const struct constraint_expr lhs,
547
                const struct constraint_expr rhs)
548
{
549
  constraint_t ret = (constraint_t) pool_alloc (constraint_pool);
550
  ret->lhs = lhs;
551
  ret->rhs = rhs;
552
  return ret;
553
}
554
 
555
/* Print out constraint C to FILE.  */
556
 
557
static void
558
dump_constraint (FILE *file, constraint_t c)
559
{
560
  if (c->lhs.type == ADDRESSOF)
561
    fprintf (file, "&");
562
  else if (c->lhs.type == DEREF)
563
    fprintf (file, "*");
564
  fprintf (file, "%s", get_varinfo (c->lhs.var)->name);
565
  if (c->lhs.offset == UNKNOWN_OFFSET)
566
    fprintf (file, " + UNKNOWN");
567
  else if (c->lhs.offset != 0)
568
    fprintf (file, " + " HOST_WIDE_INT_PRINT_DEC, c->lhs.offset);
569
  fprintf (file, " = ");
570
  if (c->rhs.type == ADDRESSOF)
571
    fprintf (file, "&");
572
  else if (c->rhs.type == DEREF)
573
    fprintf (file, "*");
574
  fprintf (file, "%s", get_varinfo (c->rhs.var)->name);
575
  if (c->rhs.offset == UNKNOWN_OFFSET)
576
    fprintf (file, " + UNKNOWN");
577
  else if (c->rhs.offset != 0)
578
    fprintf (file, " + " HOST_WIDE_INT_PRINT_DEC, c->rhs.offset);
579
  fprintf (file, "\n");
580
}
581
 
582
 
583
void debug_constraint (constraint_t);
584
void debug_constraints (void);
585
void debug_constraint_graph (void);
586
void debug_solution_for_var (unsigned int);
587
void debug_sa_points_to_info (void);
588
 
589
/* Print out constraint C to stderr.  */
590
 
591
void
592
debug_constraint (constraint_t c)
593
{
594
  dump_constraint (stderr, c);
595
}
596
 
597
/* Print out all constraints to FILE */
598
 
599
static void
600
dump_constraints (FILE *file)
601
{
602
  int i;
603
  constraint_t c;
604
  for (i = 0; VEC_iterate (constraint_t, constraints, i, c); i++)
605
    dump_constraint (file, c);
606
}
607
 
608
/* Print out all constraints to stderr.  */
609
 
610
void
611
debug_constraints (void)
612
{
613
  dump_constraints (stderr);
614
}
615
 
616
/* Print out to FILE the edge in the constraint graph that is created by
617
   constraint c. The edge may have a label, depending on the type of
618
   constraint that it represents. If complex1, e.g: a = *b, then the label
619
   is "=*", if complex2, e.g: *a = b, then the label is "*=", if
620
   complex with an offset, e.g: a = b + 8, then the label is "+".
621
   Otherwise the edge has no label.  */
622
 
623
static void
624
dump_constraint_edge (FILE *file, constraint_t c)
625
{
626
  if (c->rhs.type != ADDRESSOF)
627
    {
628
      const char *src = get_varinfo (c->rhs.var)->name;
629
      const char *dst = get_varinfo (c->lhs.var)->name;
630
      fprintf (file, "  \"%s\" -> \"%s\" ", src, dst);
631
      /* Due to preprocessing of constraints, instructions like *a = *b are
632
         illegal; thus, we do not have to handle such cases.  */
633
      if (c->lhs.type == DEREF)
634
        fprintf (file, " [ label=\"*=\" ] ;\n");
635
      else if (c->rhs.type == DEREF)
636
        fprintf (file, " [ label=\"=*\" ] ;\n");
637
      else
638
        {
639
          /* We must check the case where the constraint is an offset.
640
             In this case, it is treated as a complex constraint.  */
641
          if (c->rhs.offset != c->lhs.offset)
642
            fprintf (file, " [ label=\"+\" ] ;\n");
643
          else
644
            fprintf (file, " ;\n");
645
        }
646
    }
647
}
648
 
649
/* Print the constraint graph in dot format.  */
650
 
651
static void
652
dump_constraint_graph (FILE *file)
653
{
654
  unsigned int i=0, size;
655
  constraint_t c;
656
 
657
  /* Only print the graph if it has already been initialized:  */
658
  if (!graph)
659
    return;
660
 
661
  /* Print the constraints used to produce the constraint graph. The
662
     constraints will be printed as comments in the dot file:  */
663
  fprintf (file, "\n\n/* Constraints used in the constraint graph:\n");
664
  dump_constraints (file);
665
  fprintf (file, "*/\n");
666
 
667
  /* Prints the header of the dot file:  */
668
  fprintf (file, "\n\n// The constraint graph in dot format:\n");
669
  fprintf (file, "strict digraph {\n");
670
  fprintf (file, "  node [\n    shape = box\n  ]\n");
671
  fprintf (file, "  edge [\n    fontsize = \"12\"\n  ]\n");
672
  fprintf (file, "\n  // List of nodes in the constraint graph:\n");
673
 
674
  /* The next lines print the nodes in the graph. In order to get the
675
     number of nodes in the graph, we must choose the minimum between the
676
     vector VEC (varinfo_t, varmap) and graph->size. If the graph has not
677
     yet been initialized, then graph->size == 0, otherwise we must only
678
     read nodes that have an entry in VEC (varinfo_t, varmap).  */
679
  size = VEC_length (varinfo_t, varmap);
680
  size = size < graph->size ? size : graph->size;
681
  for (i = 0; i < size; i++)
682
    {
683
      const char *name = get_varinfo (graph->rep[i])->name;
684
      fprintf (file, "  \"%s\" ;\n", name);
685
    }
686
 
687
  /* Go over the list of constraints printing the edges in the constraint
688
     graph.  */
689
  fprintf (file, "\n  // The constraint edges:\n");
690
  for (i = 0; VEC_iterate (constraint_t, constraints, i, c); i++)
691
    if (c)
692
      dump_constraint_edge (file, c);
693
 
694
  /* Prints the tail of the dot file. By now, only the closing bracket.  */
695
  fprintf (file, "}\n\n\n");
696
}
697
 
698
/* Print out the constraint graph to stderr.  */
699
 
700
void
701
debug_constraint_graph (void)
702
{
703
  dump_constraint_graph (stderr);
704
}
705
 
706
/* SOLVER FUNCTIONS
707
 
708
   The solver is a simple worklist solver, that works on the following
709
   algorithm:
710
 
711
   sbitmap changed_nodes = all zeroes;
712
   changed_count = 0;
713
   For each node that is not already collapsed:
714
       changed_count++;
715
       set bit in changed nodes
716
 
717
   while (changed_count > 0)
718
   {
719
     compute topological ordering for constraint graph
720
 
721
     find and collapse cycles in the constraint graph (updating
722
     changed if necessary)
723
 
724
     for each node (n) in the graph in topological order:
725
       changed_count--;
726
 
727
       Process each complex constraint associated with the node,
728
       updating changed if necessary.
729
 
730
       For each outgoing edge from n, propagate the solution from n to
731
       the destination of the edge, updating changed as necessary.
732
 
733
   }  */
734
 
735
/* Return true if two constraint expressions A and B are equal.  */
736
 
737
static bool
738
constraint_expr_equal (struct constraint_expr a, struct constraint_expr b)
739
{
740
  return a.type == b.type && a.var == b.var && a.offset == b.offset;
741
}
742
 
743
/* Return true if constraint expression A is less than constraint expression
744
   B.  This is just arbitrary, but consistent, in order to give them an
745
   ordering.  */
746
 
747
static bool
748
constraint_expr_less (struct constraint_expr a, struct constraint_expr b)
749
{
750
  if (a.type == b.type)
751
    {
752
      if (a.var == b.var)
753
        return a.offset < b.offset;
754
      else
755
        return a.var < b.var;
756
    }
757
  else
758
    return a.type < b.type;
759
}
760
 
761
/* Return true if constraint A is less than constraint B.  This is just
762
   arbitrary, but consistent, in order to give them an ordering.  */
763
 
764
static bool
765
constraint_less (const constraint_t a, const constraint_t b)
766
{
767
  if (constraint_expr_less (a->lhs, b->lhs))
768
    return true;
769
  else if (constraint_expr_less (b->lhs, a->lhs))
770
    return false;
771
  else
772
    return constraint_expr_less (a->rhs, b->rhs);
773
}
774
 
775
/* Return true if two constraints A and B are equal.  */
776
 
777
static bool
778
constraint_equal (struct constraint a, struct constraint b)
779
{
780
  return constraint_expr_equal (a.lhs, b.lhs)
781
    && constraint_expr_equal (a.rhs, b.rhs);
782
}
783
 
784
 
785
/* Find a constraint LOOKFOR in the sorted constraint vector VEC */
786
 
787
static constraint_t
788
constraint_vec_find (VEC(constraint_t,heap) *vec,
789
                     struct constraint lookfor)
790
{
791
  unsigned int place;
792
  constraint_t found;
793
 
794
  if (vec == NULL)
795
    return NULL;
796
 
797
  place = VEC_lower_bound (constraint_t, vec, &lookfor, constraint_less);
798
  if (place >= VEC_length (constraint_t, vec))
799
    return NULL;
800
  found = VEC_index (constraint_t, vec, place);
801
  if (!constraint_equal (*found, lookfor))
802
    return NULL;
803
  return found;
804
}
805
 
806
/* Union two constraint vectors, TO and FROM.  Put the result in TO.  */
807
 
808
static void
809
constraint_set_union (VEC(constraint_t,heap) **to,
810
                      VEC(constraint_t,heap) **from)
811
{
812
  int i;
813
  constraint_t c;
814
 
815
  for (i = 0; VEC_iterate (constraint_t, *from, i, c); i++)
816
    {
817
      if (constraint_vec_find (*to, *c) == NULL)
818
        {
819
          unsigned int place = VEC_lower_bound (constraint_t, *to, c,
820
                                                constraint_less);
821
          VEC_safe_insert (constraint_t, heap, *to, place, c);
822
        }
823
    }
824
}
825
 
826
/* Expands the solution in SET to all sub-fields of variables included.
827
   Union the expanded result into RESULT.  */
828
 
829
static void
830
solution_set_expand (bitmap result, bitmap set)
831
{
832
  bitmap_iterator bi;
833
  bitmap vars = NULL;
834
  unsigned j;
835
 
836
  /* In a first pass record all variables we need to add all
837
     sub-fields off.  This avoids quadratic behavior.  */
838
  EXECUTE_IF_SET_IN_BITMAP (set, 0, j, bi)
839
    {
840
      varinfo_t v = get_varinfo (j);
841
      if (v->is_artificial_var
842
          || v->is_full_var)
843
        continue;
844
      v = lookup_vi_for_tree (v->decl);
845
      if (vars == NULL)
846
        vars = BITMAP_ALLOC (NULL);
847
      bitmap_set_bit (vars, v->id);
848
    }
849
 
850
  /* In the second pass now do the addition to the solution and
851
     to speed up solving add it to the delta as well.  */
852
  if (vars != NULL)
853
    {
854
      EXECUTE_IF_SET_IN_BITMAP (vars, 0, j, bi)
855
        {
856
          varinfo_t v = get_varinfo (j);
857
          for (; v != NULL; v = v->next)
858
            bitmap_set_bit (result, v->id);
859
        }
860
      BITMAP_FREE (vars);
861
    }
862
}
863
 
864
/* Take a solution set SET, add OFFSET to each member of the set, and
865
   overwrite SET with the result when done.  */
866
 
867
static void
868
solution_set_add (bitmap set, HOST_WIDE_INT offset)
869
{
870
  bitmap result = BITMAP_ALLOC (&iteration_obstack);
871
  unsigned int i;
872
  bitmap_iterator bi;
873
 
874
  /* If the offset is unknown we have to expand the solution to
875
     all subfields.  */
876
  if (offset == UNKNOWN_OFFSET)
877
    {
878
      solution_set_expand (set, set);
879
      return;
880
    }
881
 
882
  EXECUTE_IF_SET_IN_BITMAP (set, 0, i, bi)
883
    {
884
      varinfo_t vi = get_varinfo (i);
885
 
886
      /* If this is a variable with just one field just set its bit
887
         in the result.  */
888
      if (vi->is_artificial_var
889
          || vi->is_unknown_size_var
890
          || vi->is_full_var)
891
        bitmap_set_bit (result, i);
892
      else
893
        {
894
          unsigned HOST_WIDE_INT fieldoffset = vi->offset + offset;
895
 
896
          /* If the offset makes the pointer point to before the
897
             variable use offset zero for the field lookup.  */
898
          if (offset < 0
899
              && fieldoffset > vi->offset)
900
            fieldoffset = 0;
901
 
902
          if (offset != 0)
903
            vi = first_or_preceding_vi_for_offset (vi, fieldoffset);
904
 
905
          bitmap_set_bit (result, vi->id);
906
          /* If the result is not exactly at fieldoffset include the next
907
             field as well.  See get_constraint_for_ptr_offset for more
908
             rationale.  */
909
          if (vi->offset != fieldoffset
910
              && vi->next != NULL)
911
            bitmap_set_bit (result, vi->next->id);
912
        }
913
    }
914
 
915
  bitmap_copy (set, result);
916
  BITMAP_FREE (result);
917
}
918
 
919
/* Union solution sets TO and FROM, and add INC to each member of FROM in the
920
   process.  */
921
 
922
static bool
923
set_union_with_increment  (bitmap to, bitmap from, HOST_WIDE_INT inc)
924
{
925
  if (inc == 0)
926
    return bitmap_ior_into (to, from);
927
  else
928
    {
929
      bitmap tmp;
930
      bool res;
931
 
932
      tmp = BITMAP_ALLOC (&iteration_obstack);
933
      bitmap_copy (tmp, from);
934
      solution_set_add (tmp, inc);
935
      res = bitmap_ior_into (to, tmp);
936
      BITMAP_FREE (tmp);
937
      return res;
938
    }
939
}
940
 
941
/* Insert constraint C into the list of complex constraints for graph
942
   node VAR.  */
943
 
944
static void
945
insert_into_complex (constraint_graph_t graph,
946
                     unsigned int var, constraint_t c)
947
{
948
  VEC (constraint_t, heap) *complex = graph->complex[var];
949
  unsigned int place = VEC_lower_bound (constraint_t, complex, c,
950
                                        constraint_less);
951
 
952
  /* Only insert constraints that do not already exist.  */
953
  if (place >= VEC_length (constraint_t, complex)
954
      || !constraint_equal (*c, *VEC_index (constraint_t, complex, place)))
955
    VEC_safe_insert (constraint_t, heap, graph->complex[var], place, c);
956
}
957
 
958
 
959
/* Condense two variable nodes into a single variable node, by moving
960
   all associated info from SRC to TO.  */
961
 
962
static void
963
merge_node_constraints (constraint_graph_t graph, unsigned int to,
964
                        unsigned int from)
965
{
966
  unsigned int i;
967
  constraint_t c;
968
 
969
  gcc_assert (find (from) == to);
970
 
971
  /* Move all complex constraints from src node into to node  */
972
  for (i = 0; VEC_iterate (constraint_t, graph->complex[from], i, c); i++)
973
    {
974
      /* In complex constraints for node src, we may have either
975
         a = *src, and *src = a, or an offseted constraint which are
976
         always added to the rhs node's constraints.  */
977
 
978
      if (c->rhs.type == DEREF)
979
        c->rhs.var = to;
980
      else if (c->lhs.type == DEREF)
981
        c->lhs.var = to;
982
      else
983
        c->rhs.var = to;
984
    }
985
  constraint_set_union (&graph->complex[to], &graph->complex[from]);
986
  VEC_free (constraint_t, heap, graph->complex[from]);
987
  graph->complex[from] = NULL;
988
}
989
 
990
 
991
/* Remove edges involving NODE from GRAPH.  */
992
 
993
static void
994
clear_edges_for_node (constraint_graph_t graph, unsigned int node)
995
{
996
  if (graph->succs[node])
997
    BITMAP_FREE (graph->succs[node]);
998
}
999
 
1000
/* Merge GRAPH nodes FROM and TO into node TO.  */
1001
 
1002
static void
1003
merge_graph_nodes (constraint_graph_t graph, unsigned int to,
1004
                   unsigned int from)
1005
{
1006
  if (graph->indirect_cycles[from] != -1)
1007
    {
1008
      /* If we have indirect cycles with the from node, and we have
1009
         none on the to node, the to node has indirect cycles from the
1010
         from node now that they are unified.
1011
         If indirect cycles exist on both, unify the nodes that they
1012
         are in a cycle with, since we know they are in a cycle with
1013
         each other.  */
1014
      if (graph->indirect_cycles[to] == -1)
1015
        graph->indirect_cycles[to] = graph->indirect_cycles[from];
1016
    }
1017
 
1018
  /* Merge all the successor edges.  */
1019
  if (graph->succs[from])
1020
    {
1021
      if (!graph->succs[to])
1022
        graph->succs[to] = BITMAP_ALLOC (&pta_obstack);
1023
      bitmap_ior_into (graph->succs[to],
1024
                       graph->succs[from]);
1025
    }
1026
 
1027
  clear_edges_for_node (graph, from);
1028
}
1029
 
1030
 
1031
/* Add an indirect graph edge to GRAPH, going from TO to FROM if
1032
   it doesn't exist in the graph already.  */
1033
 
1034
static void
1035
add_implicit_graph_edge (constraint_graph_t graph, unsigned int to,
1036
                         unsigned int from)
1037
{
1038
  if (to == from)
1039
    return;
1040
 
1041
  if (!graph->implicit_preds[to])
1042
    graph->implicit_preds[to] = BITMAP_ALLOC (&predbitmap_obstack);
1043
 
1044
  if (bitmap_set_bit (graph->implicit_preds[to], from))
1045
    stats.num_implicit_edges++;
1046
}
1047
 
1048
/* Add a predecessor graph edge to GRAPH, going from TO to FROM if
1049
   it doesn't exist in the graph already.
1050
   Return false if the edge already existed, true otherwise.  */
1051
 
1052
static void
1053
add_pred_graph_edge (constraint_graph_t graph, unsigned int to,
1054
                     unsigned int from)
1055
{
1056
  if (!graph->preds[to])
1057
    graph->preds[to] = BITMAP_ALLOC (&predbitmap_obstack);
1058
  bitmap_set_bit (graph->preds[to], from);
1059
}
1060
 
1061
/* Add a graph edge to GRAPH, going from FROM to TO if
1062
   it doesn't exist in the graph already.
1063
   Return false if the edge already existed, true otherwise.  */
1064
 
1065
static bool
1066
add_graph_edge (constraint_graph_t graph, unsigned int to,
1067
                unsigned int from)
1068
{
1069
  if (to == from)
1070
    {
1071
      return false;
1072
    }
1073
  else
1074
    {
1075
      bool r = false;
1076
 
1077
      if (!graph->succs[from])
1078
        graph->succs[from] = BITMAP_ALLOC (&pta_obstack);
1079
      if (bitmap_set_bit (graph->succs[from], to))
1080
        {
1081
          r = true;
1082
          if (to < FIRST_REF_NODE && from < FIRST_REF_NODE)
1083
            stats.num_edges++;
1084
        }
1085
      return r;
1086
    }
1087
}
1088
 
1089
 
1090
/* Return true if {DEST.SRC} is an existing graph edge in GRAPH.  */
1091
 
1092
static bool
1093
valid_graph_edge (constraint_graph_t graph, unsigned int src,
1094
                  unsigned int dest)
1095
{
1096
  return (graph->succs[dest]
1097
          && bitmap_bit_p (graph->succs[dest], src));
1098
}
1099
 
1100
/* Initialize the constraint graph structure to contain SIZE nodes.  */
1101
 
1102
static void
1103
init_graph (unsigned int size)
1104
{
1105
  unsigned int j;
1106
 
1107
  graph = XCNEW (struct constraint_graph);
1108
  graph->size = size;
1109
  graph->succs = XCNEWVEC (bitmap, graph->size);
1110
  graph->indirect_cycles = XNEWVEC (int, graph->size);
1111
  graph->rep = XNEWVEC (unsigned int, graph->size);
1112
  graph->complex = XCNEWVEC (VEC(constraint_t, heap) *, size);
1113
  graph->pe = XCNEWVEC (unsigned int, graph->size);
1114
  graph->pe_rep = XNEWVEC (int, graph->size);
1115
 
1116
  for (j = 0; j < graph->size; j++)
1117
    {
1118
      graph->rep[j] = j;
1119
      graph->pe_rep[j] = -1;
1120
      graph->indirect_cycles[j] = -1;
1121
    }
1122
}
1123
 
1124
/* Build the constraint graph, adding only predecessor edges right now.  */
1125
 
1126
static void
1127
build_pred_graph (void)
1128
{
1129
  int i;
1130
  constraint_t c;
1131
  unsigned int j;
1132
 
1133
  graph->implicit_preds = XCNEWVEC (bitmap, graph->size);
1134
  graph->preds = XCNEWVEC (bitmap, graph->size);
1135
  graph->pointer_label = XCNEWVEC (unsigned int, graph->size);
1136
  graph->loc_label = XCNEWVEC (unsigned int, graph->size);
1137
  graph->pointed_by = XCNEWVEC (bitmap, graph->size);
1138
  graph->points_to = XCNEWVEC (bitmap, graph->size);
1139
  graph->eq_rep = XNEWVEC (int, graph->size);
1140
  graph->direct_nodes = sbitmap_alloc (graph->size);
1141
  graph->address_taken = BITMAP_ALLOC (&predbitmap_obstack);
1142
  sbitmap_zero (graph->direct_nodes);
1143
 
1144
  for (j = 0; j < FIRST_REF_NODE; j++)
1145
    {
1146
      if (!get_varinfo (j)->is_special_var)
1147
        SET_BIT (graph->direct_nodes, j);
1148
    }
1149
 
1150
  for (j = 0; j < graph->size; j++)
1151
    graph->eq_rep[j] = -1;
1152
 
1153
  for (j = 0; j < VEC_length (varinfo_t, varmap); j++)
1154
    graph->indirect_cycles[j] = -1;
1155
 
1156
  for (i = 0; VEC_iterate (constraint_t, constraints, i, c); i++)
1157
    {
1158
      struct constraint_expr lhs = c->lhs;
1159
      struct constraint_expr rhs = c->rhs;
1160
      unsigned int lhsvar = lhs.var;
1161
      unsigned int rhsvar = rhs.var;
1162
 
1163
      if (lhs.type == DEREF)
1164
        {
1165
          /* *x = y.  */
1166
          if (rhs.offset == 0 && lhs.offset == 0 && rhs.type == SCALAR)
1167
            add_pred_graph_edge (graph, FIRST_REF_NODE + lhsvar, rhsvar);
1168
        }
1169
      else if (rhs.type == DEREF)
1170
        {
1171
          /* x = *y */
1172
          if (rhs.offset == 0 && lhs.offset == 0 && lhs.type == SCALAR)
1173
            add_pred_graph_edge (graph, lhsvar, FIRST_REF_NODE + rhsvar);
1174
          else
1175
            RESET_BIT (graph->direct_nodes, lhsvar);
1176
        }
1177
      else if (rhs.type == ADDRESSOF)
1178
        {
1179
          varinfo_t v;
1180
 
1181
          /* x = &y */
1182
          if (graph->points_to[lhsvar] == NULL)
1183
            graph->points_to[lhsvar] = BITMAP_ALLOC (&predbitmap_obstack);
1184
          bitmap_set_bit (graph->points_to[lhsvar], rhsvar);
1185
 
1186
          if (graph->pointed_by[rhsvar] == NULL)
1187
            graph->pointed_by[rhsvar] = BITMAP_ALLOC (&predbitmap_obstack);
1188
          bitmap_set_bit (graph->pointed_by[rhsvar], lhsvar);
1189
 
1190
          /* Implicitly, *x = y */
1191
          add_implicit_graph_edge (graph, FIRST_REF_NODE + lhsvar, rhsvar);
1192
 
1193
          /* All related variables are no longer direct nodes.  */
1194
          RESET_BIT (graph->direct_nodes, rhsvar);
1195
          v = get_varinfo (rhsvar);
1196
          if (!v->is_full_var)
1197
            {
1198
              v = lookup_vi_for_tree (v->decl);
1199
              do
1200
                {
1201
                  RESET_BIT (graph->direct_nodes, v->id);
1202
                  v = v->next;
1203
                }
1204
              while (v != NULL);
1205
            }
1206
          bitmap_set_bit (graph->address_taken, rhsvar);
1207
        }
1208
      else if (lhsvar > anything_id
1209
               && lhsvar != rhsvar && lhs.offset == 0 && rhs.offset == 0)
1210
        {
1211
          /* x = y */
1212
          add_pred_graph_edge (graph, lhsvar, rhsvar);
1213
          /* Implicitly, *x = *y */
1214
          add_implicit_graph_edge (graph, FIRST_REF_NODE + lhsvar,
1215
                                   FIRST_REF_NODE + rhsvar);
1216
        }
1217
      else if (lhs.offset != 0 || rhs.offset != 0)
1218
        {
1219
          if (rhs.offset != 0)
1220
            RESET_BIT (graph->direct_nodes, lhs.var);
1221
          else if (lhs.offset != 0)
1222
            RESET_BIT (graph->direct_nodes, rhs.var);
1223
        }
1224
    }
1225
}
1226
 
1227
/* Build the constraint graph, adding successor edges.  */
1228
 
1229
static void
1230
build_succ_graph (void)
1231
{
1232
  unsigned i, t;
1233
  constraint_t c;
1234
 
1235
  for (i = 0; VEC_iterate (constraint_t, constraints, i, c); i++)
1236
    {
1237
      struct constraint_expr lhs;
1238
      struct constraint_expr rhs;
1239
      unsigned int lhsvar;
1240
      unsigned int rhsvar;
1241
 
1242
      if (!c)
1243
        continue;
1244
 
1245
      lhs = c->lhs;
1246
      rhs = c->rhs;
1247
      lhsvar = find (lhs.var);
1248
      rhsvar = find (rhs.var);
1249
 
1250
      if (lhs.type == DEREF)
1251
        {
1252
          if (rhs.offset == 0 && lhs.offset == 0 && rhs.type == SCALAR)
1253
            add_graph_edge (graph, FIRST_REF_NODE + lhsvar, rhsvar);
1254
        }
1255
      else if (rhs.type == DEREF)
1256
        {
1257
          if (rhs.offset == 0 && lhs.offset == 0 && lhs.type == SCALAR)
1258
            add_graph_edge (graph, lhsvar, FIRST_REF_NODE + rhsvar);
1259
        }
1260
      else if (rhs.type == ADDRESSOF)
1261
        {
1262
          /* x = &y */
1263
          gcc_assert (find (rhs.var) == rhs.var);
1264
          bitmap_set_bit (get_varinfo (lhsvar)->solution, rhsvar);
1265
        }
1266
      else if (lhsvar > anything_id
1267
               && lhsvar != rhsvar && lhs.offset == 0 && rhs.offset == 0)
1268
        {
1269
          add_graph_edge (graph, lhsvar, rhsvar);
1270
        }
1271
    }
1272
 
1273
  /* Add edges from STOREDANYTHING to all non-direct nodes that can
1274
     receive pointers.  */
1275
  t = find (storedanything_id);
1276
  for (i = integer_id + 1; i < FIRST_REF_NODE; ++i)
1277
    {
1278
      if (!TEST_BIT (graph->direct_nodes, i)
1279
          && get_varinfo (i)->may_have_pointers)
1280
        add_graph_edge (graph, find (i), t);
1281
    }
1282
 
1283
  /* Everything stored to ANYTHING also potentially escapes.  */
1284
  add_graph_edge (graph, find (escaped_id), t);
1285
}
1286
 
1287
 
1288
/* Changed variables on the last iteration.  */
1289
static unsigned int changed_count;
1290
static sbitmap changed;
1291
 
1292
/* Strongly Connected Component visitation info.  */
1293
 
1294
struct scc_info
1295
{
1296
  sbitmap visited;
1297
  sbitmap deleted;
1298
  unsigned int *dfs;
1299
  unsigned int *node_mapping;
1300
  int current_index;
1301
  VEC(unsigned,heap) *scc_stack;
1302
};
1303
 
1304
 
1305
/* Recursive routine to find strongly connected components in GRAPH.
1306
   SI is the SCC info to store the information in, and N is the id of current
1307
   graph node we are processing.
1308
 
1309
   This is Tarjan's strongly connected component finding algorithm, as
1310
   modified by Nuutila to keep only non-root nodes on the stack.
1311
   The algorithm can be found in "On finding the strongly connected
1312
   connected components in a directed graph" by Esko Nuutila and Eljas
1313
   Soisalon-Soininen, in Information Processing Letters volume 49,
1314
   number 1, pages 9-14.  */
1315
 
1316
static void
1317
scc_visit (constraint_graph_t graph, struct scc_info *si, unsigned int n)
1318
{
1319
  unsigned int i;
1320
  bitmap_iterator bi;
1321
  unsigned int my_dfs;
1322
 
1323
  SET_BIT (si->visited, n);
1324
  si->dfs[n] = si->current_index ++;
1325
  my_dfs = si->dfs[n];
1326
 
1327
  /* Visit all the successors.  */
1328
  EXECUTE_IF_IN_NONNULL_BITMAP (graph->succs[n], 0, i, bi)
1329
    {
1330
      unsigned int w;
1331
 
1332
      if (i > LAST_REF_NODE)
1333
        break;
1334
 
1335
      w = find (i);
1336
      if (TEST_BIT (si->deleted, w))
1337
        continue;
1338
 
1339
      if (!TEST_BIT (si->visited, w))
1340
        scc_visit (graph, si, w);
1341
      {
1342
        unsigned int t = find (w);
1343
        unsigned int nnode = find (n);
1344
        gcc_assert (nnode == n);
1345
 
1346
        if (si->dfs[t] < si->dfs[nnode])
1347
          si->dfs[n] = si->dfs[t];
1348
      }
1349
    }
1350
 
1351
  /* See if any components have been identified.  */
1352
  if (si->dfs[n] == my_dfs)
1353
    {
1354
      if (VEC_length (unsigned, si->scc_stack) > 0
1355
          && si->dfs[VEC_last (unsigned, si->scc_stack)] >= my_dfs)
1356
        {
1357
          bitmap scc = BITMAP_ALLOC (NULL);
1358
          unsigned int lowest_node;
1359
          bitmap_iterator bi;
1360
 
1361
          bitmap_set_bit (scc, n);
1362
 
1363
          while (VEC_length (unsigned, si->scc_stack) != 0
1364
                 && si->dfs[VEC_last (unsigned, si->scc_stack)] >= my_dfs)
1365
            {
1366
              unsigned int w = VEC_pop (unsigned, si->scc_stack);
1367
 
1368
              bitmap_set_bit (scc, w);
1369
            }
1370
 
1371
          lowest_node = bitmap_first_set_bit (scc);
1372
          gcc_assert (lowest_node < FIRST_REF_NODE);
1373
 
1374
          /* Collapse the SCC nodes into a single node, and mark the
1375
             indirect cycles.  */
1376
          EXECUTE_IF_SET_IN_BITMAP (scc, 0, i, bi)
1377
            {
1378
              if (i < FIRST_REF_NODE)
1379
                {
1380
                  if (unite (lowest_node, i))
1381
                    unify_nodes (graph, lowest_node, i, false);
1382
                }
1383
              else
1384
                {
1385
                  unite (lowest_node, i);
1386
                  graph->indirect_cycles[i - FIRST_REF_NODE] = lowest_node;
1387
                }
1388
            }
1389
        }
1390
      SET_BIT (si->deleted, n);
1391
    }
1392
  else
1393
    VEC_safe_push (unsigned, heap, si->scc_stack, n);
1394
}
1395
 
1396
/* Unify node FROM into node TO, updating the changed count if
1397
   necessary when UPDATE_CHANGED is true.  */
1398
 
1399
static void
1400
unify_nodes (constraint_graph_t graph, unsigned int to, unsigned int from,
1401
             bool update_changed)
1402
{
1403
 
1404
  gcc_assert (to != from && find (to) == to);
1405
  if (dump_file && (dump_flags & TDF_DETAILS))
1406
    fprintf (dump_file, "Unifying %s to %s\n",
1407
             get_varinfo (from)->name,
1408
             get_varinfo (to)->name);
1409
 
1410
  if (update_changed)
1411
    stats.unified_vars_dynamic++;
1412
  else
1413
    stats.unified_vars_static++;
1414
 
1415
  merge_graph_nodes (graph, to, from);
1416
  merge_node_constraints (graph, to, from);
1417
 
1418
  /* Mark TO as changed if FROM was changed. If TO was already marked
1419
     as changed, decrease the changed count.  */
1420
 
1421
  if (update_changed && TEST_BIT (changed, from))
1422
    {
1423
      RESET_BIT (changed, from);
1424
      if (!TEST_BIT (changed, to))
1425
        SET_BIT (changed, to);
1426
      else
1427
        {
1428
          gcc_assert (changed_count > 0);
1429
          changed_count--;
1430
        }
1431
    }
1432
  if (get_varinfo (from)->solution)
1433
    {
1434
      /* If the solution changes because of the merging, we need to mark
1435
         the variable as changed.  */
1436
      if (bitmap_ior_into (get_varinfo (to)->solution,
1437
                           get_varinfo (from)->solution))
1438
        {
1439
          if (update_changed && !TEST_BIT (changed, to))
1440
            {
1441
              SET_BIT (changed, to);
1442
              changed_count++;
1443
            }
1444
        }
1445
 
1446
      BITMAP_FREE (get_varinfo (from)->solution);
1447
      BITMAP_FREE (get_varinfo (from)->oldsolution);
1448
 
1449
      if (stats.iterations > 0)
1450
        {
1451
          BITMAP_FREE (get_varinfo (to)->oldsolution);
1452
          get_varinfo (to)->oldsolution = BITMAP_ALLOC (&oldpta_obstack);
1453
        }
1454
    }
1455
  if (valid_graph_edge (graph, to, to))
1456
    {
1457
      if (graph->succs[to])
1458
        bitmap_clear_bit (graph->succs[to], to);
1459
    }
1460
}
1461
 
1462
/* Information needed to compute the topological ordering of a graph.  */
1463
 
1464
struct topo_info
1465
{
1466
  /* sbitmap of visited nodes.  */
1467
  sbitmap visited;
1468
  /* Array that stores the topological order of the graph, *in
1469
     reverse*.  */
1470
  VEC(unsigned,heap) *topo_order;
1471
};
1472
 
1473
 
1474
/* Initialize and return a topological info structure.  */
1475
 
1476
static struct topo_info *
1477
init_topo_info (void)
1478
{
1479
  size_t size = graph->size;
1480
  struct topo_info *ti = XNEW (struct topo_info);
1481
  ti->visited = sbitmap_alloc (size);
1482
  sbitmap_zero (ti->visited);
1483
  ti->topo_order = VEC_alloc (unsigned, heap, 1);
1484
  return ti;
1485
}
1486
 
1487
 
1488
/* Free the topological sort info pointed to by TI.  */
1489
 
1490
static void
1491
free_topo_info (struct topo_info *ti)
1492
{
1493
  sbitmap_free (ti->visited);
1494
  VEC_free (unsigned, heap, ti->topo_order);
1495
  free (ti);
1496
}
1497
 
1498
/* Visit the graph in topological order, and store the order in the
1499
   topo_info structure.  */
1500
 
1501
static void
1502
topo_visit (constraint_graph_t graph, struct topo_info *ti,
1503
            unsigned int n)
1504
{
1505
  bitmap_iterator bi;
1506
  unsigned int j;
1507
 
1508
  SET_BIT (ti->visited, n);
1509
 
1510
  if (graph->succs[n])
1511
    EXECUTE_IF_SET_IN_BITMAP (graph->succs[n], 0, j, bi)
1512
      {
1513
        if (!TEST_BIT (ti->visited, j))
1514
          topo_visit (graph, ti, j);
1515
      }
1516
 
1517
  VEC_safe_push (unsigned, heap, ti->topo_order, n);
1518
}
1519
 
1520
/* Process a constraint C that represents x = *(y + off), using DELTA as the
1521
   starting solution for y.  */
1522
 
1523
static void
1524
do_sd_constraint (constraint_graph_t graph, constraint_t c,
1525
                  bitmap delta)
1526
{
1527
  unsigned int lhs = c->lhs.var;
1528
  bool flag = false;
1529
  bitmap sol = get_varinfo (lhs)->solution;
1530
  unsigned int j;
1531
  bitmap_iterator bi;
1532
  HOST_WIDE_INT roffset = c->rhs.offset;
1533
 
1534
  /* Our IL does not allow this.  */
1535
  gcc_assert (c->lhs.offset == 0);
1536
 
1537
  /* If the solution of Y contains anything it is good enough to transfer
1538
     this to the LHS.  */
1539
  if (bitmap_bit_p (delta, anything_id))
1540
    {
1541
      flag |= bitmap_set_bit (sol, anything_id);
1542
      goto done;
1543
    }
1544
 
1545
  /* If we do not know at with offset the rhs is dereferenced compute
1546
     the reachability set of DELTA, conservatively assuming it is
1547
     dereferenced at all valid offsets.  */
1548
  if (roffset == UNKNOWN_OFFSET)
1549
    {
1550
      solution_set_expand (delta, delta);
1551
      /* No further offset processing is necessary.  */
1552
      roffset = 0;
1553
    }
1554
 
1555
  /* For each variable j in delta (Sol(y)), add
1556
     an edge in the graph from j to x, and union Sol(j) into Sol(x).  */
1557
  EXECUTE_IF_SET_IN_BITMAP (delta, 0, j, bi)
1558
    {
1559
      varinfo_t v = get_varinfo (j);
1560
      HOST_WIDE_INT fieldoffset = v->offset + roffset;
1561
      unsigned int t;
1562
 
1563
      if (v->is_full_var)
1564
        fieldoffset = v->offset;
1565
      else if (roffset != 0)
1566
        v = first_vi_for_offset (v, fieldoffset);
1567
      /* If the access is outside of the variable we can ignore it.  */
1568
      if (!v)
1569
        continue;
1570
 
1571
      do
1572
        {
1573
          t = find (v->id);
1574
 
1575
          /* Adding edges from the special vars is pointless.
1576
             They don't have sets that can change.  */
1577
          if (get_varinfo (t)->is_special_var)
1578
            flag |= bitmap_ior_into (sol, get_varinfo (t)->solution);
1579
          /* Merging the solution from ESCAPED needlessly increases
1580
             the set.  Use ESCAPED as representative instead.  */
1581
          else if (v->id == escaped_id)
1582
            flag |= bitmap_set_bit (sol, escaped_id);
1583
          else if (add_graph_edge (graph, lhs, t))
1584
            flag |= bitmap_ior_into (sol, get_varinfo (t)->solution);
1585
 
1586
          /* If the variable is not exactly at the requested offset
1587
             we have to include the next one.  */
1588
          if (v->offset == (unsigned HOST_WIDE_INT)fieldoffset
1589
              || v->next == NULL)
1590
            break;
1591
 
1592
          v = v->next;
1593
          fieldoffset = v->offset;
1594
        }
1595
      while (1);
1596
    }
1597
 
1598
done:
1599
  /* If the LHS solution changed, mark the var as changed.  */
1600
  if (flag)
1601
    {
1602
      get_varinfo (lhs)->solution = sol;
1603
      if (!TEST_BIT (changed, lhs))
1604
        {
1605
          SET_BIT (changed, lhs);
1606
          changed_count++;
1607
        }
1608
    }
1609
}
1610
 
1611
/* Process a constraint C that represents *(x + off) = y using DELTA
1612
   as the starting solution for x.  */
1613
 
1614
static void
1615
do_ds_constraint (constraint_t c, bitmap delta)
1616
{
1617
  unsigned int rhs = c->rhs.var;
1618
  bitmap sol = get_varinfo (rhs)->solution;
1619
  unsigned int j;
1620
  bitmap_iterator bi;
1621
  HOST_WIDE_INT loff = c->lhs.offset;
1622
 
1623
  /* Our IL does not allow this.  */
1624
  gcc_assert (c->rhs.offset == 0);
1625
 
1626
  /* If the solution of y contains ANYTHING simply use the ANYTHING
1627
     solution.  This avoids needlessly increasing the points-to sets.  */
1628
  if (bitmap_bit_p (sol, anything_id))
1629
    sol = get_varinfo (find (anything_id))->solution;
1630
 
1631
  /* If the solution for x contains ANYTHING we have to merge the
1632
     solution of y into all pointer variables which we do via
1633
     STOREDANYTHING.  */
1634
  if (bitmap_bit_p (delta, anything_id))
1635
    {
1636
      unsigned t = find (storedanything_id);
1637
      if (add_graph_edge (graph, t, rhs))
1638
        {
1639
          if (bitmap_ior_into (get_varinfo (t)->solution, sol))
1640
            {
1641
              if (!TEST_BIT (changed, t))
1642
                {
1643
                  SET_BIT (changed, t);
1644
                  changed_count++;
1645
                }
1646
            }
1647
        }
1648
      return;
1649
    }
1650
 
1651
  /* If we do not know at with offset the rhs is dereferenced compute
1652
     the reachability set of DELTA, conservatively assuming it is
1653
     dereferenced at all valid offsets.  */
1654
  if (loff == UNKNOWN_OFFSET)
1655
    {
1656
      solution_set_expand (delta, delta);
1657
      loff = 0;
1658
    }
1659
 
1660
  /* For each member j of delta (Sol(x)), add an edge from y to j and
1661
     union Sol(y) into Sol(j) */
1662
  EXECUTE_IF_SET_IN_BITMAP (delta, 0, j, bi)
1663
    {
1664
      varinfo_t v = get_varinfo (j);
1665
      unsigned int t;
1666
      HOST_WIDE_INT fieldoffset = v->offset + loff;
1667
 
1668
      /* If v is a global variable then this is an escape point.  */
1669
      if (v->is_global_var)
1670
        {
1671
          t = find (escaped_id);
1672
          if (add_graph_edge (graph, t, rhs)
1673
              && bitmap_ior_into (get_varinfo (t)->solution, sol)
1674
              && !TEST_BIT (changed, t))
1675
            {
1676
              SET_BIT (changed, t);
1677
              changed_count++;
1678
            }
1679
        }
1680
 
1681
      if (v->is_special_var)
1682
        continue;
1683
 
1684
      if (v->is_full_var)
1685
        fieldoffset = v->offset;
1686
      else if (loff != 0)
1687
        v = first_vi_for_offset (v, fieldoffset);
1688
      /* If the access is outside of the variable we can ignore it.  */
1689
      if (!v)
1690
        continue;
1691
 
1692
      do
1693
        {
1694
          if (v->may_have_pointers)
1695
            {
1696
              t = find (v->id);
1697
              if (add_graph_edge (graph, t, rhs)
1698
                  && bitmap_ior_into (get_varinfo (t)->solution, sol)
1699
                  && !TEST_BIT (changed, t))
1700
                {
1701
                  SET_BIT (changed, t);
1702
                  changed_count++;
1703
                }
1704
            }
1705
 
1706
          /* If the variable is not exactly at the requested offset
1707
             we have to include the next one.  */
1708
          if (v->offset == (unsigned HOST_WIDE_INT)fieldoffset
1709
              || v->next == NULL)
1710
            break;
1711
 
1712
          v = v->next;
1713
          fieldoffset = v->offset;
1714
        }
1715
      while (1);
1716
    }
1717
}
1718
 
1719
/* Handle a non-simple (simple meaning requires no iteration),
1720
   constraint (IE *x = &y, x = *y, *x = y, and x = y with offsets involved).  */
1721
 
1722
static void
1723
do_complex_constraint (constraint_graph_t graph, constraint_t c, bitmap delta)
1724
{
1725
  if (c->lhs.type == DEREF)
1726
    {
1727
      if (c->rhs.type == ADDRESSOF)
1728
        {
1729
          gcc_unreachable();
1730
        }
1731
      else
1732
        {
1733
          /* *x = y */
1734
          do_ds_constraint (c, delta);
1735
        }
1736
    }
1737
  else if (c->rhs.type == DEREF)
1738
    {
1739
      /* x = *y */
1740
      if (!(get_varinfo (c->lhs.var)->is_special_var))
1741
        do_sd_constraint (graph, c, delta);
1742
    }
1743
  else
1744
    {
1745
      bitmap tmp;
1746
      bitmap solution;
1747
      bool flag = false;
1748
 
1749
      gcc_assert (c->rhs.type == SCALAR && c->lhs.type == SCALAR);
1750
      solution = get_varinfo (c->rhs.var)->solution;
1751
      tmp = get_varinfo (c->lhs.var)->solution;
1752
 
1753
      flag = set_union_with_increment (tmp, solution, c->rhs.offset);
1754
 
1755
      if (flag)
1756
        {
1757
          get_varinfo (c->lhs.var)->solution = tmp;
1758
          if (!TEST_BIT (changed, c->lhs.var))
1759
            {
1760
              SET_BIT (changed, c->lhs.var);
1761
              changed_count++;
1762
            }
1763
        }
1764
    }
1765
}
1766
 
1767
/* Initialize and return a new SCC info structure.  */
1768
 
1769
static struct scc_info *
1770
init_scc_info (size_t size)
1771
{
1772
  struct scc_info *si = XNEW (struct scc_info);
1773
  size_t i;
1774
 
1775
  si->current_index = 0;
1776
  si->visited = sbitmap_alloc (size);
1777
  sbitmap_zero (si->visited);
1778
  si->deleted = sbitmap_alloc (size);
1779
  sbitmap_zero (si->deleted);
1780
  si->node_mapping = XNEWVEC (unsigned int, size);
1781
  si->dfs = XCNEWVEC (unsigned int, size);
1782
 
1783
  for (i = 0; i < size; i++)
1784
    si->node_mapping[i] = i;
1785
 
1786
  si->scc_stack = VEC_alloc (unsigned, heap, 1);
1787
  return si;
1788
}
1789
 
1790
/* Free an SCC info structure pointed to by SI */
1791
 
1792
static void
1793
free_scc_info (struct scc_info *si)
1794
{
1795
  sbitmap_free (si->visited);
1796
  sbitmap_free (si->deleted);
1797
  free (si->node_mapping);
1798
  free (si->dfs);
1799
  VEC_free (unsigned, heap, si->scc_stack);
1800
  free (si);
1801
}
1802
 
1803
 
1804
/* Find indirect cycles in GRAPH that occur, using strongly connected
1805
   components, and note them in the indirect cycles map.
1806
 
1807
   This technique comes from Ben Hardekopf and Calvin Lin,
1808
   "It Pays to be Lazy: Fast and Accurate Pointer Analysis for Millions of
1809
   Lines of Code", submitted to PLDI 2007.  */
1810
 
1811
static void
1812
find_indirect_cycles (constraint_graph_t graph)
1813
{
1814
  unsigned int i;
1815
  unsigned int size = graph->size;
1816
  struct scc_info *si = init_scc_info (size);
1817
 
1818
  for (i = 0; i < MIN (LAST_REF_NODE, size); i ++ )
1819
    if (!TEST_BIT (si->visited, i) && find (i) == i)
1820
      scc_visit (graph, si, i);
1821
 
1822
  free_scc_info (si);
1823
}
1824
 
1825
/* Compute a topological ordering for GRAPH, and store the result in the
1826
   topo_info structure TI.  */
1827
 
1828
static void
1829
compute_topo_order (constraint_graph_t graph,
1830
                    struct topo_info *ti)
1831
{
1832
  unsigned int i;
1833
  unsigned int size = graph->size;
1834
 
1835
  for (i = 0; i != size; ++i)
1836
    if (!TEST_BIT (ti->visited, i) && find (i) == i)
1837
      topo_visit (graph, ti, i);
1838
}
1839
 
1840
/* Structure used to for hash value numbering of pointer equivalence
1841
   classes.  */
1842
 
1843
typedef struct equiv_class_label
1844
{
1845
  hashval_t hashcode;
1846
  unsigned int equivalence_class;
1847
  bitmap labels;
1848
} *equiv_class_label_t;
1849
typedef const struct equiv_class_label *const_equiv_class_label_t;
1850
 
1851
/* A hashtable for mapping a bitmap of labels->pointer equivalence
1852
   classes.  */
1853
static htab_t pointer_equiv_class_table;
1854
 
1855
/* A hashtable for mapping a bitmap of labels->location equivalence
1856
   classes.  */
1857
static htab_t location_equiv_class_table;
1858
 
1859
/* Hash function for a equiv_class_label_t */
1860
 
1861
static hashval_t
1862
equiv_class_label_hash (const void *p)
1863
{
1864
  const_equiv_class_label_t const ecl = (const_equiv_class_label_t) p;
1865
  return ecl->hashcode;
1866
}
1867
 
1868
/* Equality function for two equiv_class_label_t's.  */
1869
 
1870
static int
1871
equiv_class_label_eq (const void *p1, const void *p2)
1872
{
1873
  const_equiv_class_label_t const eql1 = (const_equiv_class_label_t) p1;
1874
  const_equiv_class_label_t const eql2 = (const_equiv_class_label_t) p2;
1875
  return (eql1->hashcode == eql2->hashcode
1876
          && bitmap_equal_p (eql1->labels, eql2->labels));
1877
}
1878
 
1879
/* Lookup a equivalence class in TABLE by the bitmap of LABELS it
1880
   contains.  */
1881
 
1882
static unsigned int
1883
equiv_class_lookup (htab_t table, bitmap labels)
1884
{
1885
  void **slot;
1886
  struct equiv_class_label ecl;
1887
 
1888
  ecl.labels = labels;
1889
  ecl.hashcode = bitmap_hash (labels);
1890
 
1891
  slot = htab_find_slot_with_hash (table, &ecl,
1892
                                   ecl.hashcode, NO_INSERT);
1893
  if (!slot)
1894
    return 0;
1895
  else
1896
    return ((equiv_class_label_t) *slot)->equivalence_class;
1897
}
1898
 
1899
 
1900
/* Add an equivalence class named EQUIVALENCE_CLASS with labels LABELS
1901
   to TABLE.  */
1902
 
1903
static void
1904
equiv_class_add (htab_t table, unsigned int equivalence_class,
1905
                 bitmap labels)
1906
{
1907
  void **slot;
1908
  equiv_class_label_t ecl = XNEW (struct equiv_class_label);
1909
 
1910
  ecl->labels = labels;
1911
  ecl->equivalence_class = equivalence_class;
1912
  ecl->hashcode = bitmap_hash (labels);
1913
 
1914
  slot = htab_find_slot_with_hash (table, ecl,
1915
                                   ecl->hashcode, INSERT);
1916
  gcc_assert (!*slot);
1917
  *slot = (void *) ecl;
1918
}
1919
 
1920
/* Perform offline variable substitution.
1921
 
1922
   This is a worst case quadratic time way of identifying variables
1923
   that must have equivalent points-to sets, including those caused by
1924
   static cycles, and single entry subgraphs, in the constraint graph.
1925
 
1926
   The technique is described in "Exploiting Pointer and Location
1927
   Equivalence to Optimize Pointer Analysis. In the 14th International
1928
   Static Analysis Symposium (SAS), August 2007."  It is known as the
1929
   "HU" algorithm, and is equivalent to value numbering the collapsed
1930
   constraint graph including evaluating unions.
1931
 
1932
   The general method of finding equivalence classes is as follows:
1933
   Add fake nodes (REF nodes) and edges for *a = b and a = *b constraints.
1934
   Initialize all non-REF nodes to be direct nodes.
1935
   For each constraint a = a U {b}, we set pts(a) = pts(a) u {fresh
1936
   variable}
1937
   For each constraint containing the dereference, we also do the same
1938
   thing.
1939
 
1940
   We then compute SCC's in the graph and unify nodes in the same SCC,
1941
   including pts sets.
1942
 
1943
   For each non-collapsed node x:
1944
    Visit all unvisited explicit incoming edges.
1945
    Ignoring all non-pointers, set pts(x) = Union of pts(a) for y
1946
    where y->x.
1947
    Lookup the equivalence class for pts(x).
1948
     If we found one, equivalence_class(x) = found class.
1949
     Otherwise, equivalence_class(x) = new class, and new_class is
1950
    added to the lookup table.
1951
 
1952
   All direct nodes with the same equivalence class can be replaced
1953
   with a single representative node.
1954
   All unlabeled nodes (label == 0) are not pointers and all edges
1955
   involving them can be eliminated.
1956
   We perform these optimizations during rewrite_constraints
1957
 
1958
   In addition to pointer equivalence class finding, we also perform
1959
   location equivalence class finding.  This is the set of variables
1960
   that always appear together in points-to sets.  We use this to
1961
   compress the size of the points-to sets.  */
1962
 
1963
/* Current maximum pointer equivalence class id.  */
1964
static int pointer_equiv_class;
1965
 
1966
/* Current maximum location equivalence class id.  */
1967
static int location_equiv_class;
1968
 
1969
/* Recursive routine to find strongly connected components in GRAPH,
1970
   and label it's nodes with DFS numbers.  */
1971
 
1972
static void
1973
condense_visit (constraint_graph_t graph, struct scc_info *si, unsigned int n)
1974
{
1975
  unsigned int i;
1976
  bitmap_iterator bi;
1977
  unsigned int my_dfs;
1978
 
1979
  gcc_assert (si->node_mapping[n] == n);
1980
  SET_BIT (si->visited, n);
1981
  si->dfs[n] = si->current_index ++;
1982
  my_dfs = si->dfs[n];
1983
 
1984
  /* Visit all the successors.  */
1985
  EXECUTE_IF_IN_NONNULL_BITMAP (graph->preds[n], 0, i, bi)
1986
    {
1987
      unsigned int w = si->node_mapping[i];
1988
 
1989
      if (TEST_BIT (si->deleted, w))
1990
        continue;
1991
 
1992
      if (!TEST_BIT (si->visited, w))
1993
        condense_visit (graph, si, w);
1994
      {
1995
        unsigned int t = si->node_mapping[w];
1996
        unsigned int nnode = si->node_mapping[n];
1997
        gcc_assert (nnode == n);
1998
 
1999
        if (si->dfs[t] < si->dfs[nnode])
2000
          si->dfs[n] = si->dfs[t];
2001
      }
2002
    }
2003
 
2004
  /* Visit all the implicit predecessors.  */
2005
  EXECUTE_IF_IN_NONNULL_BITMAP (graph->implicit_preds[n], 0, i, bi)
2006
    {
2007
      unsigned int w = si->node_mapping[i];
2008
 
2009
      if (TEST_BIT (si->deleted, w))
2010
        continue;
2011
 
2012
      if (!TEST_BIT (si->visited, w))
2013
        condense_visit (graph, si, w);
2014
      {
2015
        unsigned int t = si->node_mapping[w];
2016
        unsigned int nnode = si->node_mapping[n];
2017
        gcc_assert (nnode == n);
2018
 
2019
        if (si->dfs[t] < si->dfs[nnode])
2020
          si->dfs[n] = si->dfs[t];
2021
      }
2022
    }
2023
 
2024
  /* See if any components have been identified.  */
2025
  if (si->dfs[n] == my_dfs)
2026
    {
2027
      while (VEC_length (unsigned, si->scc_stack) != 0
2028
             && si->dfs[VEC_last (unsigned, si->scc_stack)] >= my_dfs)
2029
        {
2030
          unsigned int w = VEC_pop (unsigned, si->scc_stack);
2031
          si->node_mapping[w] = n;
2032
 
2033
          if (!TEST_BIT (graph->direct_nodes, w))
2034
            RESET_BIT (graph->direct_nodes, n);
2035
 
2036
          /* Unify our nodes.  */
2037
          if (graph->preds[w])
2038
            {
2039
              if (!graph->preds[n])
2040
                graph->preds[n] = BITMAP_ALLOC (&predbitmap_obstack);
2041
              bitmap_ior_into (graph->preds[n], graph->preds[w]);
2042
            }
2043
          if (graph->implicit_preds[w])
2044
            {
2045
              if (!graph->implicit_preds[n])
2046
                graph->implicit_preds[n] = BITMAP_ALLOC (&predbitmap_obstack);
2047
              bitmap_ior_into (graph->implicit_preds[n],
2048
                               graph->implicit_preds[w]);
2049
            }
2050
          if (graph->points_to[w])
2051
            {
2052
              if (!graph->points_to[n])
2053
                graph->points_to[n] = BITMAP_ALLOC (&predbitmap_obstack);
2054
              bitmap_ior_into (graph->points_to[n],
2055
                               graph->points_to[w]);
2056
            }
2057
        }
2058
      SET_BIT (si->deleted, n);
2059
    }
2060
  else
2061
    VEC_safe_push (unsigned, heap, si->scc_stack, n);
2062
}
2063
 
2064
/* Label pointer equivalences.  */
2065
 
2066
static void
2067
label_visit (constraint_graph_t graph, struct scc_info *si, unsigned int n)
2068
{
2069
  unsigned int i;
2070
  bitmap_iterator bi;
2071
  SET_BIT (si->visited, n);
2072
 
2073
  if (!graph->points_to[n])
2074
    graph->points_to[n] = BITMAP_ALLOC (&predbitmap_obstack);
2075
 
2076
  /* Label and union our incoming edges's points to sets.  */
2077
  EXECUTE_IF_IN_NONNULL_BITMAP (graph->preds[n], 0, i, bi)
2078
    {
2079
      unsigned int w = si->node_mapping[i];
2080
      if (!TEST_BIT (si->visited, w))
2081
        label_visit (graph, si, w);
2082
 
2083
      /* Skip unused edges  */
2084
      if (w == n || graph->pointer_label[w] == 0)
2085
        continue;
2086
 
2087
      if (graph->points_to[w])
2088
        bitmap_ior_into(graph->points_to[n], graph->points_to[w]);
2089
    }
2090
  /* Indirect nodes get fresh variables.  */
2091
  if (!TEST_BIT (graph->direct_nodes, n))
2092
    bitmap_set_bit (graph->points_to[n], FIRST_REF_NODE + n);
2093
 
2094
  if (!bitmap_empty_p (graph->points_to[n]))
2095
    {
2096
      unsigned int label = equiv_class_lookup (pointer_equiv_class_table,
2097
                                               graph->points_to[n]);
2098
      if (!label)
2099
        {
2100
          label = pointer_equiv_class++;
2101
          equiv_class_add (pointer_equiv_class_table,
2102
                           label, graph->points_to[n]);
2103
        }
2104
      graph->pointer_label[n] = label;
2105
    }
2106
}
2107
 
2108
/* Perform offline variable substitution, discovering equivalence
2109
   classes, and eliminating non-pointer variables.  */
2110
 
2111
static struct scc_info *
2112
perform_var_substitution (constraint_graph_t graph)
2113
{
2114
  unsigned int i;
2115
  unsigned int size = graph->size;
2116
  struct scc_info *si = init_scc_info (size);
2117
 
2118
  bitmap_obstack_initialize (&iteration_obstack);
2119
  pointer_equiv_class_table = htab_create (511, equiv_class_label_hash,
2120
                                           equiv_class_label_eq, free);
2121
  location_equiv_class_table = htab_create (511, equiv_class_label_hash,
2122
                                            equiv_class_label_eq, free);
2123
  pointer_equiv_class = 1;
2124
  location_equiv_class = 1;
2125
 
2126
  /* Condense the nodes, which means to find SCC's, count incoming
2127
     predecessors, and unite nodes in SCC's.  */
2128
  for (i = 0; i < FIRST_REF_NODE; i++)
2129
    if (!TEST_BIT (si->visited, si->node_mapping[i]))
2130
      condense_visit (graph, si, si->node_mapping[i]);
2131
 
2132
  sbitmap_zero (si->visited);
2133
  /* Actually the label the nodes for pointer equivalences  */
2134
  for (i = 0; i < FIRST_REF_NODE; i++)
2135
    if (!TEST_BIT (si->visited, si->node_mapping[i]))
2136
      label_visit (graph, si, si->node_mapping[i]);
2137
 
2138
  /* Calculate location equivalence labels.  */
2139
  for (i = 0; i < FIRST_REF_NODE; i++)
2140
    {
2141
      bitmap pointed_by;
2142
      bitmap_iterator bi;
2143
      unsigned int j;
2144
      unsigned int label;
2145
 
2146
      if (!graph->pointed_by[i])
2147
        continue;
2148
      pointed_by = BITMAP_ALLOC (&iteration_obstack);
2149
 
2150
      /* Translate the pointed-by mapping for pointer equivalence
2151
         labels.  */
2152
      EXECUTE_IF_SET_IN_BITMAP (graph->pointed_by[i], 0, j, bi)
2153
        {
2154
          bitmap_set_bit (pointed_by,
2155
                          graph->pointer_label[si->node_mapping[j]]);
2156
        }
2157
      /* The original pointed_by is now dead.  */
2158
      BITMAP_FREE (graph->pointed_by[i]);
2159
 
2160
      /* Look up the location equivalence label if one exists, or make
2161
         one otherwise.  */
2162
      label = equiv_class_lookup (location_equiv_class_table,
2163
                                  pointed_by);
2164
      if (label == 0)
2165
        {
2166
          label = location_equiv_class++;
2167
          equiv_class_add (location_equiv_class_table,
2168
                           label, pointed_by);
2169
        }
2170
      else
2171
        {
2172
          if (dump_file && (dump_flags & TDF_DETAILS))
2173
            fprintf (dump_file, "Found location equivalence for node %s\n",
2174
                     get_varinfo (i)->name);
2175
          BITMAP_FREE (pointed_by);
2176
        }
2177
      graph->loc_label[i] = label;
2178
 
2179
    }
2180
 
2181
  if (dump_file && (dump_flags & TDF_DETAILS))
2182
    for (i = 0; i < FIRST_REF_NODE; i++)
2183
      {
2184
        bool direct_node = TEST_BIT (graph->direct_nodes, i);
2185
        fprintf (dump_file,
2186
                 "Equivalence classes for %s node id %d:%s are pointer: %d"
2187
                 ", location:%d\n",
2188
                 direct_node ? "Direct node" : "Indirect node", i,
2189
                 get_varinfo (i)->name,
2190
                 graph->pointer_label[si->node_mapping[i]],
2191
                 graph->loc_label[si->node_mapping[i]]);
2192
      }
2193
 
2194
  /* Quickly eliminate our non-pointer variables.  */
2195
 
2196
  for (i = 0; i < FIRST_REF_NODE; i++)
2197
    {
2198
      unsigned int node = si->node_mapping[i];
2199
 
2200
      if (graph->pointer_label[node] == 0)
2201
        {
2202
          if (dump_file && (dump_flags & TDF_DETAILS))
2203
            fprintf (dump_file,
2204
                     "%s is a non-pointer variable, eliminating edges.\n",
2205
                     get_varinfo (node)->name);
2206
          stats.nonpointer_vars++;
2207
          clear_edges_for_node (graph, node);
2208
        }
2209
    }
2210
 
2211
  return si;
2212
}
2213
 
2214
/* Free information that was only necessary for variable
2215
   substitution.  */
2216
 
2217
static void
2218
free_var_substitution_info (struct scc_info *si)
2219
{
2220
  free_scc_info (si);
2221
  free (graph->pointer_label);
2222
  free (graph->loc_label);
2223
  free (graph->pointed_by);
2224
  free (graph->points_to);
2225
  free (graph->eq_rep);
2226
  sbitmap_free (graph->direct_nodes);
2227
  htab_delete (pointer_equiv_class_table);
2228
  htab_delete (location_equiv_class_table);
2229
  bitmap_obstack_release (&iteration_obstack);
2230
}
2231
 
2232
/* Return an existing node that is equivalent to NODE, which has
2233
   equivalence class LABEL, if one exists.  Return NODE otherwise.  */
2234
 
2235
static unsigned int
2236
find_equivalent_node (constraint_graph_t graph,
2237
                      unsigned int node, unsigned int label)
2238
{
2239
  /* If the address version of this variable is unused, we can
2240
     substitute it for anything else with the same label.
2241
     Otherwise, we know the pointers are equivalent, but not the
2242
     locations, and we can unite them later.  */
2243
 
2244
  if (!bitmap_bit_p (graph->address_taken, node))
2245
    {
2246
      gcc_assert (label < graph->size);
2247
 
2248
      if (graph->eq_rep[label] != -1)
2249
        {
2250
          /* Unify the two variables since we know they are equivalent.  */
2251
          if (unite (graph->eq_rep[label], node))
2252
            unify_nodes (graph, graph->eq_rep[label], node, false);
2253
          return graph->eq_rep[label];
2254
        }
2255
      else
2256
        {
2257
          graph->eq_rep[label] = node;
2258
          graph->pe_rep[label] = node;
2259
        }
2260
    }
2261
  else
2262
    {
2263
      gcc_assert (label < graph->size);
2264
      graph->pe[node] = label;
2265
      if (graph->pe_rep[label] == -1)
2266
        graph->pe_rep[label] = node;
2267
    }
2268
 
2269
  return node;
2270
}
2271
 
2272
/* Unite pointer equivalent but not location equivalent nodes in
2273
   GRAPH.  This may only be performed once variable substitution is
2274
   finished.  */
2275
 
2276
static void
2277
unite_pointer_equivalences (constraint_graph_t graph)
2278
{
2279
  unsigned int i;
2280
 
2281
  /* Go through the pointer equivalences and unite them to their
2282
     representative, if they aren't already.  */
2283
  for (i = 0; i < FIRST_REF_NODE; i++)
2284
    {
2285
      unsigned int label = graph->pe[i];
2286
      if (label)
2287
        {
2288
          int label_rep = graph->pe_rep[label];
2289
 
2290
          if (label_rep == -1)
2291
            continue;
2292
 
2293
          label_rep = find (label_rep);
2294
          if (label_rep >= 0 && unite (label_rep, find (i)))
2295
            unify_nodes (graph, label_rep, i, false);
2296
        }
2297
    }
2298
}
2299
 
2300
/* Move complex constraints to the GRAPH nodes they belong to.  */
2301
 
2302
static void
2303
move_complex_constraints (constraint_graph_t graph)
2304
{
2305
  int i;
2306
  constraint_t c;
2307
 
2308
  for (i = 0; VEC_iterate (constraint_t, constraints, i, c); i++)
2309
    {
2310
      if (c)
2311
        {
2312
          struct constraint_expr lhs = c->lhs;
2313
          struct constraint_expr rhs = c->rhs;
2314
 
2315
          if (lhs.type == DEREF)
2316
            {
2317
              insert_into_complex (graph, lhs.var, c);
2318
            }
2319
          else if (rhs.type == DEREF)
2320
            {
2321
              if (!(get_varinfo (lhs.var)->is_special_var))
2322
                insert_into_complex (graph, rhs.var, c);
2323
            }
2324
          else if (rhs.type != ADDRESSOF && lhs.var > anything_id
2325
                   && (lhs.offset != 0 || rhs.offset != 0))
2326
            {
2327
              insert_into_complex (graph, rhs.var, c);
2328
            }
2329
        }
2330
    }
2331
}
2332
 
2333
 
2334
/* Optimize and rewrite complex constraints while performing
2335
   collapsing of equivalent nodes.  SI is the SCC_INFO that is the
2336
   result of perform_variable_substitution.  */
2337
 
2338
static void
2339
rewrite_constraints (constraint_graph_t graph,
2340
                     struct scc_info *si)
2341
{
2342
  int i;
2343
  unsigned int j;
2344
  constraint_t c;
2345
 
2346
  for (j = 0; j < graph->size; j++)
2347
    gcc_assert (find (j) == j);
2348
 
2349
  for (i = 0; VEC_iterate (constraint_t, constraints, i, c); i++)
2350
    {
2351
      struct constraint_expr lhs = c->lhs;
2352
      struct constraint_expr rhs = c->rhs;
2353
      unsigned int lhsvar = find (lhs.var);
2354
      unsigned int rhsvar = find (rhs.var);
2355
      unsigned int lhsnode, rhsnode;
2356
      unsigned int lhslabel, rhslabel;
2357
 
2358
      lhsnode = si->node_mapping[lhsvar];
2359
      rhsnode = si->node_mapping[rhsvar];
2360
      lhslabel = graph->pointer_label[lhsnode];
2361
      rhslabel = graph->pointer_label[rhsnode];
2362
 
2363
      /* See if it is really a non-pointer variable, and if so, ignore
2364
         the constraint.  */
2365
      if (lhslabel == 0)
2366
        {
2367
          if (dump_file && (dump_flags & TDF_DETAILS))
2368
            {
2369
 
2370
              fprintf (dump_file, "%s is a non-pointer variable,"
2371
                       "ignoring constraint:",
2372
                       get_varinfo (lhs.var)->name);
2373
              dump_constraint (dump_file, c);
2374
            }
2375
          VEC_replace (constraint_t, constraints, i, NULL);
2376
          continue;
2377
        }
2378
 
2379
      if (rhslabel == 0)
2380
        {
2381
          if (dump_file && (dump_flags & TDF_DETAILS))
2382
            {
2383
 
2384
              fprintf (dump_file, "%s is a non-pointer variable,"
2385
                       "ignoring constraint:",
2386
                       get_varinfo (rhs.var)->name);
2387
              dump_constraint (dump_file, c);
2388
            }
2389
          VEC_replace (constraint_t, constraints, i, NULL);
2390
          continue;
2391
        }
2392
 
2393
      lhsvar = find_equivalent_node (graph, lhsvar, lhslabel);
2394
      rhsvar = find_equivalent_node (graph, rhsvar, rhslabel);
2395
      c->lhs.var = lhsvar;
2396
      c->rhs.var = rhsvar;
2397
 
2398
    }
2399
}
2400
 
2401
/* Eliminate indirect cycles involving NODE.  Return true if NODE was
2402
   part of an SCC, false otherwise.  */
2403
 
2404
static bool
2405
eliminate_indirect_cycles (unsigned int node)
2406
{
2407
  if (graph->indirect_cycles[node] != -1
2408
      && !bitmap_empty_p (get_varinfo (node)->solution))
2409
    {
2410
      unsigned int i;
2411
      VEC(unsigned,heap) *queue = NULL;
2412
      int queuepos;
2413
      unsigned int to = find (graph->indirect_cycles[node]);
2414
      bitmap_iterator bi;
2415
 
2416
      /* We can't touch the solution set and call unify_nodes
2417
         at the same time, because unify_nodes is going to do
2418
         bitmap unions into it. */
2419
 
2420
      EXECUTE_IF_SET_IN_BITMAP (get_varinfo (node)->solution, 0, i, bi)
2421
        {
2422
          if (find (i) == i && i != to)
2423
            {
2424
              if (unite (to, i))
2425
                VEC_safe_push (unsigned, heap, queue, i);
2426
            }
2427
        }
2428
 
2429
      for (queuepos = 0;
2430
           VEC_iterate (unsigned, queue, queuepos, i);
2431
           queuepos++)
2432
        {
2433
          unify_nodes (graph, to, i, true);
2434
        }
2435
      VEC_free (unsigned, heap, queue);
2436
      return true;
2437
    }
2438
  return false;
2439
}
2440
 
2441
/* Solve the constraint graph GRAPH using our worklist solver.
2442
   This is based on the PW* family of solvers from the "Efficient Field
2443
   Sensitive Pointer Analysis for C" paper.
2444
   It works by iterating over all the graph nodes, processing the complex
2445
   constraints and propagating the copy constraints, until everything stops
2446
   changed.  This corresponds to steps 6-8 in the solving list given above.  */
2447
 
2448
static void
2449
solve_graph (constraint_graph_t graph)
2450
{
2451
  unsigned int size = graph->size;
2452
  unsigned int i;
2453
  bitmap pts;
2454
 
2455
  changed_count = 0;
2456
  changed = sbitmap_alloc (size);
2457
  sbitmap_zero (changed);
2458
 
2459
  /* Mark all initial non-collapsed nodes as changed.  */
2460
  for (i = 0; i < size; i++)
2461
    {
2462
      varinfo_t ivi = get_varinfo (i);
2463
      if (find (i) == i && !bitmap_empty_p (ivi->solution)
2464
          && ((graph->succs[i] && !bitmap_empty_p (graph->succs[i]))
2465
              || VEC_length (constraint_t, graph->complex[i]) > 0))
2466
        {
2467
          SET_BIT (changed, i);
2468
          changed_count++;
2469
        }
2470
    }
2471
 
2472
  /* Allocate a bitmap to be used to store the changed bits.  */
2473
  pts = BITMAP_ALLOC (&pta_obstack);
2474
 
2475
  while (changed_count > 0)
2476
    {
2477
      unsigned int i;
2478
      struct topo_info *ti = init_topo_info ();
2479
      stats.iterations++;
2480
 
2481
      bitmap_obstack_initialize (&iteration_obstack);
2482
 
2483
      compute_topo_order (graph, ti);
2484
 
2485
      while (VEC_length (unsigned, ti->topo_order) != 0)
2486
        {
2487
 
2488
          i = VEC_pop (unsigned, ti->topo_order);
2489
 
2490
          /* If this variable is not a representative, skip it.  */
2491
          if (find (i) != i)
2492
            continue;
2493
 
2494
          /* In certain indirect cycle cases, we may merge this
2495
             variable to another.  */
2496
          if (eliminate_indirect_cycles (i) && find (i) != i)
2497
            continue;
2498
 
2499
          /* If the node has changed, we need to process the
2500
             complex constraints and outgoing edges again.  */
2501
          if (TEST_BIT (changed, i))
2502
            {
2503
              unsigned int j;
2504
              constraint_t c;
2505
              bitmap solution;
2506
              VEC(constraint_t,heap) *complex = graph->complex[i];
2507
              bool solution_empty;
2508
 
2509
              RESET_BIT (changed, i);
2510
              changed_count--;
2511
 
2512
              /* Compute the changed set of solution bits.  */
2513
              bitmap_and_compl (pts, get_varinfo (i)->solution,
2514
                                get_varinfo (i)->oldsolution);
2515
 
2516
              if (bitmap_empty_p (pts))
2517
                continue;
2518
 
2519
              bitmap_ior_into (get_varinfo (i)->oldsolution, pts);
2520
 
2521
              solution = get_varinfo (i)->solution;
2522
              solution_empty = bitmap_empty_p (solution);
2523
 
2524
              /* Process the complex constraints */
2525
              for (j = 0; VEC_iterate (constraint_t, complex, j, c); j++)
2526
                {
2527
                  /* XXX: This is going to unsort the constraints in
2528
                     some cases, which will occasionally add duplicate
2529
                     constraints during unification.  This does not
2530
                     affect correctness.  */
2531
                  c->lhs.var = find (c->lhs.var);
2532
                  c->rhs.var = find (c->rhs.var);
2533
 
2534
                  /* The only complex constraint that can change our
2535
                     solution to non-empty, given an empty solution,
2536
                     is a constraint where the lhs side is receiving
2537
                     some set from elsewhere.  */
2538
                  if (!solution_empty || c->lhs.type != DEREF)
2539
                    do_complex_constraint (graph, c, pts);
2540
                }
2541
 
2542
              solution_empty = bitmap_empty_p (solution);
2543
 
2544
              if (!solution_empty)
2545
                {
2546
                  bitmap_iterator bi;
2547
                  unsigned eff_escaped_id = find (escaped_id);
2548
 
2549
                  /* Propagate solution to all successors.  */
2550
                  EXECUTE_IF_IN_NONNULL_BITMAP (graph->succs[i],
2551
                                                0, j, bi)
2552
                    {
2553
                      bitmap tmp;
2554
                      bool flag;
2555
 
2556
                      unsigned int to = find (j);
2557
                      tmp = get_varinfo (to)->solution;
2558
                      flag = false;
2559
 
2560
                      /* Don't try to propagate to ourselves.  */
2561
                      if (to == i)
2562
                        continue;
2563
 
2564
                      /* If we propagate from ESCAPED use ESCAPED as
2565
                         placeholder.  */
2566
                      if (i == eff_escaped_id)
2567
                        flag = bitmap_set_bit (tmp, escaped_id);
2568
                      else
2569
                        flag = set_union_with_increment (tmp, pts, 0);
2570
 
2571
                      if (flag)
2572
                        {
2573
                          get_varinfo (to)->solution = tmp;
2574
                          if (!TEST_BIT (changed, to))
2575
                            {
2576
                              SET_BIT (changed, to);
2577
                              changed_count++;
2578
                            }
2579
                        }
2580
                    }
2581
                }
2582
            }
2583
        }
2584
      free_topo_info (ti);
2585
      bitmap_obstack_release (&iteration_obstack);
2586
    }
2587
 
2588
  BITMAP_FREE (pts);
2589
  sbitmap_free (changed);
2590
  bitmap_obstack_release (&oldpta_obstack);
2591
}
2592
 
2593
/* Map from trees to variable infos.  */
2594
static struct pointer_map_t *vi_for_tree;
2595
 
2596
 
2597
/* Insert ID as the variable id for tree T in the vi_for_tree map.  */
2598
 
2599
static void
2600
insert_vi_for_tree (tree t, varinfo_t vi)
2601
{
2602
  void **slot = pointer_map_insert (vi_for_tree, t);
2603
  gcc_assert (vi);
2604
  gcc_assert (*slot == NULL);
2605
  *slot = vi;
2606
}
2607
 
2608
/* Find the variable info for tree T in VI_FOR_TREE.  If T does not
2609
   exist in the map, return NULL, otherwise, return the varinfo we found.  */
2610
 
2611
static varinfo_t
2612
lookup_vi_for_tree (tree t)
2613
{
2614
  void **slot = pointer_map_contains (vi_for_tree, t);
2615
  if (slot == NULL)
2616
    return NULL;
2617
 
2618
  return (varinfo_t) *slot;
2619
}
2620
 
2621
/* Return a printable name for DECL  */
2622
 
2623
static const char *
2624
alias_get_name (tree decl)
2625
{
2626
  const char *res = get_name (decl);
2627
  char *temp;
2628
  int num_printed = 0;
2629
 
2630
  if (res != NULL)
2631
    return res;
2632
 
2633
  res = "NULL";
2634
  if (!dump_file)
2635
    return res;
2636
 
2637
  if (TREE_CODE (decl) == SSA_NAME)
2638
    {
2639
      num_printed = asprintf (&temp, "%s_%u",
2640
                              alias_get_name (SSA_NAME_VAR (decl)),
2641
                              SSA_NAME_VERSION (decl));
2642
    }
2643
  else if (DECL_P (decl))
2644
    {
2645
      num_printed = asprintf (&temp, "D.%u", DECL_UID (decl));
2646
    }
2647
  if (num_printed > 0)
2648
    {
2649
      res = ggc_strdup (temp);
2650
      free (temp);
2651
    }
2652
  return res;
2653
}
2654
 
2655
/* Find the variable id for tree T in the map.
2656
   If T doesn't exist in the map, create an entry for it and return it.  */
2657
 
2658
static varinfo_t
2659
get_vi_for_tree (tree t)
2660
{
2661
  void **slot = pointer_map_contains (vi_for_tree, t);
2662
  if (slot == NULL)
2663
    return get_varinfo (create_variable_info_for (t, alias_get_name (t)));
2664
 
2665
  return (varinfo_t) *slot;
2666
}
2667
 
2668
/* Get a scalar constraint expression for a new temporary variable.  */
2669
 
2670
static struct constraint_expr
2671
new_scalar_tmp_constraint_exp (const char *name)
2672
{
2673
  struct constraint_expr tmp;
2674
  varinfo_t vi;
2675
 
2676
  vi = new_var_info (NULL_TREE, name);
2677
  vi->offset = 0;
2678
  vi->size = -1;
2679
  vi->fullsize = -1;
2680
  vi->is_full_var = 1;
2681
 
2682
  tmp.var = vi->id;
2683
  tmp.type = SCALAR;
2684
  tmp.offset = 0;
2685
 
2686
  return tmp;
2687
}
2688
 
2689
/* Get a constraint expression vector from an SSA_VAR_P node.
2690
   If address_p is true, the result will be taken its address of.  */
2691
 
2692
static void
2693
get_constraint_for_ssa_var (tree t, VEC(ce_s, heap) **results, bool address_p)
2694
{
2695
  struct constraint_expr cexpr;
2696
  varinfo_t vi;
2697
 
2698
  /* We allow FUNCTION_DECLs here even though it doesn't make much sense.  */
2699
  gcc_assert (SSA_VAR_P (t) || DECL_P (t));
2700
 
2701
  /* For parameters, get at the points-to set for the actual parm
2702
     decl.  */
2703
  if (TREE_CODE (t) == SSA_NAME
2704
      && TREE_CODE (SSA_NAME_VAR (t)) == PARM_DECL
2705
      && SSA_NAME_IS_DEFAULT_DEF (t))
2706
    {
2707
      get_constraint_for_ssa_var (SSA_NAME_VAR (t), results, address_p);
2708
      return;
2709
    }
2710
 
2711
  vi = get_vi_for_tree (t);
2712
  cexpr.var = vi->id;
2713
  cexpr.type = SCALAR;
2714
  cexpr.offset = 0;
2715
  /* If we determine the result is "anything", and we know this is readonly,
2716
     say it points to readonly memory instead.  */
2717
  if (cexpr.var == anything_id && TREE_READONLY (t))
2718
    {
2719
      gcc_unreachable ();
2720
      cexpr.type = ADDRESSOF;
2721
      cexpr.var = readonly_id;
2722
    }
2723
 
2724
  /* If we are not taking the address of the constraint expr, add all
2725
     sub-fiels of the variable as well.  */
2726
  if (!address_p
2727
      && !vi->is_full_var)
2728
    {
2729
      for (; vi; vi = vi->next)
2730
        {
2731
          cexpr.var = vi->id;
2732
          VEC_safe_push (ce_s, heap, *results, &cexpr);
2733
        }
2734
      return;
2735
    }
2736
 
2737
  VEC_safe_push (ce_s, heap, *results, &cexpr);
2738
}
2739
 
2740
/* Process constraint T, performing various simplifications and then
2741
   adding it to our list of overall constraints.  */
2742
 
2743
static void
2744
process_constraint (constraint_t t)
2745
{
2746
  struct constraint_expr rhs = t->rhs;
2747
  struct constraint_expr lhs = t->lhs;
2748
 
2749
  gcc_assert (rhs.var < VEC_length (varinfo_t, varmap));
2750
  gcc_assert (lhs.var < VEC_length (varinfo_t, varmap));
2751
 
2752
  /* If we didn't get any useful constraint from the lhs we get
2753
     &ANYTHING as fallback from get_constraint_for.  Deal with
2754
     it here by turning it into *ANYTHING.  */
2755
  if (lhs.type == ADDRESSOF
2756
      && lhs.var == anything_id)
2757
    lhs.type = DEREF;
2758
 
2759
  /* ADDRESSOF on the lhs is invalid.  */
2760
  gcc_assert (lhs.type != ADDRESSOF);
2761
 
2762
  /* This can happen in our IR with things like n->a = *p */
2763
  if (rhs.type == DEREF && lhs.type == DEREF && rhs.var != anything_id)
2764
    {
2765
      /* Split into tmp = *rhs, *lhs = tmp */
2766
      struct constraint_expr tmplhs;
2767
      tmplhs = new_scalar_tmp_constraint_exp ("doubledereftmp");
2768
      process_constraint (new_constraint (tmplhs, rhs));
2769
      process_constraint (new_constraint (lhs, tmplhs));
2770
    }
2771
  else if (rhs.type == ADDRESSOF && lhs.type == DEREF)
2772
    {
2773
      /* Split into tmp = &rhs, *lhs = tmp */
2774
      struct constraint_expr tmplhs;
2775
      tmplhs = new_scalar_tmp_constraint_exp ("derefaddrtmp");
2776
      process_constraint (new_constraint (tmplhs, rhs));
2777
      process_constraint (new_constraint (lhs, tmplhs));
2778
    }
2779
  else
2780
    {
2781
      gcc_assert (rhs.type != ADDRESSOF || rhs.offset == 0);
2782
      VEC_safe_push (constraint_t, heap, constraints, t);
2783
    }
2784
}
2785
 
2786
/* Return true if T is a type that could contain pointers.  */
2787
 
2788
static bool
2789
type_could_have_pointers (tree type)
2790
{
2791
  if (POINTER_TYPE_P (type))
2792
    return true;
2793
 
2794
  if (TREE_CODE (type) == ARRAY_TYPE)
2795
    return type_could_have_pointers (TREE_TYPE (type));
2796
 
2797
  return AGGREGATE_TYPE_P (type);
2798
}
2799
 
2800
/* Return true if T is a variable of a type that could contain
2801
   pointers.  */
2802
 
2803
static bool
2804
could_have_pointers (tree t)
2805
{
2806
  return (((TREE_CODE (t) == VAR_DECL
2807
            || TREE_CODE (t) == PARM_DECL
2808
            || TREE_CODE (t) == RESULT_DECL)
2809
           && (TREE_PUBLIC (t) || DECL_EXTERNAL (t) || TREE_ADDRESSABLE (t)))
2810
          || type_could_have_pointers (TREE_TYPE (t)));
2811
}
2812
 
2813
/* Return the position, in bits, of FIELD_DECL from the beginning of its
2814
   structure.  */
2815
 
2816
static HOST_WIDE_INT
2817
bitpos_of_field (const tree fdecl)
2818
{
2819
 
2820
  if (!host_integerp (DECL_FIELD_OFFSET (fdecl), 0)
2821
      || !host_integerp (DECL_FIELD_BIT_OFFSET (fdecl), 0))
2822
    return -1;
2823
 
2824
  return (TREE_INT_CST_LOW (DECL_FIELD_OFFSET (fdecl)) * 8
2825
          + TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (fdecl)));
2826
}
2827
 
2828
 
2829
/* Get constraint expressions for offsetting PTR by OFFSET.  Stores the
2830
   resulting constraint expressions in *RESULTS.  */
2831
 
2832
static void
2833
get_constraint_for_ptr_offset (tree ptr, tree offset,
2834
                               VEC (ce_s, heap) **results)
2835
{
2836
  struct constraint_expr c;
2837
  unsigned int j, n;
2838
  HOST_WIDE_INT rhsunitoffset, rhsoffset;
2839
 
2840
  /* If we do not do field-sensitive PTA adding offsets to pointers
2841
     does not change the points-to solution.  */
2842
  if (!use_field_sensitive)
2843
    {
2844
      get_constraint_for (ptr, results);
2845
      return;
2846
    }
2847
 
2848
  /* If the offset is not a non-negative integer constant that fits
2849
     in a HOST_WIDE_INT, we have to fall back to a conservative
2850
     solution which includes all sub-fields of all pointed-to
2851
     variables of ptr.  */
2852
  if (offset == NULL_TREE
2853
      || !host_integerp (offset, 0))
2854
    rhsoffset = UNKNOWN_OFFSET;
2855
  else
2856
    {
2857
      /* Make sure the bit-offset also fits.  */
2858
      rhsunitoffset = TREE_INT_CST_LOW (offset);
2859
      rhsoffset = rhsunitoffset * BITS_PER_UNIT;
2860
      if (rhsunitoffset != rhsoffset / BITS_PER_UNIT)
2861
        rhsoffset = UNKNOWN_OFFSET;
2862
    }
2863
 
2864
  get_constraint_for (ptr, results);
2865
  if (rhsoffset == 0)
2866
    return;
2867
 
2868
  /* As we are eventually appending to the solution do not use
2869
     VEC_iterate here.  */
2870
  n = VEC_length (ce_s, *results);
2871
  for (j = 0; j < n; j++)
2872
    {
2873
      varinfo_t curr;
2874
      c = *VEC_index (ce_s, *results, j);
2875
      curr = get_varinfo (c.var);
2876
 
2877
      if (c.type == ADDRESSOF
2878
          /* If this varinfo represents a full variable just use it.  */
2879
          && curr->is_full_var)
2880
        c.offset = 0;
2881
      else if (c.type == ADDRESSOF
2882
               /* If we do not know the offset add all subfields.  */
2883
               && rhsoffset == UNKNOWN_OFFSET)
2884
        {
2885
          varinfo_t temp = lookup_vi_for_tree (curr->decl);
2886
          do
2887
            {
2888
              struct constraint_expr c2;
2889
              c2.var = temp->id;
2890
              c2.type = ADDRESSOF;
2891
              c2.offset = 0;
2892
              if (c2.var != c.var)
2893
                VEC_safe_push (ce_s, heap, *results, &c2);
2894
              temp = temp->next;
2895
            }
2896
          while (temp);
2897
        }
2898
      else if (c.type == ADDRESSOF)
2899
        {
2900
          varinfo_t temp;
2901
          unsigned HOST_WIDE_INT offset = curr->offset + rhsoffset;
2902
 
2903
          /* Search the sub-field which overlaps with the
2904
             pointed-to offset.  If the result is outside of the variable
2905
             we have to provide a conservative result, as the variable is
2906
             still reachable from the resulting pointer (even though it
2907
             technically cannot point to anything).  The last and first
2908
             sub-fields are such conservative results.
2909
             ???  If we always had a sub-field for &object + 1 then
2910
             we could represent this in a more precise way.  */
2911
          if (rhsoffset < 0
2912
              && curr->offset < offset)
2913
            offset = 0;
2914
          temp = first_or_preceding_vi_for_offset (curr, offset);
2915
 
2916
          /* If the found variable is not exactly at the pointed to
2917
             result, we have to include the next variable in the
2918
             solution as well.  Otherwise two increments by offset / 2
2919
             do not result in the same or a conservative superset
2920
             solution.  */
2921
          if (temp->offset != offset
2922
              && temp->next != NULL)
2923
            {
2924
              struct constraint_expr c2;
2925
              c2.var = temp->next->id;
2926
              c2.type = ADDRESSOF;
2927
              c2.offset = 0;
2928
              VEC_safe_push (ce_s, heap, *results, &c2);
2929
            }
2930
          c.var = temp->id;
2931
          c.offset = 0;
2932
        }
2933
      else
2934
        c.offset = rhsoffset;
2935
 
2936
      VEC_replace (ce_s, *results, j, &c);
2937
    }
2938
}
2939
 
2940
 
2941
/* Given a COMPONENT_REF T, return the constraint_expr vector for it.
2942
   If address_p is true the result will be taken its address of.  */
2943
 
2944
static void
2945
get_constraint_for_component_ref (tree t, VEC(ce_s, heap) **results,
2946
                                  bool address_p)
2947
{
2948
  tree orig_t = t;
2949
  HOST_WIDE_INT bitsize = -1;
2950
  HOST_WIDE_INT bitmaxsize = -1;
2951
  HOST_WIDE_INT bitpos;
2952
  tree forzero;
2953
  struct constraint_expr *result;
2954
 
2955
  /* Some people like to do cute things like take the address of
2956
     &0->a.b */
2957
  forzero = t;
2958
  while (!SSA_VAR_P (forzero) && !CONSTANT_CLASS_P (forzero))
2959
    forzero = TREE_OPERAND (forzero, 0);
2960
 
2961
  if (CONSTANT_CLASS_P (forzero) && integer_zerop (forzero))
2962
    {
2963
      struct constraint_expr temp;
2964
 
2965
      temp.offset = 0;
2966
      temp.var = integer_id;
2967
      temp.type = SCALAR;
2968
      VEC_safe_push (ce_s, heap, *results, &temp);
2969
      return;
2970
    }
2971
 
2972
  t = get_ref_base_and_extent (t, &bitpos, &bitsize, &bitmaxsize);
2973
 
2974
  /* Pretend to take the address of the base, we'll take care of
2975
     adding the required subset of sub-fields below.  */
2976
  get_constraint_for_1 (t, results, true);
2977
  gcc_assert (VEC_length (ce_s, *results) == 1);
2978
  result = VEC_last (ce_s, *results);
2979
 
2980
  if (result->type == SCALAR
2981
      && get_varinfo (result->var)->is_full_var)
2982
    /* For single-field vars do not bother about the offset.  */
2983
    result->offset = 0;
2984
  else if (result->type == SCALAR)
2985
    {
2986
      /* In languages like C, you can access one past the end of an
2987
         array.  You aren't allowed to dereference it, so we can
2988
         ignore this constraint. When we handle pointer subtraction,
2989
         we may have to do something cute here.  */
2990
 
2991
      if ((unsigned HOST_WIDE_INT)bitpos < get_varinfo (result->var)->fullsize
2992
          && bitmaxsize != 0)
2993
        {
2994
          /* It's also not true that the constraint will actually start at the
2995
             right offset, it may start in some padding.  We only care about
2996
             setting the constraint to the first actual field it touches, so
2997
             walk to find it.  */
2998
          struct constraint_expr cexpr = *result;
2999
          varinfo_t curr;
3000
          VEC_pop (ce_s, *results);
3001
          cexpr.offset = 0;
3002
          for (curr = get_varinfo (cexpr.var); curr; curr = curr->next)
3003
            {
3004
              if (ranges_overlap_p (curr->offset, curr->size,
3005
                                    bitpos, bitmaxsize))
3006
                {
3007
                  cexpr.var = curr->id;
3008
                  VEC_safe_push (ce_s, heap, *results, &cexpr);
3009
                  if (address_p)
3010
                    break;
3011
                }
3012
            }
3013
          /* If we are going to take the address of this field then
3014
             to be able to compute reachability correctly add at least
3015
             the last field of the variable.  */
3016
          if (address_p
3017
              && VEC_length (ce_s, *results) == 0)
3018
            {
3019
              curr = get_varinfo (cexpr.var);
3020
              while (curr->next != NULL)
3021
                curr = curr->next;
3022
              cexpr.var = curr->id;
3023
              VEC_safe_push (ce_s, heap, *results, &cexpr);
3024
            }
3025
          else
3026
            /* Assert that we found *some* field there. The user couldn't be
3027
               accessing *only* padding.  */
3028
            /* Still the user could access one past the end of an array
3029
               embedded in a struct resulting in accessing *only* padding.  */
3030
            gcc_assert (VEC_length (ce_s, *results) >= 1
3031
                        || ref_contains_array_ref (orig_t));
3032
        }
3033
      else if (bitmaxsize == 0)
3034
        {
3035
          if (dump_file && (dump_flags & TDF_DETAILS))
3036
            fprintf (dump_file, "Access to zero-sized part of variable,"
3037
                     "ignoring\n");
3038
        }
3039
      else
3040
        if (dump_file && (dump_flags & TDF_DETAILS))
3041
          fprintf (dump_file, "Access to past the end of variable, ignoring\n");
3042
    }
3043
  else if (result->type == DEREF)
3044
    {
3045
      /* If we do not know exactly where the access goes say so.  Note
3046
         that only for non-structure accesses we know that we access
3047
         at most one subfiled of any variable.  */
3048
      if (bitpos == -1
3049
          || bitsize != bitmaxsize
3050
          || AGGREGATE_TYPE_P (TREE_TYPE (orig_t)))
3051
        result->offset = UNKNOWN_OFFSET;
3052
      else
3053
        result->offset = bitpos;
3054
    }
3055
  else if (result->type == ADDRESSOF)
3056
    {
3057
      /* We can end up here for component references on a
3058
         VIEW_CONVERT_EXPR <>(&foobar).  */
3059
      result->type = SCALAR;
3060
      result->var = anything_id;
3061
      result->offset = 0;
3062
    }
3063
  else
3064
    gcc_unreachable ();
3065
}
3066
 
3067
 
3068
/* Dereference the constraint expression CONS, and return the result.
3069
   DEREF (ADDRESSOF) = SCALAR
3070
   DEREF (SCALAR) = DEREF
3071
   DEREF (DEREF) = (temp = DEREF1; result = DEREF(temp))
3072
   This is needed so that we can handle dereferencing DEREF constraints.  */
3073
 
3074
static void
3075
do_deref (VEC (ce_s, heap) **constraints)
3076
{
3077
  struct constraint_expr *c;
3078
  unsigned int i = 0;
3079
 
3080
  for (i = 0; VEC_iterate (ce_s, *constraints, i, c); i++)
3081
    {
3082
      if (c->type == SCALAR)
3083
        c->type = DEREF;
3084
      else if (c->type == ADDRESSOF)
3085
        c->type = SCALAR;
3086
      else if (c->type == DEREF)
3087
        {
3088
          struct constraint_expr tmplhs;
3089
          tmplhs = new_scalar_tmp_constraint_exp ("dereftmp");
3090
          process_constraint (new_constraint (tmplhs, *c));
3091
          c->var = tmplhs.var;
3092
        }
3093
      else
3094
        gcc_unreachable ();
3095
    }
3096
}
3097
 
3098
static void get_constraint_for_1 (tree, VEC (ce_s, heap) **, bool);
3099
 
3100
/* Given a tree T, return the constraint expression for taking the
3101
   address of it.  */
3102
 
3103
static void
3104
get_constraint_for_address_of (tree t, VEC (ce_s, heap) **results)
3105
{
3106
  struct constraint_expr *c;
3107
  unsigned int i;
3108
 
3109
  get_constraint_for_1 (t, results, true);
3110
 
3111
  for (i = 0; VEC_iterate (ce_s, *results, i, c); i++)
3112
    {
3113
      if (c->type == DEREF)
3114
        c->type = SCALAR;
3115
      else
3116
        c->type = ADDRESSOF;
3117
    }
3118
}
3119
 
3120
/* Given a tree T, return the constraint expression for it.  */
3121
 
3122
static void
3123
get_constraint_for_1 (tree t, VEC (ce_s, heap) **results, bool address_p)
3124
{
3125
  struct constraint_expr temp;
3126
 
3127
  /* x = integer is all glommed to a single variable, which doesn't
3128
     point to anything by itself.  That is, of course, unless it is an
3129
     integer constant being treated as a pointer, in which case, we
3130
     will return that this is really the addressof anything.  This
3131
     happens below, since it will fall into the default case. The only
3132
     case we know something about an integer treated like a pointer is
3133
     when it is the NULL pointer, and then we just say it points to
3134
     NULL.
3135
 
3136
     Do not do that if -fno-delete-null-pointer-checks though, because
3137
     in that case *NULL does not fail, so it _should_ alias *anything.
3138
     It is not worth adding a new option or renaming the existing one,
3139
     since this case is relatively obscure.  */
3140
  if (flag_delete_null_pointer_checks
3141
      && ((TREE_CODE (t) == INTEGER_CST
3142
           && integer_zerop (t))
3143
          /* The only valid CONSTRUCTORs in gimple with pointer typed
3144
             elements are zero-initializer.  */
3145
          || TREE_CODE (t) == CONSTRUCTOR))
3146
    {
3147
      temp.var = nothing_id;
3148
      temp.type = ADDRESSOF;
3149
      temp.offset = 0;
3150
      VEC_safe_push (ce_s, heap, *results, &temp);
3151
      return;
3152
    }
3153
 
3154
  /* String constants are read-only.  */
3155
  if (TREE_CODE (t) == STRING_CST)
3156
    {
3157
      temp.var = readonly_id;
3158
      temp.type = SCALAR;
3159
      temp.offset = 0;
3160
      VEC_safe_push (ce_s, heap, *results, &temp);
3161
      return;
3162
    }
3163
 
3164
  switch (TREE_CODE_CLASS (TREE_CODE (t)))
3165
    {
3166
    case tcc_expression:
3167
      {
3168
        switch (TREE_CODE (t))
3169
          {
3170
          case ADDR_EXPR:
3171
            get_constraint_for_address_of (TREE_OPERAND (t, 0), results);
3172
            return;
3173
          default:;
3174
          }
3175
        break;
3176
      }
3177
    case tcc_reference:
3178
      {
3179
        switch (TREE_CODE (t))
3180
          {
3181
          case INDIRECT_REF:
3182
            {
3183
              get_constraint_for_1 (TREE_OPERAND (t, 0), results, address_p);
3184
              do_deref (results);
3185
              return;
3186
            }
3187
          case ARRAY_REF:
3188
          case ARRAY_RANGE_REF:
3189
          case COMPONENT_REF:
3190
            get_constraint_for_component_ref (t, results, address_p);
3191
            return;
3192
          case VIEW_CONVERT_EXPR:
3193
            get_constraint_for_1 (TREE_OPERAND (t, 0), results, address_p);
3194
            return;
3195
          /* We are missing handling for TARGET_MEM_REF here.  */
3196
          default:;
3197
          }
3198
        break;
3199
      }
3200
    case tcc_exceptional:
3201
      {
3202
        switch (TREE_CODE (t))
3203
          {
3204
          case SSA_NAME:
3205
            {
3206
              get_constraint_for_ssa_var (t, results, address_p);
3207
              return;
3208
            }
3209
          default:;
3210
          }
3211
        break;
3212
      }
3213
    case tcc_declaration:
3214
      {
3215
        get_constraint_for_ssa_var (t, results, address_p);
3216
        return;
3217
      }
3218
    default:;
3219
    }
3220
 
3221
  /* The default fallback is a constraint from anything.  */
3222
  temp.type = ADDRESSOF;
3223
  temp.var = anything_id;
3224
  temp.offset = 0;
3225
  VEC_safe_push (ce_s, heap, *results, &temp);
3226
}
3227
 
3228
/* Given a gimple tree T, return the constraint expression vector for it.  */
3229
 
3230
static void
3231
get_constraint_for (tree t, VEC (ce_s, heap) **results)
3232
{
3233
  gcc_assert (VEC_length (ce_s, *results) == 0);
3234
 
3235
  get_constraint_for_1 (t, results, false);
3236
}
3237
 
3238
 
3239
/* Efficiently generates constraints from all entries in *RHSC to all
3240
   entries in *LHSC.  */
3241
 
3242
static void
3243
process_all_all_constraints (VEC (ce_s, heap) *lhsc, VEC (ce_s, heap) *rhsc)
3244
{
3245
  struct constraint_expr *lhsp, *rhsp;
3246
  unsigned i, j;
3247
 
3248
  if (VEC_length (ce_s, lhsc) <= 1
3249
      || VEC_length (ce_s, rhsc) <= 1)
3250
    {
3251
      for (i = 0; VEC_iterate (ce_s, lhsc, i, lhsp); ++i)
3252
        for (j = 0; VEC_iterate (ce_s, rhsc, j, rhsp); ++j)
3253
          process_constraint (new_constraint (*lhsp, *rhsp));
3254
    }
3255
  else
3256
    {
3257
      struct constraint_expr tmp;
3258
      tmp = new_scalar_tmp_constraint_exp ("allalltmp");
3259
      for (i = 0; VEC_iterate (ce_s, rhsc, i, rhsp); ++i)
3260
        process_constraint (new_constraint (tmp, *rhsp));
3261
      for (i = 0; VEC_iterate (ce_s, lhsc, i, lhsp); ++i)
3262
        process_constraint (new_constraint (*lhsp, tmp));
3263
    }
3264
}
3265
 
3266
/* Handle aggregate copies by expanding into copies of the respective
3267
   fields of the structures.  */
3268
 
3269
static void
3270
do_structure_copy (tree lhsop, tree rhsop)
3271
{
3272
  struct constraint_expr *lhsp, *rhsp;
3273
  VEC (ce_s, heap) *lhsc = NULL, *rhsc = NULL;
3274
  unsigned j;
3275
 
3276
  get_constraint_for (lhsop, &lhsc);
3277
  get_constraint_for (rhsop, &rhsc);
3278
  lhsp = VEC_index (ce_s, lhsc, 0);
3279
  rhsp = VEC_index (ce_s, rhsc, 0);
3280
  if (lhsp->type == DEREF
3281
      || (lhsp->type == ADDRESSOF && lhsp->var == anything_id)
3282
      || rhsp->type == DEREF)
3283
    process_all_all_constraints (lhsc, rhsc);
3284
  else if (lhsp->type == SCALAR
3285
           && (rhsp->type == SCALAR
3286
               || rhsp->type == ADDRESSOF))
3287
    {
3288
      HOST_WIDE_INT lhssize, lhsmaxsize, lhsoffset;
3289
      HOST_WIDE_INT rhssize, rhsmaxsize, rhsoffset;
3290
      unsigned k = 0;
3291
      get_ref_base_and_extent (lhsop, &lhsoffset, &lhssize, &lhsmaxsize);
3292
      get_ref_base_and_extent (rhsop, &rhsoffset, &rhssize, &rhsmaxsize);
3293
      for (j = 0; VEC_iterate (ce_s, lhsc, j, lhsp);)
3294
        {
3295
          varinfo_t lhsv, rhsv;
3296
          rhsp = VEC_index (ce_s, rhsc, k);
3297
          lhsv = get_varinfo (lhsp->var);
3298
          rhsv = get_varinfo (rhsp->var);
3299
          if (lhsv->may_have_pointers
3300
              && ranges_overlap_p (lhsv->offset + rhsoffset, lhsv->size,
3301
                                   rhsv->offset + lhsoffset, rhsv->size))
3302
            process_constraint (new_constraint (*lhsp, *rhsp));
3303
          if (lhsv->offset + rhsoffset + lhsv->size
3304
              > rhsv->offset + lhsoffset + rhsv->size)
3305
            {
3306
              ++k;
3307
              if (k >= VEC_length (ce_s, rhsc))
3308
                break;
3309
            }
3310
          else
3311
            ++j;
3312
        }
3313
    }
3314
  else
3315
    gcc_unreachable ();
3316
 
3317
  VEC_free (ce_s, heap, lhsc);
3318
  VEC_free (ce_s, heap, rhsc);
3319
}
3320
 
3321
/* Create a constraint ID = OP.  */
3322
 
3323
static void
3324
make_constraint_to (unsigned id, tree op)
3325
{
3326
  VEC(ce_s, heap) *rhsc = NULL;
3327
  struct constraint_expr *c;
3328
  struct constraint_expr includes;
3329
  unsigned int j;
3330
 
3331
  includes.var = id;
3332
  includes.offset = 0;
3333
  includes.type = SCALAR;
3334
 
3335
  get_constraint_for (op, &rhsc);
3336
  for (j = 0; VEC_iterate (ce_s, rhsc, j, c); j++)
3337
    process_constraint (new_constraint (includes, *c));
3338
  VEC_free (ce_s, heap, rhsc);
3339
}
3340
 
3341
/* Create a constraint ID = &FROM.  */
3342
 
3343
static void
3344
make_constraint_from (varinfo_t vi, int from)
3345
{
3346
  struct constraint_expr lhs, rhs;
3347
 
3348
  lhs.var = vi->id;
3349
  lhs.offset = 0;
3350
  lhs.type = SCALAR;
3351
 
3352
  rhs.var = from;
3353
  rhs.offset = 0;
3354
  rhs.type = ADDRESSOF;
3355
  process_constraint (new_constraint (lhs, rhs));
3356
}
3357
 
3358
/* Create a constraint ID = FROM.  */
3359
 
3360
static void
3361
make_copy_constraint (varinfo_t vi, int from)
3362
{
3363
  struct constraint_expr lhs, rhs;
3364
 
3365
  lhs.var = vi->id;
3366
  lhs.offset = 0;
3367
  lhs.type = SCALAR;
3368
 
3369
  rhs.var = from;
3370
  rhs.offset = 0;
3371
  rhs.type = SCALAR;
3372
  process_constraint (new_constraint (lhs, rhs));
3373
}
3374
 
3375
/* Make constraints necessary to make OP escape.  */
3376
 
3377
static void
3378
make_escape_constraint (tree op)
3379
{
3380
  make_constraint_to (escaped_id, op);
3381
}
3382
 
3383
/* Create a new artificial heap variable with NAME and make a
3384
   constraint from it to LHS.  Return the created variable.  */
3385
 
3386
static varinfo_t
3387
make_constraint_from_heapvar (varinfo_t lhs, const char *name)
3388
{
3389
  varinfo_t vi;
3390
  tree heapvar = heapvar_lookup (lhs->decl, lhs->offset);
3391
 
3392
  if (heapvar == NULL_TREE)
3393
    {
3394
      var_ann_t ann;
3395
      heapvar = create_tmp_var_raw (ptr_type_node, name);
3396
      DECL_EXTERNAL (heapvar) = 1;
3397
 
3398
      heapvar_insert (lhs->decl, lhs->offset, heapvar);
3399
 
3400
      ann = get_var_ann (heapvar);
3401
      ann->is_heapvar = 1;
3402
    }
3403
 
3404
  /* For global vars we need to add a heapvar to the list of referenced
3405
     vars of a different function than it was created for originally.  */
3406
  if (gimple_referenced_vars (cfun))
3407
    add_referenced_var (heapvar);
3408
 
3409
  vi = new_var_info (heapvar, name);
3410
  vi->is_artificial_var = true;
3411
  vi->is_heap_var = true;
3412
  vi->is_unknown_size_var = true;
3413
  vi->offset = 0;
3414
  vi->fullsize = ~0;
3415
  vi->size = ~0;
3416
  vi->is_full_var = true;
3417
  insert_vi_for_tree (heapvar, vi);
3418
 
3419
  make_constraint_from (lhs, vi->id);
3420
 
3421
  return vi;
3422
}
3423
 
3424
/* Create a new artificial heap variable with NAME and make a
3425
   constraint from it to LHS.  Set flags according to a tag used
3426
   for tracking restrict pointers.  */
3427
 
3428
static void
3429
make_constraint_from_restrict (varinfo_t lhs, const char *name)
3430
{
3431
  varinfo_t vi;
3432
  vi = make_constraint_from_heapvar (lhs, name);
3433
  vi->is_restrict_var = 1;
3434
  vi->is_global_var = 0;
3435
  vi->is_special_var = 1;
3436
  vi->may_have_pointers = 0;
3437
}
3438
 
3439
/* For non-IPA mode, generate constraints necessary for a call on the
3440
   RHS.  */
3441
 
3442
static void
3443
handle_rhs_call (gimple stmt, VEC(ce_s, heap) **results)
3444
{
3445
  struct constraint_expr rhsc;
3446
  unsigned i;
3447
 
3448
  for (i = 0; i < gimple_call_num_args (stmt); ++i)
3449
    {
3450
      tree arg = gimple_call_arg (stmt, i);
3451
 
3452
      /* Find those pointers being passed, and make sure they end up
3453
         pointing to anything.  */
3454
      if (could_have_pointers (arg))
3455
        make_escape_constraint (arg);
3456
    }
3457
 
3458
  /* The static chain escapes as well.  */
3459
  if (gimple_call_chain (stmt))
3460
    make_escape_constraint (gimple_call_chain (stmt));
3461
 
3462
  /* And if we applied NRV the address of the return slot escapes as well.  */
3463
  if (gimple_call_return_slot_opt_p (stmt)
3464
      && gimple_call_lhs (stmt) != NULL_TREE
3465
      && TREE_ADDRESSABLE (TREE_TYPE (gimple_call_lhs (stmt))))
3466
    {
3467
      VEC(ce_s, heap) *tmpc = NULL;
3468
      struct constraint_expr lhsc, *c;
3469
      get_constraint_for_address_of (gimple_call_lhs (stmt), &tmpc);
3470
      lhsc.var = escaped_id;
3471
      lhsc.offset = 0;
3472
      lhsc.type = SCALAR;
3473
      for (i = 0; VEC_iterate (ce_s, tmpc, i, c); ++i)
3474
        process_constraint (new_constraint (lhsc, *c));
3475
      VEC_free(ce_s, heap, tmpc);
3476
    }
3477
 
3478
  /* Regular functions return nonlocal memory.  */
3479
  rhsc.var = nonlocal_id;
3480
  rhsc.offset = 0;
3481
  rhsc.type = SCALAR;
3482
  VEC_safe_push (ce_s, heap, *results, &rhsc);
3483
}
3484
 
3485
/* For non-IPA mode, generate constraints necessary for a call
3486
   that returns a pointer and assigns it to LHS.  This simply makes
3487
   the LHS point to global and escaped variables.  */
3488
 
3489
static void
3490
handle_lhs_call (tree lhs, int flags, VEC(ce_s, heap) *rhsc, tree fndecl)
3491
{
3492
  VEC(ce_s, heap) *lhsc = NULL;
3493
 
3494
  get_constraint_for (lhs, &lhsc);
3495
 
3496
  if (flags & ECF_MALLOC)
3497
    {
3498
      varinfo_t vi;
3499
      vi = make_constraint_from_heapvar (get_vi_for_tree (lhs), "HEAP");
3500
      /* We delay marking allocated storage global until we know if
3501
         it escapes.  */
3502
      DECL_EXTERNAL (vi->decl) = 0;
3503
      vi->is_global_var = 0;
3504
      /* If this is not a real malloc call assume the memory was
3505
         initialized and thus may point to global memory.  All
3506
         builtin functions with the malloc attribute behave in a sane way.  */
3507
      if (!fndecl
3508
          || DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL)
3509
        make_constraint_from (vi, nonlocal_id);
3510
    }
3511
  else if (VEC_length (ce_s, rhsc) > 0)
3512
    {
3513
      /* If the store is to a global decl make sure to
3514
         add proper escape constraints.  */
3515
      lhs = get_base_address (lhs);
3516
      if (lhs
3517
          && DECL_P (lhs)
3518
          && is_global_var (lhs))
3519
        {
3520
          struct constraint_expr tmpc;
3521
          tmpc.var = escaped_id;
3522
          tmpc.offset = 0;
3523
          tmpc.type = SCALAR;
3524
          VEC_safe_push (ce_s, heap, lhsc, &tmpc);
3525
        }
3526
      process_all_all_constraints (lhsc, rhsc);
3527
    }
3528
  VEC_free (ce_s, heap, lhsc);
3529
}
3530
 
3531
/* For non-IPA mode, generate constraints necessary for a call of a
3532
   const function that returns a pointer in the statement STMT.  */
3533
 
3534
static void
3535
handle_const_call (gimple stmt, VEC(ce_s, heap) **results)
3536
{
3537
  struct constraint_expr rhsc;
3538
  unsigned int k;
3539
 
3540
  /* Treat nested const functions the same as pure functions as far
3541
     as the static chain is concerned.  */
3542
  if (gimple_call_chain (stmt))
3543
    {
3544
      make_constraint_to (callused_id, gimple_call_chain (stmt));
3545
      rhsc.var = callused_id;
3546
      rhsc.offset = 0;
3547
      rhsc.type = SCALAR;
3548
      VEC_safe_push (ce_s, heap, *results, &rhsc);
3549
    }
3550
 
3551
  /* May return arguments.  */
3552
  for (k = 0; k < gimple_call_num_args (stmt); ++k)
3553
    {
3554
      tree arg = gimple_call_arg (stmt, k);
3555
 
3556
      if (could_have_pointers (arg))
3557
        {
3558
          VEC(ce_s, heap) *argc = NULL;
3559
          unsigned i;
3560
          struct constraint_expr *argp;
3561
          get_constraint_for (arg, &argc);
3562
          for (i = 0; VEC_iterate (ce_s, argc, i, argp); ++i)
3563
            VEC_safe_push (ce_s, heap, *results, argp);
3564
          VEC_free(ce_s, heap, argc);
3565
        }
3566
    }
3567
 
3568
  /* May return addresses of globals.  */
3569
  rhsc.var = nonlocal_id;
3570
  rhsc.offset = 0;
3571
  rhsc.type = ADDRESSOF;
3572
  VEC_safe_push (ce_s, heap, *results, &rhsc);
3573
}
3574
 
3575
/* For non-IPA mode, generate constraints necessary for a call to a
3576
   pure function in statement STMT.  */
3577
 
3578
static void
3579
handle_pure_call (gimple stmt, VEC(ce_s, heap) **results)
3580
{
3581
  struct constraint_expr rhsc;
3582
  unsigned i;
3583
  bool need_callused = false;
3584
 
3585
  /* Memory reached from pointer arguments is call-used.  */
3586
  for (i = 0; i < gimple_call_num_args (stmt); ++i)
3587
    {
3588
      tree arg = gimple_call_arg (stmt, i);
3589
 
3590
      if (could_have_pointers (arg))
3591
        {
3592
          make_constraint_to (callused_id, arg);
3593
          need_callused = true;
3594
        }
3595
    }
3596
 
3597
  /* The static chain is used as well.  */
3598
  if (gimple_call_chain (stmt))
3599
    {
3600
      make_constraint_to (callused_id, gimple_call_chain (stmt));
3601
      need_callused = true;
3602
    }
3603
 
3604
  /* Pure functions may return callused and nonlocal memory.  */
3605
  if (need_callused)
3606
    {
3607
      rhsc.var = callused_id;
3608
      rhsc.offset = 0;
3609
      rhsc.type = SCALAR;
3610
      VEC_safe_push (ce_s, heap, *results, &rhsc);
3611
    }
3612
  rhsc.var = nonlocal_id;
3613
  rhsc.offset = 0;
3614
  rhsc.type = SCALAR;
3615
  VEC_safe_push (ce_s, heap, *results, &rhsc);
3616
}
3617
 
3618
/* Walk statement T setting up aliasing constraints according to the
3619
   references found in T.  This function is the main part of the
3620
   constraint builder.  AI points to auxiliary alias information used
3621
   when building alias sets and computing alias grouping heuristics.  */
3622
 
3623
static void
3624
find_func_aliases (gimple origt)
3625
{
3626
  gimple t = origt;
3627
  VEC(ce_s, heap) *lhsc = NULL;
3628
  VEC(ce_s, heap) *rhsc = NULL;
3629
  struct constraint_expr *c;
3630
 
3631
  /* Now build constraints expressions.  */
3632
  if (gimple_code (t) == GIMPLE_PHI)
3633
    {
3634
      gcc_assert (!AGGREGATE_TYPE_P (TREE_TYPE (gimple_phi_result (t))));
3635
 
3636
      /* Only care about pointers and structures containing
3637
         pointers.  */
3638
      if (could_have_pointers (gimple_phi_result (t)))
3639
        {
3640
          size_t i;
3641
          unsigned int j;
3642
 
3643
          /* For a phi node, assign all the arguments to
3644
             the result.  */
3645
          get_constraint_for (gimple_phi_result (t), &lhsc);
3646
          for (i = 0; i < gimple_phi_num_args (t); i++)
3647
            {
3648
              tree strippedrhs = PHI_ARG_DEF (t, i);
3649
 
3650
              STRIP_NOPS (strippedrhs);
3651
              get_constraint_for (gimple_phi_arg_def (t, i), &rhsc);
3652
 
3653
              for (j = 0; VEC_iterate (ce_s, lhsc, j, c); j++)
3654
                {
3655
                  struct constraint_expr *c2;
3656
                  while (VEC_length (ce_s, rhsc) > 0)
3657
                    {
3658
                      c2 = VEC_last (ce_s, rhsc);
3659
                      process_constraint (new_constraint (*c, *c2));
3660
                      VEC_pop (ce_s, rhsc);
3661
                    }
3662
                }
3663
            }
3664
        }
3665
    }
3666
  /* In IPA mode, we need to generate constraints to pass call
3667
     arguments through their calls.   There are two cases,
3668
     either a GIMPLE_CALL returning a value, or just a plain
3669
     GIMPLE_CALL when we are not.
3670
 
3671
     In non-ipa mode, we need to generate constraints for each
3672
     pointer passed by address.  */
3673
  else if (is_gimple_call (t))
3674
    {
3675
      tree fndecl = gimple_call_fndecl (t);
3676
      if (fndecl != NULL_TREE
3677
          && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3678
        /* ???  All builtins that are handled here need to be handled
3679
           in the alias-oracle query functions explicitly!  */
3680
        switch (DECL_FUNCTION_CODE (fndecl))
3681
          {
3682
          /* All the following functions return a pointer to the same object
3683
             as their first argument points to.  The functions do not add
3684
             to the ESCAPED solution.  The functions make the first argument
3685
             pointed to memory point to what the second argument pointed to
3686
             memory points to.  */
3687
          case BUILT_IN_STRCPY:
3688
          case BUILT_IN_STRNCPY:
3689
          case BUILT_IN_BCOPY:
3690
          case BUILT_IN_MEMCPY:
3691
          case BUILT_IN_MEMMOVE:
3692
          case BUILT_IN_MEMPCPY:
3693
          case BUILT_IN_STPCPY:
3694
          case BUILT_IN_STPNCPY:
3695
          case BUILT_IN_STRCAT:
3696
          case BUILT_IN_STRNCAT:
3697
            {
3698
              tree res = gimple_call_lhs (t);
3699
              tree dest = gimple_call_arg (t, (DECL_FUNCTION_CODE (fndecl)
3700
                                               == BUILT_IN_BCOPY ? 1 : 0));
3701
              tree src = gimple_call_arg (t, (DECL_FUNCTION_CODE (fndecl)
3702
                                              == BUILT_IN_BCOPY ? 0 : 1));
3703
              if (res != NULL_TREE)
3704
                {
3705
                  get_constraint_for (res, &lhsc);
3706
                  if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_MEMPCPY
3707
                      || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPCPY
3708
                      || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPNCPY)
3709
                    get_constraint_for_ptr_offset (dest, NULL_TREE, &rhsc);
3710
                  else
3711
                    get_constraint_for (dest, &rhsc);
3712
                  process_all_all_constraints (lhsc, rhsc);
3713
                  VEC_free (ce_s, heap, lhsc);
3714
                  VEC_free (ce_s, heap, rhsc);
3715
                }
3716
              get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
3717
              get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
3718
              do_deref (&lhsc);
3719
              do_deref (&rhsc);
3720
              process_all_all_constraints (lhsc, rhsc);
3721
              VEC_free (ce_s, heap, lhsc);
3722
              VEC_free (ce_s, heap, rhsc);
3723
              return;
3724
            }
3725
          case BUILT_IN_MEMSET:
3726
            {
3727
              tree res = gimple_call_lhs (t);
3728
              tree dest = gimple_call_arg (t, 0);
3729
              unsigned i;
3730
              ce_s *lhsp;
3731
              struct constraint_expr ac;
3732
              if (res != NULL_TREE)
3733
                {
3734
                  get_constraint_for (res, &lhsc);
3735
                  get_constraint_for (dest, &rhsc);
3736
                  process_all_all_constraints (lhsc, rhsc);
3737
                  VEC_free (ce_s, heap, lhsc);
3738
                  VEC_free (ce_s, heap, rhsc);
3739
                }
3740
              get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
3741
              do_deref (&lhsc);
3742
              if (flag_delete_null_pointer_checks
3743
                  && integer_zerop (gimple_call_arg (t, 1)))
3744
                {
3745
                  ac.type = ADDRESSOF;
3746
                  ac.var = nothing_id;
3747
                }
3748
              else
3749
                {
3750
                  ac.type = SCALAR;
3751
                  ac.var = integer_id;
3752
                }
3753
              ac.offset = 0;
3754
              for (i = 0; VEC_iterate (ce_s, lhsc, i, lhsp); ++i)
3755
                process_constraint (new_constraint (*lhsp, ac));
3756
              VEC_free (ce_s, heap, lhsc);
3757
              return;
3758
            }
3759
          /* All the following functions do not return pointers, do not
3760
             modify the points-to sets of memory reachable from their
3761
             arguments and do not add to the ESCAPED solution.  */
3762
          case BUILT_IN_SINCOS:
3763
          case BUILT_IN_SINCOSF:
3764
          case BUILT_IN_SINCOSL:
3765
          case BUILT_IN_FREXP:
3766
          case BUILT_IN_FREXPF:
3767
          case BUILT_IN_FREXPL:
3768
          case BUILT_IN_GAMMA_R:
3769
          case BUILT_IN_GAMMAF_R:
3770
          case BUILT_IN_GAMMAL_R:
3771
          case BUILT_IN_LGAMMA_R:
3772
          case BUILT_IN_LGAMMAF_R:
3773
          case BUILT_IN_LGAMMAL_R:
3774
          case BUILT_IN_MODF:
3775
          case BUILT_IN_MODFF:
3776
          case BUILT_IN_MODFL:
3777
          case BUILT_IN_REMQUO:
3778
          case BUILT_IN_REMQUOF:
3779
          case BUILT_IN_REMQUOL:
3780
          case BUILT_IN_FREE:
3781
            return;
3782
          /* printf-style functions may have hooks to set pointers to
3783
             point to somewhere into the generated string.  Leave them
3784
             for a later excercise...  */
3785
          default:
3786
            /* Fallthru to general call handling.  */;
3787
          }
3788
      if (!in_ipa_mode
3789
          || (fndecl
3790
              && !lookup_vi_for_tree (fndecl)))
3791
        {
3792
          VEC(ce_s, heap) *rhsc = NULL;
3793
          int flags = gimple_call_flags (t);
3794
 
3795
          /* Const functions can return their arguments and addresses
3796
             of global memory but not of escaped memory.  */
3797
          if (flags & (ECF_CONST|ECF_NOVOPS))
3798
            {
3799
              if (gimple_call_lhs (t)
3800
                  && could_have_pointers (gimple_call_lhs (t)))
3801
                handle_const_call (t, &rhsc);
3802
            }
3803
          /* Pure functions can return addresses in and of memory
3804
             reachable from their arguments, but they are not an escape
3805
             point for reachable memory of their arguments.  */
3806
          else if (flags & (ECF_PURE|ECF_LOOPING_CONST_OR_PURE))
3807
            handle_pure_call (t, &rhsc);
3808
          else
3809
            handle_rhs_call (t, &rhsc);
3810
          if (gimple_call_lhs (t)
3811
              && could_have_pointers (gimple_call_lhs (t)))
3812
            handle_lhs_call (gimple_call_lhs (t), flags, rhsc, fndecl);
3813
          VEC_free (ce_s, heap, rhsc);
3814
        }
3815
      else
3816
        {
3817
          tree lhsop;
3818
          varinfo_t fi;
3819
          int i = 1;
3820
          size_t j;
3821
          tree decl;
3822
 
3823
          lhsop = gimple_call_lhs (t);
3824
          decl = gimple_call_fndecl (t);
3825
 
3826
          /* If we can directly resolve the function being called, do so.
3827
             Otherwise, it must be some sort of indirect expression that
3828
             we should still be able to handle.  */
3829
          if (decl)
3830
            fi = get_vi_for_tree (decl);
3831
          else
3832
            {
3833
              decl = gimple_call_fn (t);
3834
              fi = get_vi_for_tree (decl);
3835
            }
3836
 
3837
          /* Assign all the passed arguments to the appropriate incoming
3838
             parameters of the function.  */
3839
          for (j = 0; j < gimple_call_num_args (t); j++)
3840
            {
3841
              struct constraint_expr lhs ;
3842
              struct constraint_expr *rhsp;
3843
              tree arg = gimple_call_arg (t, j);
3844
 
3845
              get_constraint_for (arg, &rhsc);
3846
              if (TREE_CODE (decl) != FUNCTION_DECL)
3847
                {
3848
                  lhs.type = DEREF;
3849
                  lhs.var = fi->id;
3850
                  lhs.offset = i;
3851
                }
3852
              else
3853
                {
3854
                  lhs.type = SCALAR;
3855
                  lhs.var = first_vi_for_offset (fi, i)->id;
3856
                  lhs.offset = 0;
3857
                }
3858
              while (VEC_length (ce_s, rhsc) != 0)
3859
                {
3860
                  rhsp = VEC_last (ce_s, rhsc);
3861
                  process_constraint (new_constraint (lhs, *rhsp));
3862
                  VEC_pop (ce_s, rhsc);
3863
                }
3864
              i++;
3865
            }
3866
 
3867
          /* If we are returning a value, assign it to the result.  */
3868
          if (lhsop)
3869
            {
3870
              struct constraint_expr rhs;
3871
              struct constraint_expr *lhsp;
3872
              unsigned int j = 0;
3873
 
3874
              get_constraint_for (lhsop, &lhsc);
3875
              if (TREE_CODE (decl) != FUNCTION_DECL)
3876
                {
3877
                  rhs.type = DEREF;
3878
                  rhs.var = fi->id;
3879
                  rhs.offset = i;
3880
                }
3881
              else
3882
                {
3883
                  rhs.type = SCALAR;
3884
                  rhs.var = first_vi_for_offset (fi, i)->id;
3885
                  rhs.offset = 0;
3886
                }
3887
              for (j = 0; VEC_iterate (ce_s, lhsc, j, lhsp); j++)
3888
                process_constraint (new_constraint (*lhsp, rhs));
3889
            }
3890
        }
3891
    }
3892
  /* Otherwise, just a regular assignment statement.  Only care about
3893
     operations with pointer result, others are dealt with as escape
3894
     points if they have pointer operands.  */
3895
  else if (is_gimple_assign (t)
3896
           && type_could_have_pointers (TREE_TYPE (gimple_assign_lhs (t))))
3897
    {
3898
      /* Otherwise, just a regular assignment statement.  */
3899
      tree lhsop = gimple_assign_lhs (t);
3900
      tree rhsop = (gimple_num_ops (t) == 2) ? gimple_assign_rhs1 (t) : NULL;
3901
 
3902
      if (rhsop && AGGREGATE_TYPE_P (TREE_TYPE (lhsop)))
3903
        do_structure_copy (lhsop, rhsop);
3904
      else
3905
        {
3906
          struct constraint_expr temp;
3907
          get_constraint_for (lhsop, &lhsc);
3908
 
3909
          if (gimple_assign_rhs_code (t) == POINTER_PLUS_EXPR)
3910
            get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
3911
                                           gimple_assign_rhs2 (t), &rhsc);
3912
          else if ((CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (t))
3913
                    && !(POINTER_TYPE_P (gimple_expr_type (t))
3914
                         && !POINTER_TYPE_P (TREE_TYPE (rhsop))))
3915
                   || gimple_assign_single_p (t))
3916
            get_constraint_for (rhsop, &rhsc);
3917
          else
3918
            {
3919
              temp.type = ADDRESSOF;
3920
              temp.var = anything_id;
3921
              temp.offset = 0;
3922
              VEC_safe_push (ce_s, heap, rhsc, &temp);
3923
            }
3924
          process_all_all_constraints (lhsc, rhsc);
3925
        }
3926
      /* If there is a store to a global variable the rhs escapes.  */
3927
      if ((lhsop = get_base_address (lhsop)) != NULL_TREE
3928
          && DECL_P (lhsop)
3929
          && is_global_var (lhsop))
3930
        make_escape_constraint (rhsop);
3931
      /* If this is a conversion of a non-restrict pointer to a
3932
         restrict pointer track it with a new heapvar.  */
3933
      else if (gimple_assign_cast_p (t)
3934
               && POINTER_TYPE_P (TREE_TYPE (rhsop))
3935
               && POINTER_TYPE_P (TREE_TYPE (lhsop))
3936
               && !TYPE_RESTRICT (TREE_TYPE (rhsop))
3937
               && TYPE_RESTRICT (TREE_TYPE (lhsop)))
3938
        make_constraint_from_restrict (get_vi_for_tree (lhsop),
3939
                                       "CAST_RESTRICT");
3940
    }
3941
  /* For conversions of pointers to non-pointers the pointer escapes.  */
3942
  else if (gimple_assign_cast_p (t)
3943
           && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (t)))
3944
           && !POINTER_TYPE_P (TREE_TYPE (gimple_assign_lhs (t))))
3945
    {
3946
      make_escape_constraint (gimple_assign_rhs1 (t));
3947
    }
3948
  /* Handle escapes through return.  */
3949
  else if (gimple_code (t) == GIMPLE_RETURN
3950
           && gimple_return_retval (t) != NULL_TREE
3951
           && could_have_pointers (gimple_return_retval (t)))
3952
    {
3953
      make_escape_constraint (gimple_return_retval (t));
3954
    }
3955
  /* Handle asms conservatively by adding escape constraints to everything.  */
3956
  else if (gimple_code (t) == GIMPLE_ASM)
3957
    {
3958
      unsigned i, noutputs;
3959
      const char **oconstraints;
3960
      const char *constraint;
3961
      bool allows_mem, allows_reg, is_inout;
3962
 
3963
      noutputs = gimple_asm_noutputs (t);
3964
      oconstraints = XALLOCAVEC (const char *, noutputs);
3965
 
3966
      for (i = 0; i < noutputs; ++i)
3967
        {
3968
          tree link = gimple_asm_output_op (t, i);
3969
          tree op = TREE_VALUE (link);
3970
 
3971
          constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
3972
          oconstraints[i] = constraint;
3973
          parse_output_constraint (&constraint, i, 0, 0, &allows_mem,
3974
                                   &allows_reg, &is_inout);
3975
 
3976
          /* A memory constraint makes the address of the operand escape.  */
3977
          if (!allows_reg && allows_mem)
3978
            make_escape_constraint (build_fold_addr_expr (op));
3979
 
3980
          /* The asm may read global memory, so outputs may point to
3981
             any global memory.  */
3982
          if (op && could_have_pointers (op))
3983
            {
3984
              VEC(ce_s, heap) *lhsc = NULL;
3985
              struct constraint_expr rhsc, *lhsp;
3986
              unsigned j;
3987
              get_constraint_for (op, &lhsc);
3988
              rhsc.var = nonlocal_id;
3989
              rhsc.offset = 0;
3990
              rhsc.type = SCALAR;
3991
              for (j = 0; VEC_iterate (ce_s, lhsc, j, lhsp); j++)
3992
                process_constraint (new_constraint (*lhsp, rhsc));
3993
              VEC_free (ce_s, heap, lhsc);
3994
            }
3995
        }
3996
      for (i = 0; i < gimple_asm_ninputs (t); ++i)
3997
        {
3998
          tree link = gimple_asm_input_op (t, i);
3999
          tree op = TREE_VALUE (link);
4000
 
4001
          constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
4002
 
4003
          parse_input_constraint (&constraint, 0, 0, noutputs, 0, oconstraints,
4004
                                  &allows_mem, &allows_reg);
4005
 
4006
          /* A memory constraint makes the address of the operand escape.  */
4007
          if (!allows_reg && allows_mem)
4008
            make_escape_constraint (build_fold_addr_expr (op));
4009
          /* Strictly we'd only need the constraint to ESCAPED if
4010
             the asm clobbers memory, otherwise using CALLUSED
4011
             would be enough.  */
4012
          else if (op && could_have_pointers (op))
4013
            make_escape_constraint (op);
4014
        }
4015
    }
4016
 
4017
  VEC_free (ce_s, heap, rhsc);
4018
  VEC_free (ce_s, heap, lhsc);
4019
}
4020
 
4021
 
4022
/* Find the first varinfo in the same variable as START that overlaps with
4023
   OFFSET.  Return NULL if we can't find one.  */
4024
 
4025
static varinfo_t
4026
first_vi_for_offset (varinfo_t start, unsigned HOST_WIDE_INT offset)
4027
{
4028
  /* If the offset is outside of the variable, bail out.  */
4029
  if (offset >= start->fullsize)
4030
    return NULL;
4031
 
4032
  /* If we cannot reach offset from start, lookup the first field
4033
     and start from there.  */
4034
  if (start->offset > offset)
4035
    start = lookup_vi_for_tree (start->decl);
4036
 
4037
  while (start)
4038
    {
4039
      /* We may not find a variable in the field list with the actual
4040
         offset when when we have glommed a structure to a variable.
4041
         In that case, however, offset should still be within the size
4042
         of the variable. */
4043
      if (offset >= start->offset
4044
          && (offset - start->offset) < start->size)
4045
        return start;
4046
 
4047
      start= start->next;
4048
    }
4049
 
4050
  return NULL;
4051
}
4052
 
4053
/* Find the first varinfo in the same variable as START that overlaps with
4054
   OFFSET.  If there is no such varinfo the varinfo directly preceding
4055
   OFFSET is returned.  */
4056
 
4057
static varinfo_t
4058
first_or_preceding_vi_for_offset (varinfo_t start,
4059
                                  unsigned HOST_WIDE_INT offset)
4060
{
4061
  /* If we cannot reach offset from start, lookup the first field
4062
     and start from there.  */
4063
  if (start->offset > offset)
4064
    start = lookup_vi_for_tree (start->decl);
4065
 
4066
  /* We may not find a variable in the field list with the actual
4067
     offset when when we have glommed a structure to a variable.
4068
     In that case, however, offset should still be within the size
4069
     of the variable.
4070
     If we got beyond the offset we look for return the field
4071
     directly preceding offset which may be the last field.  */
4072
  while (start->next
4073
         && offset >= start->offset
4074
         && !((offset - start->offset) < start->size))
4075
    start = start->next;
4076
 
4077
  return start;
4078
}
4079
 
4080
 
4081
/* Insert the varinfo FIELD into the field list for BASE, at the front
4082
   of the list.  */
4083
 
4084
static void
4085
insert_into_field_list (varinfo_t base, varinfo_t field)
4086
{
4087
  varinfo_t prev = base;
4088
  varinfo_t curr = base->next;
4089
 
4090
  field->next = curr;
4091
  prev->next = field;
4092
}
4093
 
4094
/* Insert the varinfo FIELD into the field list for BASE, ordered by
4095
   offset.  */
4096
 
4097
static void
4098
insert_into_field_list_sorted (varinfo_t base, varinfo_t field)
4099
{
4100
  varinfo_t prev = base;
4101
  varinfo_t curr = base->next;
4102
 
4103
  if (curr == NULL)
4104
    {
4105
      prev->next = field;
4106
      field->next = NULL;
4107
    }
4108
  else
4109
    {
4110
      while (curr)
4111
        {
4112
          if (field->offset <= curr->offset)
4113
            break;
4114
          prev = curr;
4115
          curr = curr->next;
4116
        }
4117
      field->next = prev->next;
4118
      prev->next = field;
4119
    }
4120
}
4121
 
4122
/* This structure is used during pushing fields onto the fieldstack
4123
   to track the offset of the field, since bitpos_of_field gives it
4124
   relative to its immediate containing type, and we want it relative
4125
   to the ultimate containing object.  */
4126
 
4127
struct fieldoff
4128
{
4129
  /* Offset from the base of the base containing object to this field.  */
4130
  HOST_WIDE_INT offset;
4131
 
4132
  /* Size, in bits, of the field.  */
4133
  unsigned HOST_WIDE_INT size;
4134
 
4135
  unsigned has_unknown_size : 1;
4136
 
4137
  unsigned may_have_pointers : 1;
4138
 
4139
  unsigned only_restrict_pointers : 1;
4140
};
4141
typedef struct fieldoff fieldoff_s;
4142
 
4143
DEF_VEC_O(fieldoff_s);
4144
DEF_VEC_ALLOC_O(fieldoff_s,heap);
4145
 
4146
/* qsort comparison function for two fieldoff's PA and PB */
4147
 
4148
static int
4149
fieldoff_compare (const void *pa, const void *pb)
4150
{
4151
  const fieldoff_s *foa = (const fieldoff_s *)pa;
4152
  const fieldoff_s *fob = (const fieldoff_s *)pb;
4153
  unsigned HOST_WIDE_INT foasize, fobsize;
4154
 
4155
  if (foa->offset < fob->offset)
4156
    return -1;
4157
  else if (foa->offset > fob->offset)
4158
    return 1;
4159
 
4160
  foasize = foa->size;
4161
  fobsize = fob->size;
4162
  if (foasize < fobsize)
4163
    return -1;
4164
  else if (foasize > fobsize)
4165
    return 1;
4166
  return 0;
4167
}
4168
 
4169
/* Sort a fieldstack according to the field offset and sizes.  */
4170
static void
4171
sort_fieldstack (VEC(fieldoff_s,heap) *fieldstack)
4172
{
4173
  qsort (VEC_address (fieldoff_s, fieldstack),
4174
         VEC_length (fieldoff_s, fieldstack),
4175
         sizeof (fieldoff_s),
4176
         fieldoff_compare);
4177
}
4178
 
4179
/* Return true if V is a tree that we can have subvars for.
4180
   Normally, this is any aggregate type.  Also complex
4181
   types which are not gimple registers can have subvars.  */
4182
 
4183
static inline bool
4184
var_can_have_subvars (const_tree v)
4185
{
4186
  /* Volatile variables should never have subvars.  */
4187
  if (TREE_THIS_VOLATILE (v))
4188
    return false;
4189
 
4190
  /* Non decls or memory tags can never have subvars.  */
4191
  if (!DECL_P (v))
4192
    return false;
4193
 
4194
  /* Aggregates without overlapping fields can have subvars.  */
4195
  if (TREE_CODE (TREE_TYPE (v)) == RECORD_TYPE)
4196
    return true;
4197
 
4198
  return false;
4199
}
4200
 
4201
/* Given a TYPE, and a vector of field offsets FIELDSTACK, push all
4202
   the fields of TYPE onto fieldstack, recording their offsets along
4203
   the way.
4204
 
4205
   OFFSET is used to keep track of the offset in this entire
4206
   structure, rather than just the immediately containing structure.
4207
   Returns the number of fields pushed.  */
4208
 
4209
static int
4210
push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
4211
                             HOST_WIDE_INT offset, bool must_have_pointers_p)
4212
{
4213
  tree field;
4214
  int count = 0;
4215
 
4216
  if (TREE_CODE (type) != RECORD_TYPE)
4217
    return 0;
4218
 
4219
  /* If the vector of fields is growing too big, bail out early.
4220
     Callers check for VEC_length <= MAX_FIELDS_FOR_FIELD_SENSITIVE, make
4221
     sure this fails.  */
4222
  if (VEC_length (fieldoff_s, *fieldstack) > MAX_FIELDS_FOR_FIELD_SENSITIVE)
4223
    return 0;
4224
 
4225
  for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
4226
    if (TREE_CODE (field) == FIELD_DECL)
4227
      {
4228
        bool push = false;
4229
        int pushed = 0;
4230
        HOST_WIDE_INT foff = bitpos_of_field (field);
4231
 
4232
        if (!var_can_have_subvars (field)
4233
            || TREE_CODE (TREE_TYPE (field)) == QUAL_UNION_TYPE
4234
            || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
4235
          push = true;
4236
        else if (!(pushed = push_fields_onto_fieldstack
4237
                   (TREE_TYPE (field), fieldstack, offset + foff,
4238
                    must_have_pointers_p))
4239
                 && (DECL_SIZE (field)
4240
                     && !integer_zerop (DECL_SIZE (field))))
4241
          /* Empty structures may have actual size, like in C++.  So
4242
             see if we didn't push any subfields and the size is
4243
             nonzero, push the field onto the stack.  */
4244
          push = true;
4245
 
4246
        if (push)
4247
          {
4248
            fieldoff_s *pair = NULL;
4249
            bool has_unknown_size = false;
4250
 
4251
            if (!VEC_empty (fieldoff_s, *fieldstack))
4252
              pair = VEC_last (fieldoff_s, *fieldstack);
4253
 
4254
            if (!DECL_SIZE (field)
4255
                || !host_integerp (DECL_SIZE (field), 1))
4256
              has_unknown_size = true;
4257
 
4258
            /* If adjacent fields do not contain pointers merge them.  */
4259
            if (pair
4260
                && !pair->may_have_pointers
4261
                && !pair->has_unknown_size
4262
                && !has_unknown_size
4263
                && pair->offset + (HOST_WIDE_INT)pair->size == offset + foff
4264
                && !must_have_pointers_p
4265
                && !could_have_pointers (field))
4266
              {
4267
                pair = VEC_last (fieldoff_s, *fieldstack);
4268
                pair->size += TREE_INT_CST_LOW (DECL_SIZE (field));
4269
              }
4270
            else
4271
              {
4272
                pair = VEC_safe_push (fieldoff_s, heap, *fieldstack, NULL);
4273
                pair->offset = offset + foff;
4274
                pair->has_unknown_size = has_unknown_size;
4275
                if (!has_unknown_size)
4276
                  pair->size = TREE_INT_CST_LOW (DECL_SIZE (field));
4277
                else
4278
                  pair->size = -1;
4279
                pair->may_have_pointers
4280
                  = must_have_pointers_p || could_have_pointers (field);
4281
                pair->only_restrict_pointers
4282
                  = (!has_unknown_size
4283
                     && POINTER_TYPE_P (TREE_TYPE (field))
4284
                     && TYPE_RESTRICT (TREE_TYPE (field)));
4285
                count++;
4286
              }
4287
          }
4288
        else
4289
          count += pushed;
4290
      }
4291
 
4292
  return count;
4293
}
4294
 
4295
/* Count the number of arguments DECL has, and set IS_VARARGS to true
4296
   if it is a varargs function.  */
4297
 
4298
static unsigned int
4299
count_num_arguments (tree decl, bool *is_varargs)
4300
{
4301
  unsigned int num = 0;
4302
  tree t;
4303
 
4304
  /* Capture named arguments for K&R functions.  They do not
4305
     have a prototype and thus no TYPE_ARG_TYPES.  */
4306
  for (t = DECL_ARGUMENTS (decl); t; t = TREE_CHAIN (t))
4307
    ++num;
4308
 
4309
  /* Check if the function has variadic arguments.  */
4310
  for (t = TYPE_ARG_TYPES (TREE_TYPE (decl)); t; t = TREE_CHAIN (t))
4311
    if (TREE_VALUE (t) == void_type_node)
4312
      break;
4313
  if (!t)
4314
    *is_varargs = true;
4315
 
4316
  return num;
4317
}
4318
 
4319
/* Creation function node for DECL, using NAME, and return the index
4320
   of the variable we've created for the function.  */
4321
 
4322
static unsigned int
4323
create_function_info_for (tree decl, const char *name)
4324
{
4325
  varinfo_t vi;
4326
  tree arg;
4327
  unsigned int i;
4328
  bool is_varargs = false;
4329
 
4330
  /* Create the variable info.  */
4331
 
4332
  vi = new_var_info (decl, name);
4333
  vi->offset = 0;
4334
  vi->size = 1;
4335
  vi->fullsize = count_num_arguments (decl, &is_varargs) + 1;
4336
  insert_vi_for_tree (vi->decl, vi);
4337
 
4338
  stats.total_vars++;
4339
 
4340
  /* If it's varargs, we don't know how many arguments it has, so we
4341
     can't do much.  */
4342
  if (is_varargs)
4343
    {
4344
      vi->fullsize = ~0;
4345
      vi->size = ~0;
4346
      vi->is_unknown_size_var = true;
4347
      return vi->id;
4348
    }
4349
 
4350
  arg = DECL_ARGUMENTS (decl);
4351
 
4352
  /* Set up variables for each argument.  */
4353
  for (i = 1; i < vi->fullsize; i++)
4354
    {
4355
      varinfo_t argvi;
4356
      const char *newname;
4357
      char *tempname;
4358
      tree argdecl = decl;
4359
 
4360
      if (arg)
4361
        argdecl = arg;
4362
 
4363
      asprintf (&tempname, "%s.arg%d", name, i-1);
4364
      newname = ggc_strdup (tempname);
4365
      free (tempname);
4366
 
4367
      argvi = new_var_info (argdecl, newname);
4368
      argvi->offset = i;
4369
      argvi->size = 1;
4370
      argvi->is_full_var = true;
4371
      argvi->fullsize = vi->fullsize;
4372
      insert_into_field_list_sorted (vi, argvi);
4373
      stats.total_vars ++;
4374
      if (arg)
4375
        {
4376
          insert_vi_for_tree (arg, argvi);
4377
          arg = TREE_CHAIN (arg);
4378
        }
4379
    }
4380
 
4381
  /* Create a variable for the return var.  */
4382
  if (DECL_RESULT (decl) != NULL
4383
      || !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
4384
    {
4385
      varinfo_t resultvi;
4386
      const char *newname;
4387
      char *tempname;
4388
      tree resultdecl = decl;
4389
 
4390
      vi->fullsize ++;
4391
 
4392
      if (DECL_RESULT (decl))
4393
        resultdecl = DECL_RESULT (decl);
4394
 
4395
      asprintf (&tempname, "%s.result", name);
4396
      newname = ggc_strdup (tempname);
4397
      free (tempname);
4398
 
4399
      resultvi = new_var_info (resultdecl, newname);
4400
      resultvi->offset = i;
4401
      resultvi->size = 1;
4402
      resultvi->fullsize = vi->fullsize;
4403
      resultvi->is_full_var = true;
4404
      insert_into_field_list_sorted (vi, resultvi);
4405
      stats.total_vars ++;
4406
      if (DECL_RESULT (decl))
4407
        insert_vi_for_tree (DECL_RESULT (decl), resultvi);
4408
    }
4409
 
4410
  return vi->id;
4411
}
4412
 
4413
 
4414
/* Return true if FIELDSTACK contains fields that overlap.
4415
   FIELDSTACK is assumed to be sorted by offset.  */
4416
 
4417
static bool
4418
check_for_overlaps (VEC (fieldoff_s,heap) *fieldstack)
4419
{
4420
  fieldoff_s *fo = NULL;
4421
  unsigned int i;
4422
  HOST_WIDE_INT lastoffset = -1;
4423
 
4424
  for (i = 0; VEC_iterate (fieldoff_s, fieldstack, i, fo); i++)
4425
    {
4426
      if (fo->offset == lastoffset)
4427
        return true;
4428
      lastoffset = fo->offset;
4429
    }
4430
  return false;
4431
}
4432
 
4433
/* Create a varinfo structure for NAME and DECL, and add it to VARMAP.
4434
   This will also create any varinfo structures necessary for fields
4435
   of DECL.  */
4436
 
4437
static unsigned int
4438
create_variable_info_for (tree decl, const char *name)
4439
{
4440
  varinfo_t vi;
4441
  tree decl_type = TREE_TYPE (decl);
4442
  tree declsize = DECL_P (decl) ? DECL_SIZE (decl) : TYPE_SIZE (decl_type);
4443
  VEC (fieldoff_s,heap) *fieldstack = NULL;
4444
 
4445
  if (var_can_have_subvars (decl) && use_field_sensitive)
4446
    push_fields_onto_fieldstack (decl_type, &fieldstack, 0,
4447
                                 TREE_PUBLIC (decl)
4448
                                 || DECL_EXTERNAL (decl)
4449
                                 || TREE_ADDRESSABLE (decl));
4450
 
4451
  /* If the variable doesn't have subvars, we may end up needing to
4452
     sort the field list and create fake variables for all the
4453
     fields.  */
4454
  vi = new_var_info (decl, name);
4455
  vi->offset = 0;
4456
  vi->may_have_pointers = could_have_pointers (decl);
4457
  if (!declsize
4458
      || !host_integerp (declsize, 1))
4459
    {
4460
      vi->is_unknown_size_var = true;
4461
      vi->fullsize = ~0;
4462
      vi->size = ~0;
4463
    }
4464
  else
4465
    {
4466
      vi->fullsize = TREE_INT_CST_LOW (declsize);
4467
      vi->size = vi->fullsize;
4468
    }
4469
 
4470
  insert_vi_for_tree (vi->decl, vi);
4471
  if (vi->is_global_var
4472
      && (!flag_whole_program || !in_ipa_mode)
4473
      && vi->may_have_pointers)
4474
    {
4475
      if (POINTER_TYPE_P (TREE_TYPE (decl))
4476
          && TYPE_RESTRICT (TREE_TYPE (decl)))
4477
        make_constraint_from_restrict (vi, "GLOBAL_RESTRICT");
4478
      make_copy_constraint (vi, nonlocal_id);
4479
    }
4480
 
4481
  stats.total_vars++;
4482
  if (use_field_sensitive
4483
      && !vi->is_unknown_size_var
4484
      && var_can_have_subvars (decl)
4485
      && VEC_length (fieldoff_s, fieldstack) > 1
4486
      && VEC_length (fieldoff_s, fieldstack) <= MAX_FIELDS_FOR_FIELD_SENSITIVE)
4487
    {
4488
      fieldoff_s *fo = NULL;
4489
      bool notokay = false;
4490
      unsigned int i;
4491
 
4492
      for (i = 0; !notokay && VEC_iterate (fieldoff_s, fieldstack, i, fo); i++)
4493
        {
4494
          if (fo->has_unknown_size
4495
              || fo->offset < 0)
4496
            {
4497
              notokay = true;
4498
              break;
4499
            }
4500
        }
4501
 
4502
      /* We can't sort them if we have a field with a variable sized type,
4503
         which will make notokay = true.  In that case, we are going to return
4504
         without creating varinfos for the fields anyway, so sorting them is a
4505
         waste to boot.  */
4506
      if (!notokay)
4507
        {
4508
          sort_fieldstack (fieldstack);
4509
          /* Due to some C++ FE issues, like PR 22488, we might end up
4510
             what appear to be overlapping fields even though they,
4511
             in reality, do not overlap.  Until the C++ FE is fixed,
4512
             we will simply disable field-sensitivity for these cases.  */
4513
          notokay = check_for_overlaps (fieldstack);
4514
        }
4515
 
4516
 
4517
      if (VEC_length (fieldoff_s, fieldstack) != 0)
4518
        fo = VEC_index (fieldoff_s, fieldstack, 0);
4519
 
4520
      if (fo == NULL || notokay)
4521
        {
4522
          vi->is_unknown_size_var = 1;
4523
          vi->fullsize = ~0;
4524
          vi->size = ~0;
4525
          vi->is_full_var = true;
4526
          VEC_free (fieldoff_s, heap, fieldstack);
4527
          return vi->id;
4528
        }
4529
 
4530
      vi->size = fo->size;
4531
      vi->offset = fo->offset;
4532
      vi->may_have_pointers = fo->may_have_pointers;
4533
      if (vi->is_global_var
4534
          && (!flag_whole_program || !in_ipa_mode)
4535
          && vi->may_have_pointers)
4536
        {
4537
          if (fo->only_restrict_pointers)
4538
            make_constraint_from_restrict (vi, "GLOBAL_RESTRICT");
4539
        }
4540
      for (i = VEC_length (fieldoff_s, fieldstack) - 1;
4541
           i >= 1 && VEC_iterate (fieldoff_s, fieldstack, i, fo);
4542
           i--)
4543
        {
4544
          varinfo_t newvi;
4545
          const char *newname = "NULL";
4546
          char *tempname;
4547
 
4548
          if (dump_file)
4549
            {
4550
              asprintf (&tempname, "%s." HOST_WIDE_INT_PRINT_DEC
4551
                        "+" HOST_WIDE_INT_PRINT_DEC,
4552
                        vi->name, fo->offset, fo->size);
4553
              newname = ggc_strdup (tempname);
4554
              free (tempname);
4555
            }
4556
          newvi = new_var_info (decl, newname);
4557
          newvi->offset = fo->offset;
4558
          newvi->size = fo->size;
4559
          newvi->fullsize = vi->fullsize;
4560
          newvi->may_have_pointers = fo->may_have_pointers;
4561
          insert_into_field_list (vi, newvi);
4562
          if ((newvi->is_global_var || TREE_CODE (decl) == PARM_DECL)
4563
              && newvi->may_have_pointers)
4564
            {
4565
               if (fo->only_restrict_pointers)
4566
                 make_constraint_from_restrict (newvi, "GLOBAL_RESTRICT");
4567
               if (newvi->is_global_var && !in_ipa_mode)
4568
                 make_copy_constraint (newvi, nonlocal_id);
4569
            }
4570
 
4571
          stats.total_vars++;
4572
        }
4573
    }
4574
  else
4575
    vi->is_full_var = true;
4576
 
4577
  VEC_free (fieldoff_s, heap, fieldstack);
4578
 
4579
  return vi->id;
4580
}
4581
 
4582
/* Print out the points-to solution for VAR to FILE.  */
4583
 
4584
static void
4585
dump_solution_for_var (FILE *file, unsigned int var)
4586
{
4587
  varinfo_t vi = get_varinfo (var);
4588
  unsigned int i;
4589
  bitmap_iterator bi;
4590
 
4591
  if (find (var) != var)
4592
    {
4593
      varinfo_t vipt = get_varinfo (find (var));
4594
      fprintf (file, "%s = same as %s\n", vi->name, vipt->name);
4595
    }
4596
  else
4597
    {
4598
      fprintf (file, "%s = { ", vi->name);
4599
      EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, i, bi)
4600
        {
4601
          fprintf (file, "%s ", get_varinfo (i)->name);
4602
        }
4603
      fprintf (file, "}\n");
4604
    }
4605
}
4606
 
4607
/* Print the points-to solution for VAR to stdout.  */
4608
 
4609
void
4610
debug_solution_for_var (unsigned int var)
4611
{
4612
  dump_solution_for_var (stdout, var);
4613
}
4614
 
4615
/* Create varinfo structures for all of the variables in the
4616
   function for intraprocedural mode.  */
4617
 
4618
static void
4619
intra_create_variable_infos (void)
4620
{
4621
  tree t;
4622
 
4623
  /* For each incoming pointer argument arg, create the constraint ARG
4624
     = NONLOCAL or a dummy variable if flag_argument_noalias is set.  */
4625
  for (t = DECL_ARGUMENTS (current_function_decl); t; t = TREE_CHAIN (t))
4626
    {
4627
      varinfo_t p;
4628
 
4629
      if (!could_have_pointers (t))
4630
        continue;
4631
 
4632
      /* For restrict qualified pointers to objects passed by
4633
         reference build a real representative for the pointed-to object.  */
4634
      if (DECL_BY_REFERENCE (t)
4635
          && POINTER_TYPE_P (TREE_TYPE (t))
4636
          && TYPE_RESTRICT (TREE_TYPE (t)))
4637
        {
4638
          struct constraint_expr lhsc, rhsc;
4639
          varinfo_t vi;
4640
          tree heapvar = heapvar_lookup (t, 0);
4641
          if (heapvar == NULL_TREE)
4642
            {
4643
              var_ann_t ann;
4644
              heapvar = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (t)),
4645
                                            "PARM_NOALIAS");
4646
              DECL_EXTERNAL (heapvar) = 1;
4647
              heapvar_insert (t, 0, heapvar);
4648
              ann = get_var_ann (heapvar);
4649
              ann->is_heapvar = 1;
4650
            }
4651
          if (gimple_referenced_vars (cfun))
4652
            add_referenced_var (heapvar);
4653
          lhsc.var = get_vi_for_tree (t)->id;
4654
          lhsc.type = SCALAR;
4655
          lhsc.offset = 0;
4656
          rhsc.var = (vi = get_vi_for_tree (heapvar))->id;
4657
          rhsc.type = ADDRESSOF;
4658
          rhsc.offset = 0;
4659
          process_constraint (new_constraint (lhsc, rhsc));
4660
          vi->is_restrict_var = 1;
4661
          continue;
4662
        }
4663
 
4664
      for (p = get_vi_for_tree (t); p; p = p->next)
4665
        if (p->may_have_pointers)
4666
          make_constraint_from (p, nonlocal_id);
4667
      if (POINTER_TYPE_P (TREE_TYPE (t))
4668
          && TYPE_RESTRICT (TREE_TYPE (t)))
4669
        make_constraint_from_restrict (get_vi_for_tree (t), "PARM_RESTRICT");
4670
    }
4671
 
4672
  /* Add a constraint for a result decl that is passed by reference.  */
4673
  if (DECL_RESULT (cfun->decl)
4674
      && DECL_BY_REFERENCE (DECL_RESULT (cfun->decl)))
4675
    {
4676
      varinfo_t p, result_vi = get_vi_for_tree (DECL_RESULT (cfun->decl));
4677
 
4678
      for (p = result_vi; p; p = p->next)
4679
        make_constraint_from (p, nonlocal_id);
4680
    }
4681
 
4682
  /* Add a constraint for the incoming static chain parameter.  */
4683
  if (cfun->static_chain_decl != NULL_TREE)
4684
    {
4685
      varinfo_t p, chain_vi = get_vi_for_tree (cfun->static_chain_decl);
4686
 
4687
      for (p = chain_vi; p; p = p->next)
4688
        make_constraint_from (p, nonlocal_id);
4689
    }
4690
}
4691
 
4692
/* Structure used to put solution bitmaps in a hashtable so they can
4693
   be shared among variables with the same points-to set.  */
4694
 
4695
typedef struct shared_bitmap_info
4696
{
4697
  bitmap pt_vars;
4698
  hashval_t hashcode;
4699
} *shared_bitmap_info_t;
4700
typedef const struct shared_bitmap_info *const_shared_bitmap_info_t;
4701
 
4702
static htab_t shared_bitmap_table;
4703
 
4704
/* Hash function for a shared_bitmap_info_t */
4705
 
4706
static hashval_t
4707
shared_bitmap_hash (const void *p)
4708
{
4709
  const_shared_bitmap_info_t const bi = (const_shared_bitmap_info_t) p;
4710
  return bi->hashcode;
4711
}
4712
 
4713
/* Equality function for two shared_bitmap_info_t's. */
4714
 
4715
static int
4716
shared_bitmap_eq (const void *p1, const void *p2)
4717
{
4718
  const_shared_bitmap_info_t const sbi1 = (const_shared_bitmap_info_t) p1;
4719
  const_shared_bitmap_info_t const sbi2 = (const_shared_bitmap_info_t) p2;
4720
  return bitmap_equal_p (sbi1->pt_vars, sbi2->pt_vars);
4721
}
4722
 
4723
/* Lookup a bitmap in the shared bitmap hashtable, and return an already
4724
   existing instance if there is one, NULL otherwise.  */
4725
 
4726
static bitmap
4727
shared_bitmap_lookup (bitmap pt_vars)
4728
{
4729
  void **slot;
4730
  struct shared_bitmap_info sbi;
4731
 
4732
  sbi.pt_vars = pt_vars;
4733
  sbi.hashcode = bitmap_hash (pt_vars);
4734
 
4735
  slot = htab_find_slot_with_hash (shared_bitmap_table, &sbi,
4736
                                   sbi.hashcode, NO_INSERT);
4737
  if (!slot)
4738
    return NULL;
4739
  else
4740
    return ((shared_bitmap_info_t) *slot)->pt_vars;
4741
}
4742
 
4743
 
4744
/* Add a bitmap to the shared bitmap hashtable.  */
4745
 
4746
static void
4747
shared_bitmap_add (bitmap pt_vars)
4748
{
4749
  void **slot;
4750
  shared_bitmap_info_t sbi = XNEW (struct shared_bitmap_info);
4751
 
4752
  sbi->pt_vars = pt_vars;
4753
  sbi->hashcode = bitmap_hash (pt_vars);
4754
 
4755
  slot = htab_find_slot_with_hash (shared_bitmap_table, sbi,
4756
                                   sbi->hashcode, INSERT);
4757
  gcc_assert (!*slot);
4758
  *slot = (void *) sbi;
4759
}
4760
 
4761
 
4762
/* Set bits in INTO corresponding to the variable uids in solution set FROM.  */
4763
 
4764
static void
4765
set_uids_in_ptset (bitmap into, bitmap from, struct pt_solution *pt)
4766
{
4767
  unsigned int i;
4768
  bitmap_iterator bi;
4769
 
4770
  EXECUTE_IF_SET_IN_BITMAP (from, 0, i, bi)
4771
    {
4772
      varinfo_t vi = get_varinfo (i);
4773
 
4774
      /* The only artificial variables that are allowed in a may-alias
4775
         set are heap variables.  */
4776
      if (vi->is_artificial_var && !vi->is_heap_var)
4777
        continue;
4778
 
4779
      if (TREE_CODE (vi->decl) == VAR_DECL
4780
          || TREE_CODE (vi->decl) == PARM_DECL
4781
          || TREE_CODE (vi->decl) == RESULT_DECL)
4782
        {
4783
          /* Add the decl to the points-to set.  Note that the points-to
4784
             set contains global variables.  */
4785
          bitmap_set_bit (into, DECL_UID (vi->decl));
4786
          if (vi->is_global_var)
4787
            pt->vars_contains_global = true;
4788
        }
4789
    }
4790
}
4791
 
4792
 
4793
/* Compute the points-to solution *PT for the variable VI.  */
4794
 
4795
static void
4796
find_what_var_points_to (varinfo_t orig_vi, struct pt_solution *pt)
4797
{
4798
  unsigned int i;
4799
  bitmap_iterator bi;
4800
  bitmap finished_solution;
4801
  bitmap result;
4802
  varinfo_t vi;
4803
 
4804
  memset (pt, 0, sizeof (struct pt_solution));
4805
 
4806
  /* This variable may have been collapsed, let's get the real
4807
     variable.  */
4808
  vi = get_varinfo (find (orig_vi->id));
4809
 
4810
  /* Translate artificial variables into SSA_NAME_PTR_INFO
4811
     attributes.  */
4812
  EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, i, bi)
4813
    {
4814
      varinfo_t vi = get_varinfo (i);
4815
 
4816
      if (vi->is_artificial_var)
4817
        {
4818
          if (vi->id == nothing_id)
4819
            pt->null = 1;
4820
          else if (vi->id == escaped_id)
4821
            pt->escaped = 1;
4822
          else if (vi->id == callused_id)
4823
            gcc_unreachable ();
4824
          else if (vi->id == nonlocal_id)
4825
            pt->nonlocal = 1;
4826
          else if (vi->is_heap_var)
4827
            /* We represent heapvars in the points-to set properly.  */
4828
            ;
4829
          else if (vi->id == readonly_id)
4830
            /* Nobody cares.  */
4831
            ;
4832
          else if (vi->id == anything_id
4833
                   || vi->id == integer_id)
4834
            pt->anything = 1;
4835
        }
4836
      if (vi->is_restrict_var)
4837
        pt->vars_contains_restrict = true;
4838
    }
4839
 
4840
  /* Instead of doing extra work, simply do not create
4841
     elaborate points-to information for pt_anything pointers.  */
4842
  if (pt->anything
4843
      && (orig_vi->is_artificial_var
4844
          || !pt->vars_contains_restrict))
4845
    return;
4846
 
4847
  /* Share the final set of variables when possible.  */
4848
  finished_solution = BITMAP_GGC_ALLOC ();
4849
  stats.points_to_sets_created++;
4850
 
4851
  set_uids_in_ptset (finished_solution, vi->solution, pt);
4852
  result = shared_bitmap_lookup (finished_solution);
4853
  if (!result)
4854
    {
4855
      shared_bitmap_add (finished_solution);
4856
      pt->vars = finished_solution;
4857
    }
4858
  else
4859
    {
4860
      pt->vars = result;
4861
      bitmap_clear (finished_solution);
4862
    }
4863
}
4864
 
4865
/* Given a pointer variable P, fill in its points-to set.  */
4866
 
4867
static void
4868
find_what_p_points_to (tree p)
4869
{
4870
  struct ptr_info_def *pi;
4871
  tree lookup_p = p;
4872
  varinfo_t vi;
4873
 
4874
  /* For parameters, get at the points-to set for the actual parm
4875
     decl.  */
4876
  if (TREE_CODE (p) == SSA_NAME
4877
      && TREE_CODE (SSA_NAME_VAR (p)) == PARM_DECL
4878
      && SSA_NAME_IS_DEFAULT_DEF (p))
4879
    lookup_p = SSA_NAME_VAR (p);
4880
 
4881
  vi = lookup_vi_for_tree (lookup_p);
4882
  if (!vi)
4883
    return;
4884
 
4885
  pi = get_ptr_info (p);
4886
  find_what_var_points_to (vi, &pi->pt);
4887
}
4888
 
4889
 
4890
/* Query statistics for points-to solutions.  */
4891
 
4892
static struct {
4893
  unsigned HOST_WIDE_INT pt_solution_includes_may_alias;
4894
  unsigned HOST_WIDE_INT pt_solution_includes_no_alias;
4895
  unsigned HOST_WIDE_INT pt_solutions_intersect_may_alias;
4896
  unsigned HOST_WIDE_INT pt_solutions_intersect_no_alias;
4897
} pta_stats;
4898
 
4899
void
4900
dump_pta_stats (FILE *s)
4901
{
4902
  fprintf (s, "\nPTA query stats:\n");
4903
  fprintf (s, "  pt_solution_includes: "
4904
           HOST_WIDE_INT_PRINT_DEC" disambiguations, "
4905
           HOST_WIDE_INT_PRINT_DEC" queries\n",
4906
           pta_stats.pt_solution_includes_no_alias,
4907
           pta_stats.pt_solution_includes_no_alias
4908
           + pta_stats.pt_solution_includes_may_alias);
4909
  fprintf (s, "  pt_solutions_intersect: "
4910
           HOST_WIDE_INT_PRINT_DEC" disambiguations, "
4911
           HOST_WIDE_INT_PRINT_DEC" queries\n",
4912
           pta_stats.pt_solutions_intersect_no_alias,
4913
           pta_stats.pt_solutions_intersect_no_alias
4914
           + pta_stats.pt_solutions_intersect_may_alias);
4915
}
4916
 
4917
 
4918
/* Reset the points-to solution *PT to a conservative default
4919
   (point to anything).  */
4920
 
4921
void
4922
pt_solution_reset (struct pt_solution *pt)
4923
{
4924
  memset (pt, 0, sizeof (struct pt_solution));
4925
  pt->anything = true;
4926
}
4927
 
4928
/* Set the points-to solution *PT to point only to the variables
4929
   in VARS.  */
4930
 
4931
void
4932
pt_solution_set (struct pt_solution *pt, bitmap vars)
4933
{
4934
  bitmap_iterator bi;
4935
  unsigned i;
4936
 
4937
  memset (pt, 0, sizeof (struct pt_solution));
4938
  pt->vars = vars;
4939
  EXECUTE_IF_SET_IN_BITMAP (vars, 0, i, bi)
4940
    {
4941
      tree var = referenced_var_lookup (i);
4942
      if (is_global_var (var))
4943
        {
4944
          pt->vars_contains_global = true;
4945
          break;
4946
        }
4947
    }
4948
}
4949
 
4950
/* Return true if the points-to solution *PT is empty.  */
4951
 
4952
static bool
4953
pt_solution_empty_p (struct pt_solution *pt)
4954
{
4955
  if (pt->anything
4956
      || pt->nonlocal)
4957
    return false;
4958
 
4959
  if (pt->vars
4960
      && !bitmap_empty_p (pt->vars))
4961
    return false;
4962
 
4963
  /* If the solution includes ESCAPED, check if that is empty.  */
4964
  if (pt->escaped
4965
      && !pt_solution_empty_p (&cfun->gimple_df->escaped))
4966
    return false;
4967
 
4968
  return true;
4969
}
4970
 
4971
/* Return true if the points-to solution *PT includes global memory.  */
4972
 
4973
bool
4974
pt_solution_includes_global (struct pt_solution *pt)
4975
{
4976
  if (pt->anything
4977
      || pt->nonlocal
4978
      || pt->vars_contains_global)
4979
    return true;
4980
 
4981
  if (pt->escaped)
4982
    return pt_solution_includes_global (&cfun->gimple_df->escaped);
4983
 
4984
  return false;
4985
}
4986
 
4987
/* Return true if the points-to solution *PT includes the variable
4988
   declaration DECL.  */
4989
 
4990
static bool
4991
pt_solution_includes_1 (struct pt_solution *pt, const_tree decl)
4992
{
4993
  if (pt->anything)
4994
    return true;
4995
 
4996
  if (pt->nonlocal
4997
      && is_global_var (decl))
4998
    return true;
4999
 
5000
  if (pt->vars
5001
      && bitmap_bit_p (pt->vars, DECL_UID (decl)))
5002
    return true;
5003
 
5004
  /* If the solution includes ESCAPED, check it.  */
5005
  if (pt->escaped
5006
      && pt_solution_includes_1 (&cfun->gimple_df->escaped, decl))
5007
    return true;
5008
 
5009
  return false;
5010
}
5011
 
5012
bool
5013
pt_solution_includes (struct pt_solution *pt, const_tree decl)
5014
{
5015
  bool res = pt_solution_includes_1 (pt, decl);
5016
  if (res)
5017
    ++pta_stats.pt_solution_includes_may_alias;
5018
  else
5019
    ++pta_stats.pt_solution_includes_no_alias;
5020
  return res;
5021
}
5022
 
5023
/* Return true if both points-to solutions PT1 and PT2 have a non-empty
5024
   intersection.  */
5025
 
5026
static bool
5027
pt_solutions_intersect_1 (struct pt_solution *pt1, struct pt_solution *pt2)
5028
{
5029
  if (pt1->anything || pt2->anything)
5030
    return true;
5031
 
5032
  /* If either points to unknown global memory and the other points to
5033
     any global memory they alias.  */
5034
  if ((pt1->nonlocal
5035
       && (pt2->nonlocal
5036
           || pt2->vars_contains_global))
5037
      || (pt2->nonlocal
5038
          && pt1->vars_contains_global))
5039
    return true;
5040
 
5041
  /* Check the escaped solution if required.  */
5042
  if ((pt1->escaped || pt2->escaped)
5043
      && !pt_solution_empty_p (&cfun->gimple_df->escaped))
5044
    {
5045
      /* If both point to escaped memory and that solution
5046
         is not empty they alias.  */
5047
      if (pt1->escaped && pt2->escaped)
5048
        return true;
5049
 
5050
      /* If either points to escaped memory see if the escaped solution
5051
         intersects with the other.  */
5052
      if ((pt1->escaped
5053
           && pt_solutions_intersect_1 (&cfun->gimple_df->escaped, pt2))
5054
          || (pt2->escaped
5055
              && pt_solutions_intersect_1 (&cfun->gimple_df->escaped, pt1)))
5056
        return true;
5057
    }
5058
 
5059
  /* Now both pointers alias if their points-to solution intersects.  */
5060
  return (pt1->vars
5061
          && pt2->vars
5062
          && bitmap_intersect_p (pt1->vars, pt2->vars));
5063
}
5064
 
5065
bool
5066
pt_solutions_intersect (struct pt_solution *pt1, struct pt_solution *pt2)
5067
{
5068
  bool res = pt_solutions_intersect_1 (pt1, pt2);
5069
  if (res)
5070
    ++pta_stats.pt_solutions_intersect_may_alias;
5071
  else
5072
    ++pta_stats.pt_solutions_intersect_no_alias;
5073
  return res;
5074
}
5075
 
5076
/* Return true if both points-to solutions PT1 and PT2 for two restrict
5077
   qualified pointers are possibly based on the same pointer.  */
5078
 
5079
bool
5080
pt_solutions_same_restrict_base (struct pt_solution *pt1,
5081
                                 struct pt_solution *pt2)
5082
{
5083
  /* If we deal with points-to solutions of two restrict qualified
5084
     pointers solely rely on the pointed-to variable bitmap intersection.
5085
     For two pointers that are based on each other the bitmaps will
5086
     intersect.  */
5087
  if (pt1->vars_contains_restrict
5088
      && pt2->vars_contains_restrict)
5089
    {
5090
      gcc_assert (pt1->vars && pt2->vars);
5091
      return bitmap_intersect_p (pt1->vars, pt2->vars);
5092
    }
5093
 
5094
  return true;
5095
}
5096
 
5097
 
5098
/* Dump points-to information to OUTFILE.  */
5099
 
5100
static void
5101
dump_sa_points_to_info (FILE *outfile)
5102
{
5103
  unsigned int i;
5104
 
5105
  fprintf (outfile, "\nPoints-to sets\n\n");
5106
 
5107
  if (dump_flags & TDF_STATS)
5108
    {
5109
      fprintf (outfile, "Stats:\n");
5110
      fprintf (outfile, "Total vars:               %d\n", stats.total_vars);
5111
      fprintf (outfile, "Non-pointer vars:          %d\n",
5112
               stats.nonpointer_vars);
5113
      fprintf (outfile, "Statically unified vars:  %d\n",
5114
               stats.unified_vars_static);
5115
      fprintf (outfile, "Dynamically unified vars: %d\n",
5116
               stats.unified_vars_dynamic);
5117
      fprintf (outfile, "Iterations:               %d\n", stats.iterations);
5118
      fprintf (outfile, "Number of edges:          %d\n", stats.num_edges);
5119
      fprintf (outfile, "Number of implicit edges: %d\n",
5120
               stats.num_implicit_edges);
5121
    }
5122
 
5123
  for (i = 0; i < VEC_length (varinfo_t, varmap); i++)
5124
    dump_solution_for_var (outfile, i);
5125
}
5126
 
5127
 
5128
/* Debug points-to information to stderr.  */
5129
 
5130
void
5131
debug_sa_points_to_info (void)
5132
{
5133
  dump_sa_points_to_info (stderr);
5134
}
5135
 
5136
 
5137
/* Initialize the always-existing constraint variables for NULL
5138
   ANYTHING, READONLY, and INTEGER */
5139
 
5140
static void
5141
init_base_vars (void)
5142
{
5143
  struct constraint_expr lhs, rhs;
5144
  varinfo_t var_anything;
5145
  varinfo_t var_nothing;
5146
  varinfo_t var_readonly;
5147
  varinfo_t var_escaped;
5148
  varinfo_t var_nonlocal;
5149
  varinfo_t var_callused;
5150
  varinfo_t var_storedanything;
5151
  varinfo_t var_integer;
5152
 
5153
  /* Create the NULL variable, used to represent that a variable points
5154
     to NULL.  */
5155
  var_nothing = new_var_info (NULL_TREE, "NULL");
5156
  gcc_assert (var_nothing->id == nothing_id);
5157
  var_nothing->is_artificial_var = 1;
5158
  var_nothing->offset = 0;
5159
  var_nothing->size = ~0;
5160
  var_nothing->fullsize = ~0;
5161
  var_nothing->is_special_var = 1;
5162
 
5163
  /* Create the ANYTHING variable, used to represent that a variable
5164
     points to some unknown piece of memory.  */
5165
  var_anything = new_var_info (NULL_TREE, "ANYTHING");
5166
  gcc_assert (var_anything->id == anything_id);
5167
  var_anything->is_artificial_var = 1;
5168
  var_anything->size = ~0;
5169
  var_anything->offset = 0;
5170
  var_anything->next = NULL;
5171
  var_anything->fullsize = ~0;
5172
  var_anything->is_special_var = 1;
5173
 
5174
  /* Anything points to anything.  This makes deref constraints just
5175
     work in the presence of linked list and other p = *p type loops,
5176
     by saying that *ANYTHING = ANYTHING. */
5177
  lhs.type = SCALAR;
5178
  lhs.var = anything_id;
5179
  lhs.offset = 0;
5180
  rhs.type = ADDRESSOF;
5181
  rhs.var = anything_id;
5182
  rhs.offset = 0;
5183
 
5184
  /* This specifically does not use process_constraint because
5185
     process_constraint ignores all anything = anything constraints, since all
5186
     but this one are redundant.  */
5187
  VEC_safe_push (constraint_t, heap, constraints, new_constraint (lhs, rhs));
5188
 
5189
  /* Create the READONLY variable, used to represent that a variable
5190
     points to readonly memory.  */
5191
  var_readonly = new_var_info (NULL_TREE, "READONLY");
5192
  gcc_assert (var_readonly->id == readonly_id);
5193
  var_readonly->is_artificial_var = 1;
5194
  var_readonly->offset = 0;
5195
  var_readonly->size = ~0;
5196
  var_readonly->fullsize = ~0;
5197
  var_readonly->next = NULL;
5198
  var_readonly->is_special_var = 1;
5199
 
5200
  /* readonly memory points to anything, in order to make deref
5201
     easier.  In reality, it points to anything the particular
5202
     readonly variable can point to, but we don't track this
5203
     separately. */
5204
  lhs.type = SCALAR;
5205
  lhs.var = readonly_id;
5206
  lhs.offset = 0;
5207
  rhs.type = ADDRESSOF;
5208
  rhs.var = readonly_id;  /* FIXME */
5209
  rhs.offset = 0;
5210
  process_constraint (new_constraint (lhs, rhs));
5211
 
5212
  /* Create the ESCAPED variable, used to represent the set of escaped
5213
     memory.  */
5214
  var_escaped = new_var_info (NULL_TREE, "ESCAPED");
5215
  gcc_assert (var_escaped->id == escaped_id);
5216
  var_escaped->is_artificial_var = 1;
5217
  var_escaped->offset = 0;
5218
  var_escaped->size = ~0;
5219
  var_escaped->fullsize = ~0;
5220
  var_escaped->is_special_var = 0;
5221
 
5222
  /* Create the NONLOCAL variable, used to represent the set of nonlocal
5223
     memory.  */
5224
  var_nonlocal = new_var_info (NULL_TREE, "NONLOCAL");
5225
  gcc_assert (var_nonlocal->id == nonlocal_id);
5226
  var_nonlocal->is_artificial_var = 1;
5227
  var_nonlocal->offset = 0;
5228
  var_nonlocal->size = ~0;
5229
  var_nonlocal->fullsize = ~0;
5230
  var_nonlocal->is_special_var = 1;
5231
 
5232
  /* ESCAPED = *ESCAPED, because escaped is may-deref'd at calls, etc.  */
5233
  lhs.type = SCALAR;
5234
  lhs.var = escaped_id;
5235
  lhs.offset = 0;
5236
  rhs.type = DEREF;
5237
  rhs.var = escaped_id;
5238
  rhs.offset = 0;
5239
  process_constraint (new_constraint (lhs, rhs));
5240
 
5241
  /* ESCAPED = ESCAPED + UNKNOWN_OFFSET, because if a sub-field escapes the
5242
     whole variable escapes.  */
5243
  lhs.type = SCALAR;
5244
  lhs.var = escaped_id;
5245
  lhs.offset = 0;
5246
  rhs.type = SCALAR;
5247
  rhs.var = escaped_id;
5248
  rhs.offset = UNKNOWN_OFFSET;
5249
  process_constraint (new_constraint (lhs, rhs));
5250
 
5251
  /* *ESCAPED = NONLOCAL.  This is true because we have to assume
5252
     everything pointed to by escaped points to what global memory can
5253
     point to.  */
5254
  lhs.type = DEREF;
5255
  lhs.var = escaped_id;
5256
  lhs.offset = 0;
5257
  rhs.type = SCALAR;
5258
  rhs.var = nonlocal_id;
5259
  rhs.offset = 0;
5260
  process_constraint (new_constraint (lhs, rhs));
5261
 
5262
  /* NONLOCAL = &NONLOCAL, NONLOCAL = &ESCAPED.  This is true because
5263
     global memory may point to global memory and escaped memory.  */
5264
  lhs.type = SCALAR;
5265
  lhs.var = nonlocal_id;
5266
  lhs.offset = 0;
5267
  rhs.type = ADDRESSOF;
5268
  rhs.var = nonlocal_id;
5269
  rhs.offset = 0;
5270
  process_constraint (new_constraint (lhs, rhs));
5271
  rhs.type = ADDRESSOF;
5272
  rhs.var = escaped_id;
5273
  rhs.offset = 0;
5274
  process_constraint (new_constraint (lhs, rhs));
5275
 
5276
  /* Create the CALLUSED variable, used to represent the set of call-used
5277
     memory.  */
5278
  var_callused = new_var_info (NULL_TREE, "CALLUSED");
5279
  gcc_assert (var_callused->id == callused_id);
5280
  var_callused->is_artificial_var = 1;
5281
  var_callused->offset = 0;
5282
  var_callused->size = ~0;
5283
  var_callused->fullsize = ~0;
5284
  var_callused->is_special_var = 0;
5285
 
5286
  /* CALLUSED = *CALLUSED, because call-used is may-deref'd at calls, etc.  */
5287
  lhs.type = SCALAR;
5288
  lhs.var = callused_id;
5289
  lhs.offset = 0;
5290
  rhs.type = DEREF;
5291
  rhs.var = callused_id;
5292
  rhs.offset = 0;
5293
  process_constraint (new_constraint (lhs, rhs));
5294
 
5295
  /* CALLUSED = CALLUSED + UNKNOWN, because if a sub-field is call-used the
5296
     whole variable is call-used.  */
5297
  lhs.type = SCALAR;
5298
  lhs.var = callused_id;
5299
  lhs.offset = 0;
5300
  rhs.type = SCALAR;
5301
  rhs.var = callused_id;
5302
  rhs.offset = UNKNOWN_OFFSET;
5303
  process_constraint (new_constraint (lhs, rhs));
5304
 
5305
  /* Create the STOREDANYTHING variable, used to represent the set of
5306
     variables stored to *ANYTHING.  */
5307
  var_storedanything = new_var_info (NULL_TREE, "STOREDANYTHING");
5308
  gcc_assert (var_storedanything->id == storedanything_id);
5309
  var_storedanything->is_artificial_var = 1;
5310
  var_storedanything->offset = 0;
5311
  var_storedanything->size = ~0;
5312
  var_storedanything->fullsize = ~0;
5313
  var_storedanything->is_special_var = 0;
5314
 
5315
  /* Create the INTEGER variable, used to represent that a variable points
5316
     to what an INTEGER "points to".  */
5317
  var_integer = new_var_info (NULL_TREE, "INTEGER");
5318
  gcc_assert (var_integer->id == integer_id);
5319
  var_integer->is_artificial_var = 1;
5320
  var_integer->size = ~0;
5321
  var_integer->fullsize = ~0;
5322
  var_integer->offset = 0;
5323
  var_integer->next = NULL;
5324
  var_integer->is_special_var = 1;
5325
 
5326
  /* INTEGER = ANYTHING, because we don't know where a dereference of
5327
     a random integer will point to.  */
5328
  lhs.type = SCALAR;
5329
  lhs.var = integer_id;
5330
  lhs.offset = 0;
5331
  rhs.type = ADDRESSOF;
5332
  rhs.var = anything_id;
5333
  rhs.offset = 0;
5334
  process_constraint (new_constraint (lhs, rhs));
5335
}
5336
 
5337
/* Initialize things necessary to perform PTA */
5338
 
5339
static void
5340
init_alias_vars (void)
5341
{
5342
  use_field_sensitive = (MAX_FIELDS_FOR_FIELD_SENSITIVE > 1);
5343
 
5344
  bitmap_obstack_initialize (&pta_obstack);
5345
  bitmap_obstack_initialize (&oldpta_obstack);
5346
  bitmap_obstack_initialize (&predbitmap_obstack);
5347
 
5348
  constraint_pool = create_alloc_pool ("Constraint pool",
5349
                                       sizeof (struct constraint), 30);
5350
  variable_info_pool = create_alloc_pool ("Variable info pool",
5351
                                          sizeof (struct variable_info), 30);
5352
  constraints = VEC_alloc (constraint_t, heap, 8);
5353
  varmap = VEC_alloc (varinfo_t, heap, 8);
5354
  vi_for_tree = pointer_map_create ();
5355
 
5356
  memset (&stats, 0, sizeof (stats));
5357
  shared_bitmap_table = htab_create (511, shared_bitmap_hash,
5358
                                     shared_bitmap_eq, free);
5359
  init_base_vars ();
5360
}
5361
 
5362
/* Remove the REF and ADDRESS edges from GRAPH, as well as all the
5363
   predecessor edges.  */
5364
 
5365
static void
5366
remove_preds_and_fake_succs (constraint_graph_t graph)
5367
{
5368
  unsigned int i;
5369
 
5370
  /* Clear the implicit ref and address nodes from the successor
5371
     lists.  */
5372
  for (i = 0; i < FIRST_REF_NODE; i++)
5373
    {
5374
      if (graph->succs[i])
5375
        bitmap_clear_range (graph->succs[i], FIRST_REF_NODE,
5376
                            FIRST_REF_NODE * 2);
5377
    }
5378
 
5379
  /* Free the successor list for the non-ref nodes.  */
5380
  for (i = FIRST_REF_NODE; i < graph->size; i++)
5381
    {
5382
      if (graph->succs[i])
5383
        BITMAP_FREE (graph->succs[i]);
5384
    }
5385
 
5386
  /* Now reallocate the size of the successor list as, and blow away
5387
     the predecessor bitmaps.  */
5388
  graph->size = VEC_length (varinfo_t, varmap);
5389
  graph->succs = XRESIZEVEC (bitmap, graph->succs, graph->size);
5390
 
5391
  free (graph->implicit_preds);
5392
  graph->implicit_preds = NULL;
5393
  free (graph->preds);
5394
  graph->preds = NULL;
5395
  bitmap_obstack_release (&predbitmap_obstack);
5396
}
5397
 
5398
/* Initialize the heapvar for statement mapping.  */
5399
 
5400
static void
5401
init_alias_heapvars (void)
5402
{
5403
  if (!heapvar_for_stmt)
5404
    heapvar_for_stmt = htab_create_ggc (11, tree_map_hash, heapvar_map_eq,
5405
                                        NULL);
5406
}
5407
 
5408
/* Delete the heapvar for statement mapping.  */
5409
 
5410
void
5411
delete_alias_heapvars (void)
5412
{
5413
  if (heapvar_for_stmt)
5414
    htab_delete (heapvar_for_stmt);
5415
  heapvar_for_stmt = NULL;
5416
}
5417
 
5418
/* Solve the constraint set.  */
5419
 
5420
static void
5421
solve_constraints (void)
5422
{
5423
  struct scc_info *si;
5424
 
5425
  if (dump_file)
5426
    {
5427
      fprintf (dump_file, "Points-to analysis\n\nConstraints:\n\n");
5428
      dump_constraints (dump_file);
5429
    }
5430
 
5431
  if (dump_file)
5432
    fprintf (dump_file,
5433
             "\nCollapsing static cycles and doing variable "
5434
             "substitution\n");
5435
 
5436
  init_graph (VEC_length (varinfo_t, varmap) * 2);
5437
 
5438
  if (dump_file)
5439
    fprintf (dump_file, "Building predecessor graph\n");
5440
  build_pred_graph ();
5441
 
5442
  if (dump_file)
5443
    fprintf (dump_file, "Detecting pointer and location "
5444
             "equivalences\n");
5445
  si = perform_var_substitution (graph);
5446
 
5447
  if (dump_file)
5448
    fprintf (dump_file, "Rewriting constraints and unifying "
5449
             "variables\n");
5450
  rewrite_constraints (graph, si);
5451
 
5452
  build_succ_graph ();
5453
  free_var_substitution_info (si);
5454
 
5455
  if (dump_file && (dump_flags & TDF_GRAPH))
5456
    dump_constraint_graph (dump_file);
5457
 
5458
  move_complex_constraints (graph);
5459
 
5460
  if (dump_file)
5461
    fprintf (dump_file, "Uniting pointer but not location equivalent "
5462
             "variables\n");
5463
  unite_pointer_equivalences (graph);
5464
 
5465
  if (dump_file)
5466
    fprintf (dump_file, "Finding indirect cycles\n");
5467
  find_indirect_cycles (graph);
5468
 
5469
  /* Implicit nodes and predecessors are no longer necessary at this
5470
     point. */
5471
  remove_preds_and_fake_succs (graph);
5472
 
5473
  if (dump_file)
5474
    fprintf (dump_file, "Solving graph\n");
5475
 
5476
  solve_graph (graph);
5477
 
5478
  if (dump_file)
5479
    dump_sa_points_to_info (dump_file);
5480
}
5481
 
5482
/* Create points-to sets for the current function.  See the comments
5483
   at the start of the file for an algorithmic overview.  */
5484
 
5485
static void
5486
compute_points_to_sets (void)
5487
{
5488
  basic_block bb;
5489
  unsigned i;
5490
  varinfo_t vi;
5491
 
5492
  timevar_push (TV_TREE_PTA);
5493
 
5494
  init_alias_vars ();
5495
  init_alias_heapvars ();
5496
 
5497
  intra_create_variable_infos ();
5498
 
5499
  /* Now walk all statements and derive aliases.  */
5500
  FOR_EACH_BB (bb)
5501
    {
5502
      gimple_stmt_iterator gsi;
5503
 
5504
      for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
5505
        {
5506
          gimple phi = gsi_stmt (gsi);
5507
 
5508
          if (is_gimple_reg (gimple_phi_result (phi)))
5509
            find_func_aliases (phi);
5510
        }
5511
 
5512
      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
5513
        {
5514
          gimple stmt = gsi_stmt (gsi);
5515
 
5516
          find_func_aliases (stmt);
5517
        }
5518
    }
5519
 
5520
  /* From the constraints compute the points-to sets.  */
5521
  solve_constraints ();
5522
 
5523
  /* Compute the points-to sets for ESCAPED and CALLUSED used for
5524
     call-clobber analysis.  */
5525
  find_what_var_points_to (get_varinfo (escaped_id),
5526
                           &cfun->gimple_df->escaped);
5527
  find_what_var_points_to (get_varinfo (callused_id),
5528
                           &cfun->gimple_df->callused);
5529
 
5530
  /* Make sure the ESCAPED solution (which is used as placeholder in
5531
     other solutions) does not reference itself.  This simplifies
5532
     points-to solution queries.  */
5533
  cfun->gimple_df->escaped.escaped = 0;
5534
 
5535
  /* Mark escaped HEAP variables as global.  */
5536
  for (i = 0; VEC_iterate (varinfo_t, varmap, i, vi); ++i)
5537
    if (vi->is_heap_var
5538
        && !vi->is_restrict_var
5539
        && !vi->is_global_var)
5540
      DECL_EXTERNAL (vi->decl) = vi->is_global_var
5541
        = pt_solution_includes (&cfun->gimple_df->escaped, vi->decl);
5542
 
5543
  /* Compute the points-to sets for pointer SSA_NAMEs.  */
5544
  for (i = 0; i < num_ssa_names; ++i)
5545
    {
5546
      tree ptr = ssa_name (i);
5547
      if (ptr
5548
          && POINTER_TYPE_P (TREE_TYPE (ptr)))
5549
        find_what_p_points_to (ptr);
5550
    }
5551
 
5552
  timevar_pop (TV_TREE_PTA);
5553
}
5554
 
5555
 
5556
/* Delete created points-to sets.  */
5557
 
5558
static void
5559
delete_points_to_sets (void)
5560
{
5561
  unsigned int i;
5562
 
5563
  htab_delete (shared_bitmap_table);
5564
  if (dump_file && (dump_flags & TDF_STATS))
5565
    fprintf (dump_file, "Points to sets created:%d\n",
5566
             stats.points_to_sets_created);
5567
 
5568
  pointer_map_destroy (vi_for_tree);
5569
  bitmap_obstack_release (&pta_obstack);
5570
  VEC_free (constraint_t, heap, constraints);
5571
 
5572
  for (i = 0; i < graph->size; i++)
5573
    VEC_free (constraint_t, heap, graph->complex[i]);
5574
  free (graph->complex);
5575
 
5576
  free (graph->rep);
5577
  free (graph->succs);
5578
  free (graph->pe);
5579
  free (graph->pe_rep);
5580
  free (graph->indirect_cycles);
5581
  free (graph);
5582
 
5583
  VEC_free (varinfo_t, heap, varmap);
5584
  free_alloc_pool (variable_info_pool);
5585
  free_alloc_pool (constraint_pool);
5586
}
5587
 
5588
 
5589
/* Compute points-to information for every SSA_NAME pointer in the
5590
   current function and compute the transitive closure of escaped
5591
   variables to re-initialize the call-clobber states of local variables.  */
5592
 
5593
unsigned int
5594
compute_may_aliases (void)
5595
{
5596
  /* For each pointer P_i, determine the sets of variables that P_i may
5597
     point-to.  Compute the reachability set of escaped and call-used
5598
     variables.  */
5599
  compute_points_to_sets ();
5600
 
5601
  /* Debugging dumps.  */
5602
  if (dump_file)
5603
    {
5604
      dump_alias_info (dump_file);
5605
 
5606
      if (dump_flags & TDF_DETAILS)
5607
        dump_referenced_vars (dump_file);
5608
    }
5609
 
5610
  /* Deallocate memory used by aliasing data structures and the internal
5611
     points-to solution.  */
5612
  delete_points_to_sets ();
5613
 
5614
  gcc_assert (!need_ssa_update_p (cfun));
5615
 
5616
  return 0;
5617
}
5618
 
5619
static bool
5620
gate_tree_pta (void)
5621
{
5622
  return flag_tree_pta;
5623
}
5624
 
5625
/* A dummy pass to cause points-to information to be computed via
5626
   TODO_rebuild_alias.  */
5627
 
5628
struct gimple_opt_pass pass_build_alias =
5629
{
5630
 {
5631
  GIMPLE_PASS,
5632
  "alias",                  /* name */
5633
  gate_tree_pta,            /* gate */
5634
  NULL,                     /* execute */
5635
  NULL,                     /* sub */
5636
  NULL,                     /* next */
5637
  0,                        /* static_pass_number */
5638
  TV_NONE,                  /* tv_id */
5639
  PROP_cfg | PROP_ssa,      /* properties_required */
5640
  0,                         /* properties_provided */
5641
  0,                        /* properties_destroyed */
5642
  0,                        /* todo_flags_start */
5643
  TODO_rebuild_alias | TODO_dump_func  /* todo_flags_finish */
5644
 }
5645
};
5646
 
5647
/* A dummy pass to cause points-to information to be computed via
5648
   TODO_rebuild_alias.  */
5649
 
5650
struct gimple_opt_pass pass_build_ealias =
5651
{
5652
 {
5653
  GIMPLE_PASS,
5654
  "ealias",                 /* name */
5655
  gate_tree_pta,            /* gate */
5656
  NULL,                     /* execute */
5657
  NULL,                     /* sub */
5658
  NULL,                     /* next */
5659
  0,                        /* static_pass_number */
5660
  TV_NONE,                  /* tv_id */
5661
  PROP_cfg | PROP_ssa,      /* properties_required */
5662
  0,                         /* properties_provided */
5663
  0,                        /* properties_destroyed */
5664
  0,                        /* todo_flags_start */
5665
  TODO_rebuild_alias | TODO_dump_func  /* todo_flags_finish */
5666
 }
5667
};
5668
 
5669
 
5670
/* Return true if we should execute IPA PTA.  */
5671
static bool
5672
gate_ipa_pta (void)
5673
{
5674
  return (optimize
5675
          && flag_ipa_pta
5676
          /* Don't bother doing anything if the program has errors.  */
5677
          && !(errorcount || sorrycount));
5678
}
5679
 
5680
/* Execute the driver for IPA PTA.  */
5681
static unsigned int
5682
ipa_pta_execute (void)
5683
{
5684
  struct cgraph_node *node;
5685
 
5686
  in_ipa_mode = 1;
5687
 
5688
  init_alias_heapvars ();
5689
  init_alias_vars ();
5690
 
5691
  /* Build the constraints.  */
5692
  for (node = cgraph_nodes; node; node = node->next)
5693
    {
5694
      /* Nodes without a body are not interesting.  Especially do not
5695
         visit clones at this point for now - we get duplicate decls
5696
         there for inline clones at least.  */
5697
      if (!gimple_has_body_p (node->decl)
5698
          || node->clone_of)
5699
        continue;
5700
 
5701
      /* It does not make sense to have graph edges into or out of
5702
         externally visible functions.  There is no extra information
5703
         we can gather from them.  */
5704
      if (node->local.externally_visible)
5705
        continue;
5706
 
5707
      create_function_info_for (node->decl,
5708
                                cgraph_node_name (node));
5709
    }
5710
 
5711
  for (node = cgraph_nodes; node; node = node->next)
5712
    {
5713
      struct function *func;
5714
      basic_block bb;
5715
      tree old_func_decl;
5716
 
5717
      /* Nodes without a body are not interesting.  */
5718
      if (!gimple_has_body_p (node->decl)
5719
          || node->clone_of)
5720
        continue;
5721
 
5722
      if (dump_file)
5723
        fprintf (dump_file,
5724
                 "Generating constraints for %s\n",
5725
                 cgraph_node_name (node));
5726
 
5727
      func = DECL_STRUCT_FUNCTION (node->decl);
5728
      old_func_decl = current_function_decl;
5729
      push_cfun (func);
5730
      current_function_decl = node->decl;
5731
 
5732
      /* For externally visible functions use local constraints for
5733
         their arguments.  For local functions we see all callers
5734
         and thus do not need initial constraints for parameters.  */
5735
      if (node->local.externally_visible)
5736
        intra_create_variable_infos ();
5737
 
5738
      /* Build constriants for the function body.  */
5739
      FOR_EACH_BB_FN (bb, func)
5740
        {
5741
          gimple_stmt_iterator gsi;
5742
 
5743
          for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
5744
               gsi_next (&gsi))
5745
            {
5746
              gimple phi = gsi_stmt (gsi);
5747
 
5748
              if (is_gimple_reg (gimple_phi_result (phi)))
5749
                find_func_aliases (phi);
5750
            }
5751
 
5752
          for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
5753
            {
5754
              gimple stmt = gsi_stmt (gsi);
5755
 
5756
              find_func_aliases (stmt);
5757
            }
5758
        }
5759
 
5760
      current_function_decl = old_func_decl;
5761
      pop_cfun ();
5762
    }
5763
 
5764
  /* From the constraints compute the points-to sets.  */
5765
  solve_constraints ();
5766
 
5767
  delete_points_to_sets ();
5768
 
5769
  in_ipa_mode = 0;
5770
 
5771
  return 0;
5772
}
5773
 
5774
struct simple_ipa_opt_pass pass_ipa_pta =
5775
{
5776
 {
5777
  SIMPLE_IPA_PASS,
5778
  "pta",                                /* name */
5779
  gate_ipa_pta,                 /* gate */
5780
  ipa_pta_execute,                      /* execute */
5781
  NULL,                                 /* sub */
5782
  NULL,                                 /* next */
5783
  0,                                     /* static_pass_number */
5784
  TV_IPA_PTA,                   /* tv_id */
5785
  0,                                     /* properties_required */
5786
  0,                                     /* properties_provided */
5787
  0,                                     /* properties_destroyed */
5788
  0,                                     /* todo_flags_start */
5789
  TODO_update_ssa                       /* todo_flags_finish */
5790
 }
5791
};
5792
 
5793
 
5794
#include "gt-tree-ssa-structalias.h"

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.