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

Subversion Repositories openrisc

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

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 378 julius
  while (handled_component_p (forzero)
2959
         || INDIRECT_REF_P (forzero))
2960 280 jeremybenn
    forzero = TREE_OPERAND (forzero, 0);
2961
 
2962
  if (CONSTANT_CLASS_P (forzero) && integer_zerop (forzero))
2963
    {
2964
      struct constraint_expr temp;
2965
 
2966
      temp.offset = 0;
2967
      temp.var = integer_id;
2968
      temp.type = SCALAR;
2969
      VEC_safe_push (ce_s, heap, *results, &temp);
2970
      return;
2971
    }
2972
 
2973
  t = get_ref_base_and_extent (t, &bitpos, &bitsize, &bitmaxsize);
2974
 
2975
  /* Pretend to take the address of the base, we'll take care of
2976
     adding the required subset of sub-fields below.  */
2977
  get_constraint_for_1 (t, results, true);
2978
  gcc_assert (VEC_length (ce_s, *results) == 1);
2979
  result = VEC_last (ce_s, *results);
2980
 
2981
  if (result->type == SCALAR
2982
      && get_varinfo (result->var)->is_full_var)
2983
    /* For single-field vars do not bother about the offset.  */
2984
    result->offset = 0;
2985
  else if (result->type == SCALAR)
2986
    {
2987
      /* In languages like C, you can access one past the end of an
2988
         array.  You aren't allowed to dereference it, so we can
2989
         ignore this constraint. When we handle pointer subtraction,
2990
         we may have to do something cute here.  */
2991
 
2992
      if ((unsigned HOST_WIDE_INT)bitpos < get_varinfo (result->var)->fullsize
2993
          && bitmaxsize != 0)
2994
        {
2995
          /* It's also not true that the constraint will actually start at the
2996
             right offset, it may start in some padding.  We only care about
2997
             setting the constraint to the first actual field it touches, so
2998
             walk to find it.  */
2999
          struct constraint_expr cexpr = *result;
3000
          varinfo_t curr;
3001
          VEC_pop (ce_s, *results);
3002
          cexpr.offset = 0;
3003
          for (curr = get_varinfo (cexpr.var); curr; curr = curr->next)
3004
            {
3005
              if (ranges_overlap_p (curr->offset, curr->size,
3006
                                    bitpos, bitmaxsize))
3007
                {
3008
                  cexpr.var = curr->id;
3009
                  VEC_safe_push (ce_s, heap, *results, &cexpr);
3010
                  if (address_p)
3011
                    break;
3012
                }
3013
            }
3014
          /* If we are going to take the address of this field then
3015
             to be able to compute reachability correctly add at least
3016
             the last field of the variable.  */
3017
          if (address_p
3018
              && VEC_length (ce_s, *results) == 0)
3019
            {
3020
              curr = get_varinfo (cexpr.var);
3021
              while (curr->next != NULL)
3022
                curr = curr->next;
3023
              cexpr.var = curr->id;
3024
              VEC_safe_push (ce_s, heap, *results, &cexpr);
3025
            }
3026
          else
3027
            /* Assert that we found *some* field there. The user couldn't be
3028
               accessing *only* padding.  */
3029
            /* Still the user could access one past the end of an array
3030
               embedded in a struct resulting in accessing *only* padding.  */
3031
            gcc_assert (VEC_length (ce_s, *results) >= 1
3032
                        || ref_contains_array_ref (orig_t));
3033
        }
3034
      else if (bitmaxsize == 0)
3035
        {
3036
          if (dump_file && (dump_flags & TDF_DETAILS))
3037
            fprintf (dump_file, "Access to zero-sized part of variable,"
3038
                     "ignoring\n");
3039
        }
3040
      else
3041
        if (dump_file && (dump_flags & TDF_DETAILS))
3042
          fprintf (dump_file, "Access to past the end of variable, ignoring\n");
3043
    }
3044
  else if (result->type == DEREF)
3045
    {
3046
      /* If we do not know exactly where the access goes say so.  Note
3047
         that only for non-structure accesses we know that we access
3048
         at most one subfiled of any variable.  */
3049
      if (bitpos == -1
3050
          || bitsize != bitmaxsize
3051
          || AGGREGATE_TYPE_P (TREE_TYPE (orig_t)))
3052
        result->offset = UNKNOWN_OFFSET;
3053
      else
3054
        result->offset = bitpos;
3055
    }
3056
  else if (result->type == ADDRESSOF)
3057
    {
3058
      /* We can end up here for component references on a
3059
         VIEW_CONVERT_EXPR <>(&foobar).  */
3060
      result->type = SCALAR;
3061
      result->var = anything_id;
3062
      result->offset = 0;
3063
    }
3064
  else
3065
    gcc_unreachable ();
3066
}
3067
 
3068
 
3069
/* Dereference the constraint expression CONS, and return the result.
3070
   DEREF (ADDRESSOF) = SCALAR
3071
   DEREF (SCALAR) = DEREF
3072
   DEREF (DEREF) = (temp = DEREF1; result = DEREF(temp))
3073
   This is needed so that we can handle dereferencing DEREF constraints.  */
3074
 
3075
static void
3076
do_deref (VEC (ce_s, heap) **constraints)
3077
{
3078
  struct constraint_expr *c;
3079
  unsigned int i = 0;
3080
 
3081
  for (i = 0; VEC_iterate (ce_s, *constraints, i, c); i++)
3082
    {
3083
      if (c->type == SCALAR)
3084
        c->type = DEREF;
3085
      else if (c->type == ADDRESSOF)
3086
        c->type = SCALAR;
3087
      else if (c->type == DEREF)
3088
        {
3089
          struct constraint_expr tmplhs;
3090
          tmplhs = new_scalar_tmp_constraint_exp ("dereftmp");
3091
          process_constraint (new_constraint (tmplhs, *c));
3092
          c->var = tmplhs.var;
3093
        }
3094
      else
3095
        gcc_unreachable ();
3096
    }
3097
}
3098
 
3099
static void get_constraint_for_1 (tree, VEC (ce_s, heap) **, bool);
3100
 
3101
/* Given a tree T, return the constraint expression for taking the
3102
   address of it.  */
3103
 
3104
static void
3105
get_constraint_for_address_of (tree t, VEC (ce_s, heap) **results)
3106
{
3107
  struct constraint_expr *c;
3108
  unsigned int i;
3109
 
3110
  get_constraint_for_1 (t, results, true);
3111
 
3112
  for (i = 0; VEC_iterate (ce_s, *results, i, c); i++)
3113
    {
3114
      if (c->type == DEREF)
3115
        c->type = SCALAR;
3116
      else
3117
        c->type = ADDRESSOF;
3118
    }
3119
}
3120
 
3121
/* Given a tree T, return the constraint expression for it.  */
3122
 
3123
static void
3124
get_constraint_for_1 (tree t, VEC (ce_s, heap) **results, bool address_p)
3125
{
3126
  struct constraint_expr temp;
3127
 
3128
  /* x = integer is all glommed to a single variable, which doesn't
3129
     point to anything by itself.  That is, of course, unless it is an
3130
     integer constant being treated as a pointer, in which case, we
3131
     will return that this is really the addressof anything.  This
3132
     happens below, since it will fall into the default case. The only
3133
     case we know something about an integer treated like a pointer is
3134
     when it is the NULL pointer, and then we just say it points to
3135
     NULL.
3136
 
3137
     Do not do that if -fno-delete-null-pointer-checks though, because
3138
     in that case *NULL does not fail, so it _should_ alias *anything.
3139
     It is not worth adding a new option or renaming the existing one,
3140
     since this case is relatively obscure.  */
3141
  if (flag_delete_null_pointer_checks
3142
      && ((TREE_CODE (t) == INTEGER_CST
3143
           && integer_zerop (t))
3144
          /* The only valid CONSTRUCTORs in gimple with pointer typed
3145
             elements are zero-initializer.  */
3146
          || TREE_CODE (t) == CONSTRUCTOR))
3147
    {
3148
      temp.var = nothing_id;
3149
      temp.type = ADDRESSOF;
3150
      temp.offset = 0;
3151
      VEC_safe_push (ce_s, heap, *results, &temp);
3152
      return;
3153
    }
3154
 
3155
  /* String constants are read-only.  */
3156
  if (TREE_CODE (t) == STRING_CST)
3157
    {
3158
      temp.var = readonly_id;
3159
      temp.type = SCALAR;
3160
      temp.offset = 0;
3161
      VEC_safe_push (ce_s, heap, *results, &temp);
3162
      return;
3163
    }
3164
 
3165
  switch (TREE_CODE_CLASS (TREE_CODE (t)))
3166
    {
3167
    case tcc_expression:
3168
      {
3169
        switch (TREE_CODE (t))
3170
          {
3171
          case ADDR_EXPR:
3172
            get_constraint_for_address_of (TREE_OPERAND (t, 0), results);
3173
            return;
3174
          default:;
3175
          }
3176
        break;
3177
      }
3178
    case tcc_reference:
3179
      {
3180
        switch (TREE_CODE (t))
3181
          {
3182
          case INDIRECT_REF:
3183
            {
3184
              get_constraint_for_1 (TREE_OPERAND (t, 0), results, address_p);
3185
              do_deref (results);
3186
              return;
3187
            }
3188
          case ARRAY_REF:
3189
          case ARRAY_RANGE_REF:
3190
          case COMPONENT_REF:
3191
            get_constraint_for_component_ref (t, results, address_p);
3192
            return;
3193
          case VIEW_CONVERT_EXPR:
3194
            get_constraint_for_1 (TREE_OPERAND (t, 0), results, address_p);
3195
            return;
3196
          /* We are missing handling for TARGET_MEM_REF here.  */
3197
          default:;
3198
          }
3199
        break;
3200
      }
3201
    case tcc_exceptional:
3202
      {
3203
        switch (TREE_CODE (t))
3204
          {
3205
          case SSA_NAME:
3206
            {
3207
              get_constraint_for_ssa_var (t, results, address_p);
3208
              return;
3209
            }
3210
          default:;
3211
          }
3212
        break;
3213
      }
3214
    case tcc_declaration:
3215
      {
3216
        get_constraint_for_ssa_var (t, results, address_p);
3217
        return;
3218
      }
3219
    default:;
3220
    }
3221
 
3222
  /* The default fallback is a constraint from anything.  */
3223
  temp.type = ADDRESSOF;
3224
  temp.var = anything_id;
3225
  temp.offset = 0;
3226
  VEC_safe_push (ce_s, heap, *results, &temp);
3227
}
3228
 
3229
/* Given a gimple tree T, return the constraint expression vector for it.  */
3230
 
3231
static void
3232
get_constraint_for (tree t, VEC (ce_s, heap) **results)
3233
{
3234
  gcc_assert (VEC_length (ce_s, *results) == 0);
3235
 
3236
  get_constraint_for_1 (t, results, false);
3237
}
3238
 
3239
 
3240
/* Efficiently generates constraints from all entries in *RHSC to all
3241
   entries in *LHSC.  */
3242
 
3243
static void
3244
process_all_all_constraints (VEC (ce_s, heap) *lhsc, VEC (ce_s, heap) *rhsc)
3245
{
3246
  struct constraint_expr *lhsp, *rhsp;
3247
  unsigned i, j;
3248
 
3249
  if (VEC_length (ce_s, lhsc) <= 1
3250
      || VEC_length (ce_s, rhsc) <= 1)
3251
    {
3252
      for (i = 0; VEC_iterate (ce_s, lhsc, i, lhsp); ++i)
3253
        for (j = 0; VEC_iterate (ce_s, rhsc, j, rhsp); ++j)
3254
          process_constraint (new_constraint (*lhsp, *rhsp));
3255
    }
3256
  else
3257
    {
3258
      struct constraint_expr tmp;
3259
      tmp = new_scalar_tmp_constraint_exp ("allalltmp");
3260
      for (i = 0; VEC_iterate (ce_s, rhsc, i, rhsp); ++i)
3261
        process_constraint (new_constraint (tmp, *rhsp));
3262
      for (i = 0; VEC_iterate (ce_s, lhsc, i, lhsp); ++i)
3263
        process_constraint (new_constraint (*lhsp, tmp));
3264
    }
3265
}
3266
 
3267
/* Handle aggregate copies by expanding into copies of the respective
3268
   fields of the structures.  */
3269
 
3270
static void
3271
do_structure_copy (tree lhsop, tree rhsop)
3272
{
3273
  struct constraint_expr *lhsp, *rhsp;
3274
  VEC (ce_s, heap) *lhsc = NULL, *rhsc = NULL;
3275
  unsigned j;
3276
 
3277
  get_constraint_for (lhsop, &lhsc);
3278
  get_constraint_for (rhsop, &rhsc);
3279
  lhsp = VEC_index (ce_s, lhsc, 0);
3280
  rhsp = VEC_index (ce_s, rhsc, 0);
3281
  if (lhsp->type == DEREF
3282
      || (lhsp->type == ADDRESSOF && lhsp->var == anything_id)
3283
      || rhsp->type == DEREF)
3284
    process_all_all_constraints (lhsc, rhsc);
3285
  else if (lhsp->type == SCALAR
3286
           && (rhsp->type == SCALAR
3287
               || rhsp->type == ADDRESSOF))
3288
    {
3289
      HOST_WIDE_INT lhssize, lhsmaxsize, lhsoffset;
3290
      HOST_WIDE_INT rhssize, rhsmaxsize, rhsoffset;
3291
      unsigned k = 0;
3292
      get_ref_base_and_extent (lhsop, &lhsoffset, &lhssize, &lhsmaxsize);
3293
      get_ref_base_and_extent (rhsop, &rhsoffset, &rhssize, &rhsmaxsize);
3294
      for (j = 0; VEC_iterate (ce_s, lhsc, j, lhsp);)
3295
        {
3296
          varinfo_t lhsv, rhsv;
3297
          rhsp = VEC_index (ce_s, rhsc, k);
3298
          lhsv = get_varinfo (lhsp->var);
3299
          rhsv = get_varinfo (rhsp->var);
3300
          if (lhsv->may_have_pointers
3301
              && ranges_overlap_p (lhsv->offset + rhsoffset, lhsv->size,
3302
                                   rhsv->offset + lhsoffset, rhsv->size))
3303
            process_constraint (new_constraint (*lhsp, *rhsp));
3304
          if (lhsv->offset + rhsoffset + lhsv->size
3305
              > rhsv->offset + lhsoffset + rhsv->size)
3306
            {
3307
              ++k;
3308
              if (k >= VEC_length (ce_s, rhsc))
3309
                break;
3310
            }
3311
          else
3312
            ++j;
3313
        }
3314
    }
3315
  else
3316
    gcc_unreachable ();
3317
 
3318
  VEC_free (ce_s, heap, lhsc);
3319
  VEC_free (ce_s, heap, rhsc);
3320
}
3321
 
3322
/* Create a constraint ID = OP.  */
3323
 
3324
static void
3325
make_constraint_to (unsigned id, tree op)
3326
{
3327
  VEC(ce_s, heap) *rhsc = NULL;
3328
  struct constraint_expr *c;
3329
  struct constraint_expr includes;
3330
  unsigned int j;
3331
 
3332
  includes.var = id;
3333
  includes.offset = 0;
3334
  includes.type = SCALAR;
3335
 
3336
  get_constraint_for (op, &rhsc);
3337
  for (j = 0; VEC_iterate (ce_s, rhsc, j, c); j++)
3338
    process_constraint (new_constraint (includes, *c));
3339
  VEC_free (ce_s, heap, rhsc);
3340
}
3341
 
3342
/* Create a constraint ID = &FROM.  */
3343
 
3344
static void
3345
make_constraint_from (varinfo_t vi, int from)
3346
{
3347
  struct constraint_expr lhs, rhs;
3348
 
3349
  lhs.var = vi->id;
3350
  lhs.offset = 0;
3351
  lhs.type = SCALAR;
3352
 
3353
  rhs.var = from;
3354
  rhs.offset = 0;
3355
  rhs.type = ADDRESSOF;
3356
  process_constraint (new_constraint (lhs, rhs));
3357
}
3358
 
3359
/* Create a constraint ID = FROM.  */
3360
 
3361
static void
3362
make_copy_constraint (varinfo_t vi, int from)
3363
{
3364
  struct constraint_expr lhs, rhs;
3365
 
3366
  lhs.var = vi->id;
3367
  lhs.offset = 0;
3368
  lhs.type = SCALAR;
3369
 
3370
  rhs.var = from;
3371
  rhs.offset = 0;
3372
  rhs.type = SCALAR;
3373
  process_constraint (new_constraint (lhs, rhs));
3374
}
3375
 
3376
/* Make constraints necessary to make OP escape.  */
3377
 
3378
static void
3379
make_escape_constraint (tree op)
3380
{
3381
  make_constraint_to (escaped_id, op);
3382
}
3383
 
3384
/* Create a new artificial heap variable with NAME and make a
3385
   constraint from it to LHS.  Return the created variable.  */
3386
 
3387
static varinfo_t
3388
make_constraint_from_heapvar (varinfo_t lhs, const char *name)
3389
{
3390
  varinfo_t vi;
3391
  tree heapvar = heapvar_lookup (lhs->decl, lhs->offset);
3392
 
3393
  if (heapvar == NULL_TREE)
3394
    {
3395
      var_ann_t ann;
3396
      heapvar = create_tmp_var_raw (ptr_type_node, name);
3397
      DECL_EXTERNAL (heapvar) = 1;
3398
 
3399
      heapvar_insert (lhs->decl, lhs->offset, heapvar);
3400
 
3401
      ann = get_var_ann (heapvar);
3402
      ann->is_heapvar = 1;
3403
    }
3404
 
3405
  /* For global vars we need to add a heapvar to the list of referenced
3406
     vars of a different function than it was created for originally.  */
3407
  if (gimple_referenced_vars (cfun))
3408
    add_referenced_var (heapvar);
3409
 
3410
  vi = new_var_info (heapvar, name);
3411
  vi->is_artificial_var = true;
3412
  vi->is_heap_var = true;
3413
  vi->is_unknown_size_var = true;
3414
  vi->offset = 0;
3415
  vi->fullsize = ~0;
3416
  vi->size = ~0;
3417
  vi->is_full_var = true;
3418
  insert_vi_for_tree (heapvar, vi);
3419
 
3420
  make_constraint_from (lhs, vi->id);
3421
 
3422
  return vi;
3423
}
3424
 
3425
/* Create a new artificial heap variable with NAME and make a
3426
   constraint from it to LHS.  Set flags according to a tag used
3427
   for tracking restrict pointers.  */
3428
 
3429
static void
3430
make_constraint_from_restrict (varinfo_t lhs, const char *name)
3431
{
3432
  varinfo_t vi;
3433
  vi = make_constraint_from_heapvar (lhs, name);
3434
  vi->is_restrict_var = 1;
3435
  vi->is_global_var = 0;
3436
  vi->is_special_var = 1;
3437
  vi->may_have_pointers = 0;
3438
}
3439
 
3440
/* For non-IPA mode, generate constraints necessary for a call on the
3441
   RHS.  */
3442
 
3443
static void
3444
handle_rhs_call (gimple stmt, VEC(ce_s, heap) **results)
3445
{
3446
  struct constraint_expr rhsc;
3447
  unsigned i;
3448
 
3449
  for (i = 0; i < gimple_call_num_args (stmt); ++i)
3450
    {
3451
      tree arg = gimple_call_arg (stmt, i);
3452
 
3453
      /* Find those pointers being passed, and make sure they end up
3454
         pointing to anything.  */
3455
      if (could_have_pointers (arg))
3456
        make_escape_constraint (arg);
3457
    }
3458
 
3459
  /* The static chain escapes as well.  */
3460
  if (gimple_call_chain (stmt))
3461
    make_escape_constraint (gimple_call_chain (stmt));
3462
 
3463
  /* And if we applied NRV the address of the return slot escapes as well.  */
3464
  if (gimple_call_return_slot_opt_p (stmt)
3465
      && gimple_call_lhs (stmt) != NULL_TREE
3466
      && TREE_ADDRESSABLE (TREE_TYPE (gimple_call_lhs (stmt))))
3467
    {
3468
      VEC(ce_s, heap) *tmpc = NULL;
3469
      struct constraint_expr lhsc, *c;
3470
      get_constraint_for_address_of (gimple_call_lhs (stmt), &tmpc);
3471
      lhsc.var = escaped_id;
3472
      lhsc.offset = 0;
3473
      lhsc.type = SCALAR;
3474
      for (i = 0; VEC_iterate (ce_s, tmpc, i, c); ++i)
3475
        process_constraint (new_constraint (lhsc, *c));
3476
      VEC_free(ce_s, heap, tmpc);
3477
    }
3478
 
3479
  /* Regular functions return nonlocal memory.  */
3480
  rhsc.var = nonlocal_id;
3481
  rhsc.offset = 0;
3482
  rhsc.type = SCALAR;
3483
  VEC_safe_push (ce_s, heap, *results, &rhsc);
3484
}
3485
 
3486
/* For non-IPA mode, generate constraints necessary for a call
3487
   that returns a pointer and assigns it to LHS.  This simply makes
3488
   the LHS point to global and escaped variables.  */
3489
 
3490
static void
3491
handle_lhs_call (tree lhs, int flags, VEC(ce_s, heap) *rhsc, tree fndecl)
3492
{
3493
  VEC(ce_s, heap) *lhsc = NULL;
3494
 
3495
  get_constraint_for (lhs, &lhsc);
3496
 
3497
  if (flags & ECF_MALLOC)
3498
    {
3499
      varinfo_t vi;
3500
      vi = make_constraint_from_heapvar (get_vi_for_tree (lhs), "HEAP");
3501
      /* We delay marking allocated storage global until we know if
3502
         it escapes.  */
3503
      DECL_EXTERNAL (vi->decl) = 0;
3504
      vi->is_global_var = 0;
3505
      /* If this is not a real malloc call assume the memory was
3506
         initialized and thus may point to global memory.  All
3507
         builtin functions with the malloc attribute behave in a sane way.  */
3508
      if (!fndecl
3509
          || DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL)
3510
        make_constraint_from (vi, nonlocal_id);
3511
    }
3512
  else if (VEC_length (ce_s, rhsc) > 0)
3513
    {
3514
      /* If the store is to a global decl make sure to
3515
         add proper escape constraints.  */
3516
      lhs = get_base_address (lhs);
3517
      if (lhs
3518
          && DECL_P (lhs)
3519
          && is_global_var (lhs))
3520
        {
3521
          struct constraint_expr tmpc;
3522
          tmpc.var = escaped_id;
3523
          tmpc.offset = 0;
3524
          tmpc.type = SCALAR;
3525
          VEC_safe_push (ce_s, heap, lhsc, &tmpc);
3526
        }
3527
      process_all_all_constraints (lhsc, rhsc);
3528
    }
3529
  VEC_free (ce_s, heap, lhsc);
3530
}
3531
 
3532
/* For non-IPA mode, generate constraints necessary for a call of a
3533
   const function that returns a pointer in the statement STMT.  */
3534
 
3535
static void
3536
handle_const_call (gimple stmt, VEC(ce_s, heap) **results)
3537
{
3538
  struct constraint_expr rhsc;
3539
  unsigned int k;
3540
 
3541
  /* Treat nested const functions the same as pure functions as far
3542
     as the static chain is concerned.  */
3543
  if (gimple_call_chain (stmt))
3544
    {
3545
      make_constraint_to (callused_id, gimple_call_chain (stmt));
3546
      rhsc.var = callused_id;
3547
      rhsc.offset = 0;
3548
      rhsc.type = SCALAR;
3549
      VEC_safe_push (ce_s, heap, *results, &rhsc);
3550
    }
3551
 
3552
  /* May return arguments.  */
3553
  for (k = 0; k < gimple_call_num_args (stmt); ++k)
3554
    {
3555
      tree arg = gimple_call_arg (stmt, k);
3556
 
3557
      if (could_have_pointers (arg))
3558
        {
3559
          VEC(ce_s, heap) *argc = NULL;
3560
          unsigned i;
3561
          struct constraint_expr *argp;
3562
          get_constraint_for (arg, &argc);
3563
          for (i = 0; VEC_iterate (ce_s, argc, i, argp); ++i)
3564
            VEC_safe_push (ce_s, heap, *results, argp);
3565
          VEC_free(ce_s, heap, argc);
3566
        }
3567
    }
3568
 
3569
  /* May return addresses of globals.  */
3570
  rhsc.var = nonlocal_id;
3571
  rhsc.offset = 0;
3572
  rhsc.type = ADDRESSOF;
3573
  VEC_safe_push (ce_s, heap, *results, &rhsc);
3574
}
3575
 
3576
/* For non-IPA mode, generate constraints necessary for a call to a
3577
   pure function in statement STMT.  */
3578
 
3579
static void
3580
handle_pure_call (gimple stmt, VEC(ce_s, heap) **results)
3581
{
3582
  struct constraint_expr rhsc;
3583
  unsigned i;
3584
  bool need_callused = false;
3585
 
3586
  /* Memory reached from pointer arguments is call-used.  */
3587
  for (i = 0; i < gimple_call_num_args (stmt); ++i)
3588
    {
3589
      tree arg = gimple_call_arg (stmt, i);
3590
 
3591
      if (could_have_pointers (arg))
3592
        {
3593
          make_constraint_to (callused_id, arg);
3594
          need_callused = true;
3595
        }
3596
    }
3597
 
3598
  /* The static chain is used as well.  */
3599
  if (gimple_call_chain (stmt))
3600
    {
3601
      make_constraint_to (callused_id, gimple_call_chain (stmt));
3602
      need_callused = true;
3603
    }
3604
 
3605
  /* Pure functions may return callused and nonlocal memory.  */
3606
  if (need_callused)
3607
    {
3608
      rhsc.var = callused_id;
3609
      rhsc.offset = 0;
3610
      rhsc.type = SCALAR;
3611
      VEC_safe_push (ce_s, heap, *results, &rhsc);
3612
    }
3613
  rhsc.var = nonlocal_id;
3614
  rhsc.offset = 0;
3615
  rhsc.type = SCALAR;
3616
  VEC_safe_push (ce_s, heap, *results, &rhsc);
3617
}
3618
 
3619
/* Walk statement T setting up aliasing constraints according to the
3620
   references found in T.  This function is the main part of the
3621
   constraint builder.  AI points to auxiliary alias information used
3622
   when building alias sets and computing alias grouping heuristics.  */
3623
 
3624
static void
3625
find_func_aliases (gimple origt)
3626
{
3627
  gimple t = origt;
3628
  VEC(ce_s, heap) *lhsc = NULL;
3629
  VEC(ce_s, heap) *rhsc = NULL;
3630
  struct constraint_expr *c;
3631
 
3632
  /* Now build constraints expressions.  */
3633
  if (gimple_code (t) == GIMPLE_PHI)
3634
    {
3635
      gcc_assert (!AGGREGATE_TYPE_P (TREE_TYPE (gimple_phi_result (t))));
3636
 
3637
      /* Only care about pointers and structures containing
3638
         pointers.  */
3639
      if (could_have_pointers (gimple_phi_result (t)))
3640
        {
3641
          size_t i;
3642
          unsigned int j;
3643
 
3644
          /* For a phi node, assign all the arguments to
3645
             the result.  */
3646
          get_constraint_for (gimple_phi_result (t), &lhsc);
3647
          for (i = 0; i < gimple_phi_num_args (t); i++)
3648
            {
3649
              tree strippedrhs = PHI_ARG_DEF (t, i);
3650
 
3651
              STRIP_NOPS (strippedrhs);
3652
              get_constraint_for (gimple_phi_arg_def (t, i), &rhsc);
3653
 
3654
              for (j = 0; VEC_iterate (ce_s, lhsc, j, c); j++)
3655
                {
3656
                  struct constraint_expr *c2;
3657
                  while (VEC_length (ce_s, rhsc) > 0)
3658
                    {
3659
                      c2 = VEC_last (ce_s, rhsc);
3660
                      process_constraint (new_constraint (*c, *c2));
3661
                      VEC_pop (ce_s, rhsc);
3662
                    }
3663
                }
3664
            }
3665
        }
3666
    }
3667
  /* In IPA mode, we need to generate constraints to pass call
3668
     arguments through their calls.   There are two cases,
3669
     either a GIMPLE_CALL returning a value, or just a plain
3670
     GIMPLE_CALL when we are not.
3671
 
3672
     In non-ipa mode, we need to generate constraints for each
3673
     pointer passed by address.  */
3674
  else if (is_gimple_call (t))
3675
    {
3676
      tree fndecl = gimple_call_fndecl (t);
3677
      if (fndecl != NULL_TREE
3678
          && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3679
        /* ???  All builtins that are handled here need to be handled
3680
           in the alias-oracle query functions explicitly!  */
3681
        switch (DECL_FUNCTION_CODE (fndecl))
3682
          {
3683
          /* All the following functions return a pointer to the same object
3684
             as their first argument points to.  The functions do not add
3685
             to the ESCAPED solution.  The functions make the first argument
3686
             pointed to memory point to what the second argument pointed to
3687
             memory points to.  */
3688
          case BUILT_IN_STRCPY:
3689
          case BUILT_IN_STRNCPY:
3690
          case BUILT_IN_BCOPY:
3691
          case BUILT_IN_MEMCPY:
3692
          case BUILT_IN_MEMMOVE:
3693
          case BUILT_IN_MEMPCPY:
3694
          case BUILT_IN_STPCPY:
3695
          case BUILT_IN_STPNCPY:
3696
          case BUILT_IN_STRCAT:
3697
          case BUILT_IN_STRNCAT:
3698
            {
3699
              tree res = gimple_call_lhs (t);
3700
              tree dest = gimple_call_arg (t, (DECL_FUNCTION_CODE (fndecl)
3701
                                               == BUILT_IN_BCOPY ? 1 : 0));
3702
              tree src = gimple_call_arg (t, (DECL_FUNCTION_CODE (fndecl)
3703
                                              == BUILT_IN_BCOPY ? 0 : 1));
3704
              if (res != NULL_TREE)
3705
                {
3706
                  get_constraint_for (res, &lhsc);
3707
                  if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_MEMPCPY
3708
                      || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPCPY
3709
                      || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPNCPY)
3710
                    get_constraint_for_ptr_offset (dest, NULL_TREE, &rhsc);
3711
                  else
3712
                    get_constraint_for (dest, &rhsc);
3713
                  process_all_all_constraints (lhsc, rhsc);
3714
                  VEC_free (ce_s, heap, lhsc);
3715
                  VEC_free (ce_s, heap, rhsc);
3716
                }
3717
              get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
3718
              get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
3719
              do_deref (&lhsc);
3720
              do_deref (&rhsc);
3721
              process_all_all_constraints (lhsc, rhsc);
3722
              VEC_free (ce_s, heap, lhsc);
3723
              VEC_free (ce_s, heap, rhsc);
3724
              return;
3725
            }
3726
          case BUILT_IN_MEMSET:
3727
            {
3728
              tree res = gimple_call_lhs (t);
3729
              tree dest = gimple_call_arg (t, 0);
3730
              unsigned i;
3731
              ce_s *lhsp;
3732
              struct constraint_expr ac;
3733
              if (res != NULL_TREE)
3734
                {
3735
                  get_constraint_for (res, &lhsc);
3736
                  get_constraint_for (dest, &rhsc);
3737
                  process_all_all_constraints (lhsc, rhsc);
3738
                  VEC_free (ce_s, heap, lhsc);
3739
                  VEC_free (ce_s, heap, rhsc);
3740
                }
3741
              get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
3742
              do_deref (&lhsc);
3743
              if (flag_delete_null_pointer_checks
3744
                  && integer_zerop (gimple_call_arg (t, 1)))
3745
                {
3746
                  ac.type = ADDRESSOF;
3747
                  ac.var = nothing_id;
3748
                }
3749
              else
3750
                {
3751
                  ac.type = SCALAR;
3752
                  ac.var = integer_id;
3753
                }
3754
              ac.offset = 0;
3755
              for (i = 0; VEC_iterate (ce_s, lhsc, i, lhsp); ++i)
3756
                process_constraint (new_constraint (*lhsp, ac));
3757
              VEC_free (ce_s, heap, lhsc);
3758
              return;
3759
            }
3760
          /* All the following functions do not return pointers, do not
3761
             modify the points-to sets of memory reachable from their
3762
             arguments and do not add to the ESCAPED solution.  */
3763
          case BUILT_IN_SINCOS:
3764
          case BUILT_IN_SINCOSF:
3765
          case BUILT_IN_SINCOSL:
3766
          case BUILT_IN_FREXP:
3767
          case BUILT_IN_FREXPF:
3768
          case BUILT_IN_FREXPL:
3769
          case BUILT_IN_GAMMA_R:
3770
          case BUILT_IN_GAMMAF_R:
3771
          case BUILT_IN_GAMMAL_R:
3772
          case BUILT_IN_LGAMMA_R:
3773
          case BUILT_IN_LGAMMAF_R:
3774
          case BUILT_IN_LGAMMAL_R:
3775
          case BUILT_IN_MODF:
3776
          case BUILT_IN_MODFF:
3777
          case BUILT_IN_MODFL:
3778
          case BUILT_IN_REMQUO:
3779
          case BUILT_IN_REMQUOF:
3780
          case BUILT_IN_REMQUOL:
3781
          case BUILT_IN_FREE:
3782
            return;
3783
          /* printf-style functions may have hooks to set pointers to
3784
             point to somewhere into the generated string.  Leave them
3785
             for a later excercise...  */
3786
          default:
3787
            /* Fallthru to general call handling.  */;
3788
          }
3789
      if (!in_ipa_mode
3790
          || (fndecl
3791
              && !lookup_vi_for_tree (fndecl)))
3792
        {
3793
          VEC(ce_s, heap) *rhsc = NULL;
3794
          int flags = gimple_call_flags (t);
3795
 
3796
          /* Const functions can return their arguments and addresses
3797
             of global memory but not of escaped memory.  */
3798
          if (flags & (ECF_CONST|ECF_NOVOPS))
3799
            {
3800
              if (gimple_call_lhs (t)
3801
                  && could_have_pointers (gimple_call_lhs (t)))
3802
                handle_const_call (t, &rhsc);
3803
            }
3804
          /* Pure functions can return addresses in and of memory
3805
             reachable from their arguments, but they are not an escape
3806
             point for reachable memory of their arguments.  */
3807
          else if (flags & (ECF_PURE|ECF_LOOPING_CONST_OR_PURE))
3808
            handle_pure_call (t, &rhsc);
3809
          else
3810
            handle_rhs_call (t, &rhsc);
3811
          if (gimple_call_lhs (t)
3812
              && could_have_pointers (gimple_call_lhs (t)))
3813
            handle_lhs_call (gimple_call_lhs (t), flags, rhsc, fndecl);
3814
          VEC_free (ce_s, heap, rhsc);
3815
        }
3816
      else
3817
        {
3818
          tree lhsop;
3819
          varinfo_t fi;
3820
          int i = 1;
3821
          size_t j;
3822
          tree decl;
3823
 
3824
          lhsop = gimple_call_lhs (t);
3825
          decl = gimple_call_fndecl (t);
3826
 
3827
          /* If we can directly resolve the function being called, do so.
3828
             Otherwise, it must be some sort of indirect expression that
3829
             we should still be able to handle.  */
3830
          if (decl)
3831
            fi = get_vi_for_tree (decl);
3832
          else
3833
            {
3834
              decl = gimple_call_fn (t);
3835
              fi = get_vi_for_tree (decl);
3836
            }
3837
 
3838
          /* Assign all the passed arguments to the appropriate incoming
3839
             parameters of the function.  */
3840
          for (j = 0; j < gimple_call_num_args (t); j++)
3841
            {
3842
              struct constraint_expr lhs ;
3843
              struct constraint_expr *rhsp;
3844
              tree arg = gimple_call_arg (t, j);
3845
 
3846
              get_constraint_for (arg, &rhsc);
3847
              if (TREE_CODE (decl) != FUNCTION_DECL)
3848
                {
3849
                  lhs.type = DEREF;
3850
                  lhs.var = fi->id;
3851
                  lhs.offset = i;
3852
                }
3853
              else
3854
                {
3855
                  lhs.type = SCALAR;
3856
                  lhs.var = first_vi_for_offset (fi, i)->id;
3857
                  lhs.offset = 0;
3858
                }
3859
              while (VEC_length (ce_s, rhsc) != 0)
3860
                {
3861
                  rhsp = VEC_last (ce_s, rhsc);
3862
                  process_constraint (new_constraint (lhs, *rhsp));
3863
                  VEC_pop (ce_s, rhsc);
3864
                }
3865
              i++;
3866
            }
3867
 
3868
          /* If we are returning a value, assign it to the result.  */
3869
          if (lhsop)
3870
            {
3871
              struct constraint_expr rhs;
3872
              struct constraint_expr *lhsp;
3873
              unsigned int j = 0;
3874
 
3875
              get_constraint_for (lhsop, &lhsc);
3876
              if (TREE_CODE (decl) != FUNCTION_DECL)
3877
                {
3878
                  rhs.type = DEREF;
3879
                  rhs.var = fi->id;
3880
                  rhs.offset = i;
3881
                }
3882
              else
3883
                {
3884
                  rhs.type = SCALAR;
3885
                  rhs.var = first_vi_for_offset (fi, i)->id;
3886
                  rhs.offset = 0;
3887
                }
3888
              for (j = 0; VEC_iterate (ce_s, lhsc, j, lhsp); j++)
3889
                process_constraint (new_constraint (*lhsp, rhs));
3890
            }
3891
        }
3892
    }
3893
  /* Otherwise, just a regular assignment statement.  Only care about
3894
     operations with pointer result, others are dealt with as escape
3895
     points if they have pointer operands.  */
3896
  else if (is_gimple_assign (t)
3897
           && type_could_have_pointers (TREE_TYPE (gimple_assign_lhs (t))))
3898
    {
3899
      /* Otherwise, just a regular assignment statement.  */
3900
      tree lhsop = gimple_assign_lhs (t);
3901
      tree rhsop = (gimple_num_ops (t) == 2) ? gimple_assign_rhs1 (t) : NULL;
3902
 
3903
      if (rhsop && AGGREGATE_TYPE_P (TREE_TYPE (lhsop)))
3904
        do_structure_copy (lhsop, rhsop);
3905
      else
3906
        {
3907
          struct constraint_expr temp;
3908
          get_constraint_for (lhsop, &lhsc);
3909
 
3910
          if (gimple_assign_rhs_code (t) == POINTER_PLUS_EXPR)
3911
            get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
3912
                                           gimple_assign_rhs2 (t), &rhsc);
3913
          else if ((CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (t))
3914
                    && !(POINTER_TYPE_P (gimple_expr_type (t))
3915
                         && !POINTER_TYPE_P (TREE_TYPE (rhsop))))
3916
                   || gimple_assign_single_p (t))
3917
            get_constraint_for (rhsop, &rhsc);
3918
          else
3919
            {
3920
              temp.type = ADDRESSOF;
3921
              temp.var = anything_id;
3922
              temp.offset = 0;
3923
              VEC_safe_push (ce_s, heap, rhsc, &temp);
3924
            }
3925
          process_all_all_constraints (lhsc, rhsc);
3926
        }
3927
      /* If there is a store to a global variable the rhs escapes.  */
3928
      if ((lhsop = get_base_address (lhsop)) != NULL_TREE
3929
          && DECL_P (lhsop)
3930
          && is_global_var (lhsop))
3931
        make_escape_constraint (rhsop);
3932
      /* If this is a conversion of a non-restrict pointer to a
3933
         restrict pointer track it with a new heapvar.  */
3934
      else if (gimple_assign_cast_p (t)
3935
               && POINTER_TYPE_P (TREE_TYPE (rhsop))
3936
               && POINTER_TYPE_P (TREE_TYPE (lhsop))
3937
               && !TYPE_RESTRICT (TREE_TYPE (rhsop))
3938
               && TYPE_RESTRICT (TREE_TYPE (lhsop)))
3939
        make_constraint_from_restrict (get_vi_for_tree (lhsop),
3940
                                       "CAST_RESTRICT");
3941
    }
3942
  /* For conversions of pointers to non-pointers the pointer escapes.  */
3943
  else if (gimple_assign_cast_p (t)
3944
           && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (t)))
3945
           && !POINTER_TYPE_P (TREE_TYPE (gimple_assign_lhs (t))))
3946
    {
3947
      make_escape_constraint (gimple_assign_rhs1 (t));
3948
    }
3949
  /* Handle escapes through return.  */
3950
  else if (gimple_code (t) == GIMPLE_RETURN
3951
           && gimple_return_retval (t) != NULL_TREE
3952
           && could_have_pointers (gimple_return_retval (t)))
3953
    {
3954
      make_escape_constraint (gimple_return_retval (t));
3955
    }
3956
  /* Handle asms conservatively by adding escape constraints to everything.  */
3957
  else if (gimple_code (t) == GIMPLE_ASM)
3958
    {
3959
      unsigned i, noutputs;
3960
      const char **oconstraints;
3961
      const char *constraint;
3962
      bool allows_mem, allows_reg, is_inout;
3963
 
3964
      noutputs = gimple_asm_noutputs (t);
3965
      oconstraints = XALLOCAVEC (const char *, noutputs);
3966
 
3967
      for (i = 0; i < noutputs; ++i)
3968
        {
3969
          tree link = gimple_asm_output_op (t, i);
3970
          tree op = TREE_VALUE (link);
3971
 
3972
          constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
3973
          oconstraints[i] = constraint;
3974
          parse_output_constraint (&constraint, i, 0, 0, &allows_mem,
3975
                                   &allows_reg, &is_inout);
3976
 
3977
          /* A memory constraint makes the address of the operand escape.  */
3978
          if (!allows_reg && allows_mem)
3979
            make_escape_constraint (build_fold_addr_expr (op));
3980
 
3981
          /* The asm may read global memory, so outputs may point to
3982
             any global memory.  */
3983
          if (op && could_have_pointers (op))
3984
            {
3985
              VEC(ce_s, heap) *lhsc = NULL;
3986
              struct constraint_expr rhsc, *lhsp;
3987
              unsigned j;
3988
              get_constraint_for (op, &lhsc);
3989
              rhsc.var = nonlocal_id;
3990
              rhsc.offset = 0;
3991
              rhsc.type = SCALAR;
3992
              for (j = 0; VEC_iterate (ce_s, lhsc, j, lhsp); j++)
3993
                process_constraint (new_constraint (*lhsp, rhsc));
3994
              VEC_free (ce_s, heap, lhsc);
3995
            }
3996
        }
3997
      for (i = 0; i < gimple_asm_ninputs (t); ++i)
3998
        {
3999
          tree link = gimple_asm_input_op (t, i);
4000
          tree op = TREE_VALUE (link);
4001
 
4002
          constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
4003
 
4004
          parse_input_constraint (&constraint, 0, 0, noutputs, 0, oconstraints,
4005
                                  &allows_mem, &allows_reg);
4006
 
4007
          /* A memory constraint makes the address of the operand escape.  */
4008
          if (!allows_reg && allows_mem)
4009
            make_escape_constraint (build_fold_addr_expr (op));
4010
          /* Strictly we'd only need the constraint to ESCAPED if
4011
             the asm clobbers memory, otherwise using CALLUSED
4012
             would be enough.  */
4013
          else if (op && could_have_pointers (op))
4014
            make_escape_constraint (op);
4015
        }
4016
    }
4017
 
4018
  VEC_free (ce_s, heap, rhsc);
4019
  VEC_free (ce_s, heap, lhsc);
4020
}
4021
 
4022
 
4023
/* Find the first varinfo in the same variable as START that overlaps with
4024
   OFFSET.  Return NULL if we can't find one.  */
4025
 
4026
static varinfo_t
4027
first_vi_for_offset (varinfo_t start, unsigned HOST_WIDE_INT offset)
4028
{
4029
  /* If the offset is outside of the variable, bail out.  */
4030
  if (offset >= start->fullsize)
4031
    return NULL;
4032
 
4033
  /* If we cannot reach offset from start, lookup the first field
4034
     and start from there.  */
4035
  if (start->offset > offset)
4036
    start = lookup_vi_for_tree (start->decl);
4037
 
4038
  while (start)
4039
    {
4040
      /* We may not find a variable in the field list with the actual
4041
         offset when when we have glommed a structure to a variable.
4042
         In that case, however, offset should still be within the size
4043
         of the variable. */
4044
      if (offset >= start->offset
4045
          && (offset - start->offset) < start->size)
4046
        return start;
4047
 
4048
      start= start->next;
4049
    }
4050
 
4051
  return NULL;
4052
}
4053
 
4054
/* Find the first varinfo in the same variable as START that overlaps with
4055
   OFFSET.  If there is no such varinfo the varinfo directly preceding
4056
   OFFSET is returned.  */
4057
 
4058
static varinfo_t
4059
first_or_preceding_vi_for_offset (varinfo_t start,
4060
                                  unsigned HOST_WIDE_INT offset)
4061
{
4062
  /* If we cannot reach offset from start, lookup the first field
4063
     and start from there.  */
4064
  if (start->offset > offset)
4065
    start = lookup_vi_for_tree (start->decl);
4066
 
4067
  /* We may not find a variable in the field list with the actual
4068
     offset when when we have glommed a structure to a variable.
4069
     In that case, however, offset should still be within the size
4070
     of the variable.
4071
     If we got beyond the offset we look for return the field
4072
     directly preceding offset which may be the last field.  */
4073
  while (start->next
4074
         && offset >= start->offset
4075
         && !((offset - start->offset) < start->size))
4076
    start = start->next;
4077
 
4078
  return start;
4079
}
4080
 
4081
 
4082
/* Insert the varinfo FIELD into the field list for BASE, at the front
4083
   of the list.  */
4084
 
4085
static void
4086
insert_into_field_list (varinfo_t base, varinfo_t field)
4087
{
4088
  varinfo_t prev = base;
4089
  varinfo_t curr = base->next;
4090
 
4091
  field->next = curr;
4092
  prev->next = field;
4093
}
4094
 
4095
/* Insert the varinfo FIELD into the field list for BASE, ordered by
4096
   offset.  */
4097
 
4098
static void
4099
insert_into_field_list_sorted (varinfo_t base, varinfo_t field)
4100
{
4101
  varinfo_t prev = base;
4102
  varinfo_t curr = base->next;
4103
 
4104
  if (curr == NULL)
4105
    {
4106
      prev->next = field;
4107
      field->next = NULL;
4108
    }
4109
  else
4110
    {
4111
      while (curr)
4112
        {
4113
          if (field->offset <= curr->offset)
4114
            break;
4115
          prev = curr;
4116
          curr = curr->next;
4117
        }
4118
      field->next = prev->next;
4119
      prev->next = field;
4120
    }
4121
}
4122
 
4123
/* This structure is used during pushing fields onto the fieldstack
4124
   to track the offset of the field, since bitpos_of_field gives it
4125
   relative to its immediate containing type, and we want it relative
4126
   to the ultimate containing object.  */
4127
 
4128
struct fieldoff
4129
{
4130
  /* Offset from the base of the base containing object to this field.  */
4131
  HOST_WIDE_INT offset;
4132
 
4133
  /* Size, in bits, of the field.  */
4134
  unsigned HOST_WIDE_INT size;
4135
 
4136
  unsigned has_unknown_size : 1;
4137
 
4138
  unsigned may_have_pointers : 1;
4139
 
4140
  unsigned only_restrict_pointers : 1;
4141
};
4142
typedef struct fieldoff fieldoff_s;
4143
 
4144
DEF_VEC_O(fieldoff_s);
4145
DEF_VEC_ALLOC_O(fieldoff_s,heap);
4146
 
4147
/* qsort comparison function for two fieldoff's PA and PB */
4148
 
4149
static int
4150
fieldoff_compare (const void *pa, const void *pb)
4151
{
4152
  const fieldoff_s *foa = (const fieldoff_s *)pa;
4153
  const fieldoff_s *fob = (const fieldoff_s *)pb;
4154
  unsigned HOST_WIDE_INT foasize, fobsize;
4155
 
4156
  if (foa->offset < fob->offset)
4157
    return -1;
4158
  else if (foa->offset > fob->offset)
4159
    return 1;
4160
 
4161
  foasize = foa->size;
4162
  fobsize = fob->size;
4163
  if (foasize < fobsize)
4164
    return -1;
4165
  else if (foasize > fobsize)
4166
    return 1;
4167
  return 0;
4168
}
4169
 
4170
/* Sort a fieldstack according to the field offset and sizes.  */
4171
static void
4172
sort_fieldstack (VEC(fieldoff_s,heap) *fieldstack)
4173
{
4174
  qsort (VEC_address (fieldoff_s, fieldstack),
4175
         VEC_length (fieldoff_s, fieldstack),
4176
         sizeof (fieldoff_s),
4177
         fieldoff_compare);
4178
}
4179
 
4180
/* Return true if V is a tree that we can have subvars for.
4181
   Normally, this is any aggregate type.  Also complex
4182
   types which are not gimple registers can have subvars.  */
4183
 
4184
static inline bool
4185
var_can_have_subvars (const_tree v)
4186
{
4187
  /* Volatile variables should never have subvars.  */
4188
  if (TREE_THIS_VOLATILE (v))
4189
    return false;
4190
 
4191
  /* Non decls or memory tags can never have subvars.  */
4192
  if (!DECL_P (v))
4193
    return false;
4194
 
4195
  /* Aggregates without overlapping fields can have subvars.  */
4196
  if (TREE_CODE (TREE_TYPE (v)) == RECORD_TYPE)
4197
    return true;
4198
 
4199
  return false;
4200
}
4201
 
4202
/* Given a TYPE, and a vector of field offsets FIELDSTACK, push all
4203
   the fields of TYPE onto fieldstack, recording their offsets along
4204
   the way.
4205
 
4206
   OFFSET is used to keep track of the offset in this entire
4207
   structure, rather than just the immediately containing structure.
4208
   Returns the number of fields pushed.  */
4209
 
4210
static int
4211
push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
4212
                             HOST_WIDE_INT offset, bool must_have_pointers_p)
4213
{
4214
  tree field;
4215
  int count = 0;
4216
 
4217
  if (TREE_CODE (type) != RECORD_TYPE)
4218
    return 0;
4219
 
4220
  /* If the vector of fields is growing too big, bail out early.
4221
     Callers check for VEC_length <= MAX_FIELDS_FOR_FIELD_SENSITIVE, make
4222
     sure this fails.  */
4223
  if (VEC_length (fieldoff_s, *fieldstack) > MAX_FIELDS_FOR_FIELD_SENSITIVE)
4224
    return 0;
4225
 
4226
  for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
4227
    if (TREE_CODE (field) == FIELD_DECL)
4228
      {
4229
        bool push = false;
4230
        int pushed = 0;
4231
        HOST_WIDE_INT foff = bitpos_of_field (field);
4232
 
4233
        if (!var_can_have_subvars (field)
4234
            || TREE_CODE (TREE_TYPE (field)) == QUAL_UNION_TYPE
4235
            || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
4236
          push = true;
4237
        else if (!(pushed = push_fields_onto_fieldstack
4238
                   (TREE_TYPE (field), fieldstack, offset + foff,
4239
                    must_have_pointers_p))
4240
                 && (DECL_SIZE (field)
4241
                     && !integer_zerop (DECL_SIZE (field))))
4242
          /* Empty structures may have actual size, like in C++.  So
4243
             see if we didn't push any subfields and the size is
4244
             nonzero, push the field onto the stack.  */
4245
          push = true;
4246
 
4247
        if (push)
4248
          {
4249
            fieldoff_s *pair = NULL;
4250
            bool has_unknown_size = false;
4251
 
4252
            if (!VEC_empty (fieldoff_s, *fieldstack))
4253
              pair = VEC_last (fieldoff_s, *fieldstack);
4254
 
4255
            if (!DECL_SIZE (field)
4256
                || !host_integerp (DECL_SIZE (field), 1))
4257
              has_unknown_size = true;
4258
 
4259
            /* If adjacent fields do not contain pointers merge them.  */
4260
            if (pair
4261
                && !pair->may_have_pointers
4262
                && !pair->has_unknown_size
4263
                && !has_unknown_size
4264
                && pair->offset + (HOST_WIDE_INT)pair->size == offset + foff
4265
                && !must_have_pointers_p
4266
                && !could_have_pointers (field))
4267
              {
4268
                pair = VEC_last (fieldoff_s, *fieldstack);
4269
                pair->size += TREE_INT_CST_LOW (DECL_SIZE (field));
4270
              }
4271
            else
4272
              {
4273
                pair = VEC_safe_push (fieldoff_s, heap, *fieldstack, NULL);
4274
                pair->offset = offset + foff;
4275
                pair->has_unknown_size = has_unknown_size;
4276
                if (!has_unknown_size)
4277
                  pair->size = TREE_INT_CST_LOW (DECL_SIZE (field));
4278
                else
4279
                  pair->size = -1;
4280
                pair->may_have_pointers
4281
                  = must_have_pointers_p || could_have_pointers (field);
4282
                pair->only_restrict_pointers
4283
                  = (!has_unknown_size
4284
                     && POINTER_TYPE_P (TREE_TYPE (field))
4285
                     && TYPE_RESTRICT (TREE_TYPE (field)));
4286
                count++;
4287
              }
4288
          }
4289
        else
4290
          count += pushed;
4291
      }
4292
 
4293
  return count;
4294
}
4295
 
4296
/* Count the number of arguments DECL has, and set IS_VARARGS to true
4297
   if it is a varargs function.  */
4298
 
4299
static unsigned int
4300
count_num_arguments (tree decl, bool *is_varargs)
4301
{
4302
  unsigned int num = 0;
4303
  tree t;
4304
 
4305
  /* Capture named arguments for K&R functions.  They do not
4306
     have a prototype and thus no TYPE_ARG_TYPES.  */
4307
  for (t = DECL_ARGUMENTS (decl); t; t = TREE_CHAIN (t))
4308
    ++num;
4309
 
4310
  /* Check if the function has variadic arguments.  */
4311
  for (t = TYPE_ARG_TYPES (TREE_TYPE (decl)); t; t = TREE_CHAIN (t))
4312
    if (TREE_VALUE (t) == void_type_node)
4313
      break;
4314
  if (!t)
4315
    *is_varargs = true;
4316
 
4317
  return num;
4318
}
4319
 
4320
/* Creation function node for DECL, using NAME, and return the index
4321
   of the variable we've created for the function.  */
4322
 
4323
static unsigned int
4324
create_function_info_for (tree decl, const char *name)
4325
{
4326
  varinfo_t vi;
4327
  tree arg;
4328
  unsigned int i;
4329
  bool is_varargs = false;
4330
 
4331
  /* Create the variable info.  */
4332
 
4333
  vi = new_var_info (decl, name);
4334
  vi->offset = 0;
4335
  vi->size = 1;
4336
  vi->fullsize = count_num_arguments (decl, &is_varargs) + 1;
4337
  insert_vi_for_tree (vi->decl, vi);
4338
 
4339
  stats.total_vars++;
4340
 
4341
  /* If it's varargs, we don't know how many arguments it has, so we
4342
     can't do much.  */
4343
  if (is_varargs)
4344
    {
4345
      vi->fullsize = ~0;
4346
      vi->size = ~0;
4347
      vi->is_unknown_size_var = true;
4348
      return vi->id;
4349
    }
4350
 
4351
  arg = DECL_ARGUMENTS (decl);
4352
 
4353
  /* Set up variables for each argument.  */
4354
  for (i = 1; i < vi->fullsize; i++)
4355
    {
4356
      varinfo_t argvi;
4357
      const char *newname;
4358
      char *tempname;
4359
      tree argdecl = decl;
4360
 
4361
      if (arg)
4362
        argdecl = arg;
4363
 
4364
      asprintf (&tempname, "%s.arg%d", name, i-1);
4365
      newname = ggc_strdup (tempname);
4366
      free (tempname);
4367
 
4368
      argvi = new_var_info (argdecl, newname);
4369
      argvi->offset = i;
4370
      argvi->size = 1;
4371
      argvi->is_full_var = true;
4372
      argvi->fullsize = vi->fullsize;
4373
      insert_into_field_list_sorted (vi, argvi);
4374
      stats.total_vars ++;
4375
      if (arg)
4376
        {
4377
          insert_vi_for_tree (arg, argvi);
4378
          arg = TREE_CHAIN (arg);
4379
        }
4380
    }
4381
 
4382
  /* Create a variable for the return var.  */
4383
  if (DECL_RESULT (decl) != NULL
4384
      || !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
4385
    {
4386
      varinfo_t resultvi;
4387
      const char *newname;
4388
      char *tempname;
4389
      tree resultdecl = decl;
4390
 
4391
      vi->fullsize ++;
4392
 
4393
      if (DECL_RESULT (decl))
4394
        resultdecl = DECL_RESULT (decl);
4395
 
4396
      asprintf (&tempname, "%s.result", name);
4397
      newname = ggc_strdup (tempname);
4398
      free (tempname);
4399
 
4400
      resultvi = new_var_info (resultdecl, newname);
4401
      resultvi->offset = i;
4402
      resultvi->size = 1;
4403
      resultvi->fullsize = vi->fullsize;
4404
      resultvi->is_full_var = true;
4405
      insert_into_field_list_sorted (vi, resultvi);
4406
      stats.total_vars ++;
4407
      if (DECL_RESULT (decl))
4408
        insert_vi_for_tree (DECL_RESULT (decl), resultvi);
4409
    }
4410
 
4411
  return vi->id;
4412
}
4413
 
4414
 
4415
/* Return true if FIELDSTACK contains fields that overlap.
4416
   FIELDSTACK is assumed to be sorted by offset.  */
4417
 
4418
static bool
4419
check_for_overlaps (VEC (fieldoff_s,heap) *fieldstack)
4420
{
4421
  fieldoff_s *fo = NULL;
4422
  unsigned int i;
4423
  HOST_WIDE_INT lastoffset = -1;
4424
 
4425
  for (i = 0; VEC_iterate (fieldoff_s, fieldstack, i, fo); i++)
4426
    {
4427
      if (fo->offset == lastoffset)
4428
        return true;
4429
      lastoffset = fo->offset;
4430
    }
4431
  return false;
4432
}
4433
 
4434
/* Create a varinfo structure for NAME and DECL, and add it to VARMAP.
4435
   This will also create any varinfo structures necessary for fields
4436
   of DECL.  */
4437
 
4438
static unsigned int
4439
create_variable_info_for (tree decl, const char *name)
4440
{
4441
  varinfo_t vi;
4442
  tree decl_type = TREE_TYPE (decl);
4443
  tree declsize = DECL_P (decl) ? DECL_SIZE (decl) : TYPE_SIZE (decl_type);
4444
  VEC (fieldoff_s,heap) *fieldstack = NULL;
4445
 
4446
  if (var_can_have_subvars (decl) && use_field_sensitive)
4447
    push_fields_onto_fieldstack (decl_type, &fieldstack, 0,
4448
                                 TREE_PUBLIC (decl)
4449
                                 || DECL_EXTERNAL (decl)
4450
                                 || TREE_ADDRESSABLE (decl));
4451
 
4452
  /* If the variable doesn't have subvars, we may end up needing to
4453
     sort the field list and create fake variables for all the
4454
     fields.  */
4455
  vi = new_var_info (decl, name);
4456
  vi->offset = 0;
4457
  vi->may_have_pointers = could_have_pointers (decl);
4458
  if (!declsize
4459
      || !host_integerp (declsize, 1))
4460
    {
4461
      vi->is_unknown_size_var = true;
4462
      vi->fullsize = ~0;
4463
      vi->size = ~0;
4464
    }
4465
  else
4466
    {
4467
      vi->fullsize = TREE_INT_CST_LOW (declsize);
4468
      vi->size = vi->fullsize;
4469
    }
4470
 
4471
  insert_vi_for_tree (vi->decl, vi);
4472
  if (vi->is_global_var
4473
      && (!flag_whole_program || !in_ipa_mode)
4474
      && vi->may_have_pointers)
4475
    {
4476
      if (POINTER_TYPE_P (TREE_TYPE (decl))
4477
          && TYPE_RESTRICT (TREE_TYPE (decl)))
4478
        make_constraint_from_restrict (vi, "GLOBAL_RESTRICT");
4479
      make_copy_constraint (vi, nonlocal_id);
4480
    }
4481
 
4482
  stats.total_vars++;
4483
  if (use_field_sensitive
4484
      && !vi->is_unknown_size_var
4485
      && var_can_have_subvars (decl)
4486
      && VEC_length (fieldoff_s, fieldstack) > 1
4487
      && VEC_length (fieldoff_s, fieldstack) <= MAX_FIELDS_FOR_FIELD_SENSITIVE)
4488
    {
4489
      fieldoff_s *fo = NULL;
4490
      bool notokay = false;
4491
      unsigned int i;
4492
 
4493
      for (i = 0; !notokay && VEC_iterate (fieldoff_s, fieldstack, i, fo); i++)
4494
        {
4495
          if (fo->has_unknown_size
4496
              || fo->offset < 0)
4497
            {
4498
              notokay = true;
4499
              break;
4500
            }
4501
        }
4502
 
4503
      /* We can't sort them if we have a field with a variable sized type,
4504
         which will make notokay = true.  In that case, we are going to return
4505
         without creating varinfos for the fields anyway, so sorting them is a
4506
         waste to boot.  */
4507
      if (!notokay)
4508
        {
4509
          sort_fieldstack (fieldstack);
4510
          /* Due to some C++ FE issues, like PR 22488, we might end up
4511
             what appear to be overlapping fields even though they,
4512
             in reality, do not overlap.  Until the C++ FE is fixed,
4513
             we will simply disable field-sensitivity for these cases.  */
4514
          notokay = check_for_overlaps (fieldstack);
4515
        }
4516
 
4517
 
4518
      if (VEC_length (fieldoff_s, fieldstack) != 0)
4519
        fo = VEC_index (fieldoff_s, fieldstack, 0);
4520
 
4521
      if (fo == NULL || notokay)
4522
        {
4523
          vi->is_unknown_size_var = 1;
4524
          vi->fullsize = ~0;
4525
          vi->size = ~0;
4526
          vi->is_full_var = true;
4527
          VEC_free (fieldoff_s, heap, fieldstack);
4528
          return vi->id;
4529
        }
4530
 
4531
      vi->size = fo->size;
4532
      vi->offset = fo->offset;
4533
      vi->may_have_pointers = fo->may_have_pointers;
4534
      if (vi->is_global_var
4535
          && (!flag_whole_program || !in_ipa_mode)
4536
          && vi->may_have_pointers)
4537
        {
4538
          if (fo->only_restrict_pointers)
4539
            make_constraint_from_restrict (vi, "GLOBAL_RESTRICT");
4540
        }
4541
      for (i = VEC_length (fieldoff_s, fieldstack) - 1;
4542
           i >= 1 && VEC_iterate (fieldoff_s, fieldstack, i, fo);
4543
           i--)
4544
        {
4545
          varinfo_t newvi;
4546
          const char *newname = "NULL";
4547
          char *tempname;
4548
 
4549
          if (dump_file)
4550
            {
4551
              asprintf (&tempname, "%s." HOST_WIDE_INT_PRINT_DEC
4552
                        "+" HOST_WIDE_INT_PRINT_DEC,
4553
                        vi->name, fo->offset, fo->size);
4554
              newname = ggc_strdup (tempname);
4555
              free (tempname);
4556
            }
4557
          newvi = new_var_info (decl, newname);
4558
          newvi->offset = fo->offset;
4559
          newvi->size = fo->size;
4560
          newvi->fullsize = vi->fullsize;
4561
          newvi->may_have_pointers = fo->may_have_pointers;
4562
          insert_into_field_list (vi, newvi);
4563
          if ((newvi->is_global_var || TREE_CODE (decl) == PARM_DECL)
4564
              && newvi->may_have_pointers)
4565
            {
4566
               if (fo->only_restrict_pointers)
4567
                 make_constraint_from_restrict (newvi, "GLOBAL_RESTRICT");
4568
               if (newvi->is_global_var && !in_ipa_mode)
4569
                 make_copy_constraint (newvi, nonlocal_id);
4570
            }
4571
 
4572
          stats.total_vars++;
4573
        }
4574
    }
4575
  else
4576
    vi->is_full_var = true;
4577
 
4578
  VEC_free (fieldoff_s, heap, fieldstack);
4579
 
4580
  return vi->id;
4581
}
4582
 
4583
/* Print out the points-to solution for VAR to FILE.  */
4584
 
4585
static void
4586
dump_solution_for_var (FILE *file, unsigned int var)
4587
{
4588
  varinfo_t vi = get_varinfo (var);
4589
  unsigned int i;
4590
  bitmap_iterator bi;
4591
 
4592
  if (find (var) != var)
4593
    {
4594
      varinfo_t vipt = get_varinfo (find (var));
4595
      fprintf (file, "%s = same as %s\n", vi->name, vipt->name);
4596
    }
4597
  else
4598
    {
4599
      fprintf (file, "%s = { ", vi->name);
4600
      EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, i, bi)
4601
        {
4602
          fprintf (file, "%s ", get_varinfo (i)->name);
4603
        }
4604
      fprintf (file, "}\n");
4605
    }
4606
}
4607
 
4608
/* Print the points-to solution for VAR to stdout.  */
4609
 
4610
void
4611
debug_solution_for_var (unsigned int var)
4612
{
4613
  dump_solution_for_var (stdout, var);
4614
}
4615
 
4616
/* Create varinfo structures for all of the variables in the
4617
   function for intraprocedural mode.  */
4618
 
4619
static void
4620
intra_create_variable_infos (void)
4621
{
4622
  tree t;
4623
 
4624
  /* For each incoming pointer argument arg, create the constraint ARG
4625
     = NONLOCAL or a dummy variable if flag_argument_noalias is set.  */
4626
  for (t = DECL_ARGUMENTS (current_function_decl); t; t = TREE_CHAIN (t))
4627
    {
4628
      varinfo_t p;
4629
 
4630
      if (!could_have_pointers (t))
4631
        continue;
4632
 
4633
      /* For restrict qualified pointers to objects passed by
4634
         reference build a real representative for the pointed-to object.  */
4635
      if (DECL_BY_REFERENCE (t)
4636
          && POINTER_TYPE_P (TREE_TYPE (t))
4637
          && TYPE_RESTRICT (TREE_TYPE (t)))
4638
        {
4639
          struct constraint_expr lhsc, rhsc;
4640
          varinfo_t vi;
4641
          tree heapvar = heapvar_lookup (t, 0);
4642
          if (heapvar == NULL_TREE)
4643
            {
4644
              var_ann_t ann;
4645
              heapvar = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (t)),
4646
                                            "PARM_NOALIAS");
4647
              DECL_EXTERNAL (heapvar) = 1;
4648
              heapvar_insert (t, 0, heapvar);
4649
              ann = get_var_ann (heapvar);
4650
              ann->is_heapvar = 1;
4651
            }
4652
          if (gimple_referenced_vars (cfun))
4653
            add_referenced_var (heapvar);
4654
          lhsc.var = get_vi_for_tree (t)->id;
4655
          lhsc.type = SCALAR;
4656
          lhsc.offset = 0;
4657
          rhsc.var = (vi = get_vi_for_tree (heapvar))->id;
4658
          rhsc.type = ADDRESSOF;
4659
          rhsc.offset = 0;
4660
          process_constraint (new_constraint (lhsc, rhsc));
4661
          vi->is_restrict_var = 1;
4662
          continue;
4663
        }
4664
 
4665
      for (p = get_vi_for_tree (t); p; p = p->next)
4666
        if (p->may_have_pointers)
4667
          make_constraint_from (p, nonlocal_id);
4668
      if (POINTER_TYPE_P (TREE_TYPE (t))
4669
          && TYPE_RESTRICT (TREE_TYPE (t)))
4670
        make_constraint_from_restrict (get_vi_for_tree (t), "PARM_RESTRICT");
4671
    }
4672
 
4673
  /* Add a constraint for a result decl that is passed by reference.  */
4674
  if (DECL_RESULT (cfun->decl)
4675
      && DECL_BY_REFERENCE (DECL_RESULT (cfun->decl)))
4676
    {
4677
      varinfo_t p, result_vi = get_vi_for_tree (DECL_RESULT (cfun->decl));
4678
 
4679
      for (p = result_vi; p; p = p->next)
4680
        make_constraint_from (p, nonlocal_id);
4681
    }
4682
 
4683
  /* Add a constraint for the incoming static chain parameter.  */
4684
  if (cfun->static_chain_decl != NULL_TREE)
4685
    {
4686
      varinfo_t p, chain_vi = get_vi_for_tree (cfun->static_chain_decl);
4687
 
4688
      for (p = chain_vi; p; p = p->next)
4689
        make_constraint_from (p, nonlocal_id);
4690
    }
4691
}
4692
 
4693
/* Structure used to put solution bitmaps in a hashtable so they can
4694
   be shared among variables with the same points-to set.  */
4695
 
4696
typedef struct shared_bitmap_info
4697
{
4698
  bitmap pt_vars;
4699
  hashval_t hashcode;
4700
} *shared_bitmap_info_t;
4701
typedef const struct shared_bitmap_info *const_shared_bitmap_info_t;
4702
 
4703
static htab_t shared_bitmap_table;
4704
 
4705
/* Hash function for a shared_bitmap_info_t */
4706
 
4707
static hashval_t
4708
shared_bitmap_hash (const void *p)
4709
{
4710
  const_shared_bitmap_info_t const bi = (const_shared_bitmap_info_t) p;
4711
  return bi->hashcode;
4712
}
4713
 
4714
/* Equality function for two shared_bitmap_info_t's. */
4715
 
4716
static int
4717
shared_bitmap_eq (const void *p1, const void *p2)
4718
{
4719
  const_shared_bitmap_info_t const sbi1 = (const_shared_bitmap_info_t) p1;
4720
  const_shared_bitmap_info_t const sbi2 = (const_shared_bitmap_info_t) p2;
4721
  return bitmap_equal_p (sbi1->pt_vars, sbi2->pt_vars);
4722
}
4723
 
4724
/* Lookup a bitmap in the shared bitmap hashtable, and return an already
4725
   existing instance if there is one, NULL otherwise.  */
4726
 
4727
static bitmap
4728
shared_bitmap_lookup (bitmap pt_vars)
4729
{
4730
  void **slot;
4731
  struct shared_bitmap_info sbi;
4732
 
4733
  sbi.pt_vars = pt_vars;
4734
  sbi.hashcode = bitmap_hash (pt_vars);
4735
 
4736
  slot = htab_find_slot_with_hash (shared_bitmap_table, &sbi,
4737
                                   sbi.hashcode, NO_INSERT);
4738
  if (!slot)
4739
    return NULL;
4740
  else
4741
    return ((shared_bitmap_info_t) *slot)->pt_vars;
4742
}
4743
 
4744
 
4745
/* Add a bitmap to the shared bitmap hashtable.  */
4746
 
4747
static void
4748
shared_bitmap_add (bitmap pt_vars)
4749
{
4750
  void **slot;
4751
  shared_bitmap_info_t sbi = XNEW (struct shared_bitmap_info);
4752
 
4753
  sbi->pt_vars = pt_vars;
4754
  sbi->hashcode = bitmap_hash (pt_vars);
4755
 
4756
  slot = htab_find_slot_with_hash (shared_bitmap_table, sbi,
4757
                                   sbi->hashcode, INSERT);
4758
  gcc_assert (!*slot);
4759
  *slot = (void *) sbi;
4760
}
4761
 
4762
 
4763
/* Set bits in INTO corresponding to the variable uids in solution set FROM.  */
4764
 
4765
static void
4766
set_uids_in_ptset (bitmap into, bitmap from, struct pt_solution *pt)
4767
{
4768
  unsigned int i;
4769
  bitmap_iterator bi;
4770
 
4771
  EXECUTE_IF_SET_IN_BITMAP (from, 0, i, bi)
4772
    {
4773
      varinfo_t vi = get_varinfo (i);
4774
 
4775
      /* The only artificial variables that are allowed in a may-alias
4776
         set are heap variables.  */
4777
      if (vi->is_artificial_var && !vi->is_heap_var)
4778
        continue;
4779
 
4780
      if (TREE_CODE (vi->decl) == VAR_DECL
4781
          || TREE_CODE (vi->decl) == PARM_DECL
4782
          || TREE_CODE (vi->decl) == RESULT_DECL)
4783
        {
4784
          /* Add the decl to the points-to set.  Note that the points-to
4785
             set contains global variables.  */
4786
          bitmap_set_bit (into, DECL_UID (vi->decl));
4787
          if (vi->is_global_var)
4788
            pt->vars_contains_global = true;
4789
        }
4790
    }
4791
}
4792
 
4793
 
4794
/* Compute the points-to solution *PT for the variable VI.  */
4795
 
4796
static void
4797
find_what_var_points_to (varinfo_t orig_vi, struct pt_solution *pt)
4798
{
4799
  unsigned int i;
4800
  bitmap_iterator bi;
4801
  bitmap finished_solution;
4802
  bitmap result;
4803
  varinfo_t vi;
4804
 
4805
  memset (pt, 0, sizeof (struct pt_solution));
4806
 
4807
  /* This variable may have been collapsed, let's get the real
4808
     variable.  */
4809
  vi = get_varinfo (find (orig_vi->id));
4810
 
4811
  /* Translate artificial variables into SSA_NAME_PTR_INFO
4812
     attributes.  */
4813
  EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, i, bi)
4814
    {
4815
      varinfo_t vi = get_varinfo (i);
4816
 
4817
      if (vi->is_artificial_var)
4818
        {
4819
          if (vi->id == nothing_id)
4820
            pt->null = 1;
4821
          else if (vi->id == escaped_id)
4822
            pt->escaped = 1;
4823
          else if (vi->id == callused_id)
4824
            gcc_unreachable ();
4825
          else if (vi->id == nonlocal_id)
4826
            pt->nonlocal = 1;
4827
          else if (vi->is_heap_var)
4828
            /* We represent heapvars in the points-to set properly.  */
4829
            ;
4830
          else if (vi->id == readonly_id)
4831
            /* Nobody cares.  */
4832
            ;
4833
          else if (vi->id == anything_id
4834
                   || vi->id == integer_id)
4835
            pt->anything = 1;
4836
        }
4837
      if (vi->is_restrict_var)
4838
        pt->vars_contains_restrict = true;
4839
    }
4840
 
4841
  /* Instead of doing extra work, simply do not create
4842
     elaborate points-to information for pt_anything pointers.  */
4843
  if (pt->anything
4844
      && (orig_vi->is_artificial_var
4845
          || !pt->vars_contains_restrict))
4846
    return;
4847
 
4848
  /* Share the final set of variables when possible.  */
4849
  finished_solution = BITMAP_GGC_ALLOC ();
4850
  stats.points_to_sets_created++;
4851
 
4852
  set_uids_in_ptset (finished_solution, vi->solution, pt);
4853
  result = shared_bitmap_lookup (finished_solution);
4854
  if (!result)
4855
    {
4856
      shared_bitmap_add (finished_solution);
4857
      pt->vars = finished_solution;
4858
    }
4859
  else
4860
    {
4861
      pt->vars = result;
4862
      bitmap_clear (finished_solution);
4863
    }
4864
}
4865
 
4866
/* Given a pointer variable P, fill in its points-to set.  */
4867
 
4868
static void
4869
find_what_p_points_to (tree p)
4870
{
4871
  struct ptr_info_def *pi;
4872
  tree lookup_p = p;
4873
  varinfo_t vi;
4874
 
4875
  /* For parameters, get at the points-to set for the actual parm
4876
     decl.  */
4877
  if (TREE_CODE (p) == SSA_NAME
4878
      && TREE_CODE (SSA_NAME_VAR (p)) == PARM_DECL
4879
      && SSA_NAME_IS_DEFAULT_DEF (p))
4880
    lookup_p = SSA_NAME_VAR (p);
4881
 
4882
  vi = lookup_vi_for_tree (lookup_p);
4883
  if (!vi)
4884
    return;
4885
 
4886
  pi = get_ptr_info (p);
4887
  find_what_var_points_to (vi, &pi->pt);
4888
}
4889
 
4890
 
4891
/* Query statistics for points-to solutions.  */
4892
 
4893
static struct {
4894
  unsigned HOST_WIDE_INT pt_solution_includes_may_alias;
4895
  unsigned HOST_WIDE_INT pt_solution_includes_no_alias;
4896
  unsigned HOST_WIDE_INT pt_solutions_intersect_may_alias;
4897
  unsigned HOST_WIDE_INT pt_solutions_intersect_no_alias;
4898
} pta_stats;
4899
 
4900
void
4901
dump_pta_stats (FILE *s)
4902
{
4903
  fprintf (s, "\nPTA query stats:\n");
4904
  fprintf (s, "  pt_solution_includes: "
4905
           HOST_WIDE_INT_PRINT_DEC" disambiguations, "
4906
           HOST_WIDE_INT_PRINT_DEC" queries\n",
4907
           pta_stats.pt_solution_includes_no_alias,
4908
           pta_stats.pt_solution_includes_no_alias
4909
           + pta_stats.pt_solution_includes_may_alias);
4910
  fprintf (s, "  pt_solutions_intersect: "
4911
           HOST_WIDE_INT_PRINT_DEC" disambiguations, "
4912
           HOST_WIDE_INT_PRINT_DEC" queries\n",
4913
           pta_stats.pt_solutions_intersect_no_alias,
4914
           pta_stats.pt_solutions_intersect_no_alias
4915
           + pta_stats.pt_solutions_intersect_may_alias);
4916
}
4917
 
4918
 
4919
/* Reset the points-to solution *PT to a conservative default
4920
   (point to anything).  */
4921
 
4922
void
4923
pt_solution_reset (struct pt_solution *pt)
4924
{
4925
  memset (pt, 0, sizeof (struct pt_solution));
4926
  pt->anything = true;
4927
}
4928
 
4929
/* Set the points-to solution *PT to point only to the variables
4930
   in VARS.  */
4931
 
4932
void
4933
pt_solution_set (struct pt_solution *pt, bitmap vars)
4934
{
4935
  bitmap_iterator bi;
4936
  unsigned i;
4937
 
4938
  memset (pt, 0, sizeof (struct pt_solution));
4939
  pt->vars = vars;
4940
  EXECUTE_IF_SET_IN_BITMAP (vars, 0, i, bi)
4941
    {
4942
      tree var = referenced_var_lookup (i);
4943
      if (is_global_var (var))
4944
        {
4945
          pt->vars_contains_global = true;
4946
          break;
4947
        }
4948
    }
4949
}
4950
 
4951
/* Return true if the points-to solution *PT is empty.  */
4952
 
4953
static bool
4954
pt_solution_empty_p (struct pt_solution *pt)
4955
{
4956
  if (pt->anything
4957
      || pt->nonlocal)
4958
    return false;
4959
 
4960
  if (pt->vars
4961
      && !bitmap_empty_p (pt->vars))
4962
    return false;
4963
 
4964
  /* If the solution includes ESCAPED, check if that is empty.  */
4965
  if (pt->escaped
4966
      && !pt_solution_empty_p (&cfun->gimple_df->escaped))
4967
    return false;
4968
 
4969
  return true;
4970
}
4971
 
4972
/* Return true if the points-to solution *PT includes global memory.  */
4973
 
4974
bool
4975
pt_solution_includes_global (struct pt_solution *pt)
4976
{
4977
  if (pt->anything
4978
      || pt->nonlocal
4979
      || pt->vars_contains_global)
4980
    return true;
4981
 
4982
  if (pt->escaped)
4983
    return pt_solution_includes_global (&cfun->gimple_df->escaped);
4984
 
4985
  return false;
4986
}
4987
 
4988
/* Return true if the points-to solution *PT includes the variable
4989
   declaration DECL.  */
4990
 
4991
static bool
4992
pt_solution_includes_1 (struct pt_solution *pt, const_tree decl)
4993
{
4994
  if (pt->anything)
4995
    return true;
4996
 
4997
  if (pt->nonlocal
4998
      && is_global_var (decl))
4999
    return true;
5000
 
5001
  if (pt->vars
5002
      && bitmap_bit_p (pt->vars, DECL_UID (decl)))
5003
    return true;
5004
 
5005
  /* If the solution includes ESCAPED, check it.  */
5006
  if (pt->escaped
5007
      && pt_solution_includes_1 (&cfun->gimple_df->escaped, decl))
5008
    return true;
5009
 
5010
  return false;
5011
}
5012
 
5013
bool
5014
pt_solution_includes (struct pt_solution *pt, const_tree decl)
5015
{
5016
  bool res = pt_solution_includes_1 (pt, decl);
5017
  if (res)
5018
    ++pta_stats.pt_solution_includes_may_alias;
5019
  else
5020
    ++pta_stats.pt_solution_includes_no_alias;
5021
  return res;
5022
}
5023
 
5024
/* Return true if both points-to solutions PT1 and PT2 have a non-empty
5025
   intersection.  */
5026
 
5027
static bool
5028
pt_solutions_intersect_1 (struct pt_solution *pt1, struct pt_solution *pt2)
5029
{
5030
  if (pt1->anything || pt2->anything)
5031
    return true;
5032
 
5033
  /* If either points to unknown global memory and the other points to
5034
     any global memory they alias.  */
5035
  if ((pt1->nonlocal
5036
       && (pt2->nonlocal
5037
           || pt2->vars_contains_global))
5038
      || (pt2->nonlocal
5039
          && pt1->vars_contains_global))
5040
    return true;
5041
 
5042
  /* Check the escaped solution if required.  */
5043
  if ((pt1->escaped || pt2->escaped)
5044
      && !pt_solution_empty_p (&cfun->gimple_df->escaped))
5045
    {
5046
      /* If both point to escaped memory and that solution
5047
         is not empty they alias.  */
5048
      if (pt1->escaped && pt2->escaped)
5049
        return true;
5050
 
5051
      /* If either points to escaped memory see if the escaped solution
5052
         intersects with the other.  */
5053
      if ((pt1->escaped
5054
           && pt_solutions_intersect_1 (&cfun->gimple_df->escaped, pt2))
5055
          || (pt2->escaped
5056
              && pt_solutions_intersect_1 (&cfun->gimple_df->escaped, pt1)))
5057
        return true;
5058
    }
5059
 
5060
  /* Now both pointers alias if their points-to solution intersects.  */
5061
  return (pt1->vars
5062
          && pt2->vars
5063
          && bitmap_intersect_p (pt1->vars, pt2->vars));
5064
}
5065
 
5066
bool
5067
pt_solutions_intersect (struct pt_solution *pt1, struct pt_solution *pt2)
5068
{
5069
  bool res = pt_solutions_intersect_1 (pt1, pt2);
5070
  if (res)
5071
    ++pta_stats.pt_solutions_intersect_may_alias;
5072
  else
5073
    ++pta_stats.pt_solutions_intersect_no_alias;
5074
  return res;
5075
}
5076
 
5077
/* Return true if both points-to solutions PT1 and PT2 for two restrict
5078
   qualified pointers are possibly based on the same pointer.  */
5079
 
5080
bool
5081
pt_solutions_same_restrict_base (struct pt_solution *pt1,
5082
                                 struct pt_solution *pt2)
5083
{
5084
  /* If we deal with points-to solutions of two restrict qualified
5085
     pointers solely rely on the pointed-to variable bitmap intersection.
5086
     For two pointers that are based on each other the bitmaps will
5087
     intersect.  */
5088
  if (pt1->vars_contains_restrict
5089
      && pt2->vars_contains_restrict)
5090
    {
5091
      gcc_assert (pt1->vars && pt2->vars);
5092
      return bitmap_intersect_p (pt1->vars, pt2->vars);
5093
    }
5094
 
5095
  return true;
5096
}
5097
 
5098
 
5099
/* Dump points-to information to OUTFILE.  */
5100
 
5101
static void
5102
dump_sa_points_to_info (FILE *outfile)
5103
{
5104
  unsigned int i;
5105
 
5106
  fprintf (outfile, "\nPoints-to sets\n\n");
5107
 
5108
  if (dump_flags & TDF_STATS)
5109
    {
5110
      fprintf (outfile, "Stats:\n");
5111
      fprintf (outfile, "Total vars:               %d\n", stats.total_vars);
5112
      fprintf (outfile, "Non-pointer vars:          %d\n",
5113
               stats.nonpointer_vars);
5114
      fprintf (outfile, "Statically unified vars:  %d\n",
5115
               stats.unified_vars_static);
5116
      fprintf (outfile, "Dynamically unified vars: %d\n",
5117
               stats.unified_vars_dynamic);
5118
      fprintf (outfile, "Iterations:               %d\n", stats.iterations);
5119
      fprintf (outfile, "Number of edges:          %d\n", stats.num_edges);
5120
      fprintf (outfile, "Number of implicit edges: %d\n",
5121
               stats.num_implicit_edges);
5122
    }
5123
 
5124
  for (i = 0; i < VEC_length (varinfo_t, varmap); i++)
5125
    dump_solution_for_var (outfile, i);
5126
}
5127
 
5128
 
5129
/* Debug points-to information to stderr.  */
5130
 
5131
void
5132
debug_sa_points_to_info (void)
5133
{
5134
  dump_sa_points_to_info (stderr);
5135
}
5136
 
5137
 
5138
/* Initialize the always-existing constraint variables for NULL
5139
   ANYTHING, READONLY, and INTEGER */
5140
 
5141
static void
5142
init_base_vars (void)
5143
{
5144
  struct constraint_expr lhs, rhs;
5145
  varinfo_t var_anything;
5146
  varinfo_t var_nothing;
5147
  varinfo_t var_readonly;
5148
  varinfo_t var_escaped;
5149
  varinfo_t var_nonlocal;
5150
  varinfo_t var_callused;
5151
  varinfo_t var_storedanything;
5152
  varinfo_t var_integer;
5153
 
5154
  /* Create the NULL variable, used to represent that a variable points
5155
     to NULL.  */
5156
  var_nothing = new_var_info (NULL_TREE, "NULL");
5157
  gcc_assert (var_nothing->id == nothing_id);
5158
  var_nothing->is_artificial_var = 1;
5159
  var_nothing->offset = 0;
5160
  var_nothing->size = ~0;
5161
  var_nothing->fullsize = ~0;
5162
  var_nothing->is_special_var = 1;
5163
 
5164
  /* Create the ANYTHING variable, used to represent that a variable
5165
     points to some unknown piece of memory.  */
5166
  var_anything = new_var_info (NULL_TREE, "ANYTHING");
5167
  gcc_assert (var_anything->id == anything_id);
5168
  var_anything->is_artificial_var = 1;
5169
  var_anything->size = ~0;
5170
  var_anything->offset = 0;
5171
  var_anything->next = NULL;
5172
  var_anything->fullsize = ~0;
5173
  var_anything->is_special_var = 1;
5174
 
5175
  /* Anything points to anything.  This makes deref constraints just
5176
     work in the presence of linked list and other p = *p type loops,
5177
     by saying that *ANYTHING = ANYTHING. */
5178
  lhs.type = SCALAR;
5179
  lhs.var = anything_id;
5180
  lhs.offset = 0;
5181
  rhs.type = ADDRESSOF;
5182
  rhs.var = anything_id;
5183
  rhs.offset = 0;
5184
 
5185
  /* This specifically does not use process_constraint because
5186
     process_constraint ignores all anything = anything constraints, since all
5187
     but this one are redundant.  */
5188
  VEC_safe_push (constraint_t, heap, constraints, new_constraint (lhs, rhs));
5189
 
5190
  /* Create the READONLY variable, used to represent that a variable
5191
     points to readonly memory.  */
5192
  var_readonly = new_var_info (NULL_TREE, "READONLY");
5193
  gcc_assert (var_readonly->id == readonly_id);
5194
  var_readonly->is_artificial_var = 1;
5195
  var_readonly->offset = 0;
5196
  var_readonly->size = ~0;
5197
  var_readonly->fullsize = ~0;
5198
  var_readonly->next = NULL;
5199
  var_readonly->is_special_var = 1;
5200
 
5201
  /* readonly memory points to anything, in order to make deref
5202
     easier.  In reality, it points to anything the particular
5203
     readonly variable can point to, but we don't track this
5204
     separately. */
5205
  lhs.type = SCALAR;
5206
  lhs.var = readonly_id;
5207
  lhs.offset = 0;
5208
  rhs.type = ADDRESSOF;
5209
  rhs.var = readonly_id;  /* FIXME */
5210
  rhs.offset = 0;
5211
  process_constraint (new_constraint (lhs, rhs));
5212
 
5213
  /* Create the ESCAPED variable, used to represent the set of escaped
5214
     memory.  */
5215
  var_escaped = new_var_info (NULL_TREE, "ESCAPED");
5216
  gcc_assert (var_escaped->id == escaped_id);
5217
  var_escaped->is_artificial_var = 1;
5218
  var_escaped->offset = 0;
5219
  var_escaped->size = ~0;
5220
  var_escaped->fullsize = ~0;
5221
  var_escaped->is_special_var = 0;
5222
 
5223
  /* Create the NONLOCAL variable, used to represent the set of nonlocal
5224
     memory.  */
5225
  var_nonlocal = new_var_info (NULL_TREE, "NONLOCAL");
5226
  gcc_assert (var_nonlocal->id == nonlocal_id);
5227
  var_nonlocal->is_artificial_var = 1;
5228
  var_nonlocal->offset = 0;
5229
  var_nonlocal->size = ~0;
5230
  var_nonlocal->fullsize = ~0;
5231
  var_nonlocal->is_special_var = 1;
5232
 
5233
  /* ESCAPED = *ESCAPED, because escaped is may-deref'd at calls, etc.  */
5234
  lhs.type = SCALAR;
5235
  lhs.var = escaped_id;
5236
  lhs.offset = 0;
5237
  rhs.type = DEREF;
5238
  rhs.var = escaped_id;
5239
  rhs.offset = 0;
5240
  process_constraint (new_constraint (lhs, rhs));
5241
 
5242
  /* ESCAPED = ESCAPED + UNKNOWN_OFFSET, because if a sub-field escapes the
5243
     whole variable escapes.  */
5244
  lhs.type = SCALAR;
5245
  lhs.var = escaped_id;
5246
  lhs.offset = 0;
5247
  rhs.type = SCALAR;
5248
  rhs.var = escaped_id;
5249
  rhs.offset = UNKNOWN_OFFSET;
5250
  process_constraint (new_constraint (lhs, rhs));
5251
 
5252
  /* *ESCAPED = NONLOCAL.  This is true because we have to assume
5253
     everything pointed to by escaped points to what global memory can
5254
     point to.  */
5255
  lhs.type = DEREF;
5256
  lhs.var = escaped_id;
5257
  lhs.offset = 0;
5258
  rhs.type = SCALAR;
5259
  rhs.var = nonlocal_id;
5260
  rhs.offset = 0;
5261
  process_constraint (new_constraint (lhs, rhs));
5262
 
5263
  /* NONLOCAL = &NONLOCAL, NONLOCAL = &ESCAPED.  This is true because
5264
     global memory may point to global memory and escaped memory.  */
5265
  lhs.type = SCALAR;
5266
  lhs.var = nonlocal_id;
5267
  lhs.offset = 0;
5268
  rhs.type = ADDRESSOF;
5269
  rhs.var = nonlocal_id;
5270
  rhs.offset = 0;
5271
  process_constraint (new_constraint (lhs, rhs));
5272
  rhs.type = ADDRESSOF;
5273
  rhs.var = escaped_id;
5274
  rhs.offset = 0;
5275
  process_constraint (new_constraint (lhs, rhs));
5276
 
5277
  /* Create the CALLUSED variable, used to represent the set of call-used
5278
     memory.  */
5279
  var_callused = new_var_info (NULL_TREE, "CALLUSED");
5280
  gcc_assert (var_callused->id == callused_id);
5281
  var_callused->is_artificial_var = 1;
5282
  var_callused->offset = 0;
5283
  var_callused->size = ~0;
5284
  var_callused->fullsize = ~0;
5285
  var_callused->is_special_var = 0;
5286
 
5287
  /* CALLUSED = *CALLUSED, because call-used is may-deref'd at calls, etc.  */
5288
  lhs.type = SCALAR;
5289
  lhs.var = callused_id;
5290
  lhs.offset = 0;
5291
  rhs.type = DEREF;
5292
  rhs.var = callused_id;
5293
  rhs.offset = 0;
5294
  process_constraint (new_constraint (lhs, rhs));
5295
 
5296
  /* CALLUSED = CALLUSED + UNKNOWN, because if a sub-field is call-used the
5297
     whole variable is call-used.  */
5298
  lhs.type = SCALAR;
5299
  lhs.var = callused_id;
5300
  lhs.offset = 0;
5301
  rhs.type = SCALAR;
5302
  rhs.var = callused_id;
5303
  rhs.offset = UNKNOWN_OFFSET;
5304
  process_constraint (new_constraint (lhs, rhs));
5305
 
5306
  /* Create the STOREDANYTHING variable, used to represent the set of
5307
     variables stored to *ANYTHING.  */
5308
  var_storedanything = new_var_info (NULL_TREE, "STOREDANYTHING");
5309
  gcc_assert (var_storedanything->id == storedanything_id);
5310
  var_storedanything->is_artificial_var = 1;
5311
  var_storedanything->offset = 0;
5312
  var_storedanything->size = ~0;
5313
  var_storedanything->fullsize = ~0;
5314
  var_storedanything->is_special_var = 0;
5315
 
5316
  /* Create the INTEGER variable, used to represent that a variable points
5317
     to what an INTEGER "points to".  */
5318
  var_integer = new_var_info (NULL_TREE, "INTEGER");
5319
  gcc_assert (var_integer->id == integer_id);
5320
  var_integer->is_artificial_var = 1;
5321
  var_integer->size = ~0;
5322
  var_integer->fullsize = ~0;
5323
  var_integer->offset = 0;
5324
  var_integer->next = NULL;
5325
  var_integer->is_special_var = 1;
5326
 
5327
  /* INTEGER = ANYTHING, because we don't know where a dereference of
5328
     a random integer will point to.  */
5329
  lhs.type = SCALAR;
5330
  lhs.var = integer_id;
5331
  lhs.offset = 0;
5332
  rhs.type = ADDRESSOF;
5333
  rhs.var = anything_id;
5334
  rhs.offset = 0;
5335
  process_constraint (new_constraint (lhs, rhs));
5336
}
5337
 
5338
/* Initialize things necessary to perform PTA */
5339
 
5340
static void
5341
init_alias_vars (void)
5342
{
5343
  use_field_sensitive = (MAX_FIELDS_FOR_FIELD_SENSITIVE > 1);
5344
 
5345
  bitmap_obstack_initialize (&pta_obstack);
5346
  bitmap_obstack_initialize (&oldpta_obstack);
5347
  bitmap_obstack_initialize (&predbitmap_obstack);
5348
 
5349
  constraint_pool = create_alloc_pool ("Constraint pool",
5350
                                       sizeof (struct constraint), 30);
5351
  variable_info_pool = create_alloc_pool ("Variable info pool",
5352
                                          sizeof (struct variable_info), 30);
5353
  constraints = VEC_alloc (constraint_t, heap, 8);
5354
  varmap = VEC_alloc (varinfo_t, heap, 8);
5355
  vi_for_tree = pointer_map_create ();
5356
 
5357
  memset (&stats, 0, sizeof (stats));
5358
  shared_bitmap_table = htab_create (511, shared_bitmap_hash,
5359
                                     shared_bitmap_eq, free);
5360
  init_base_vars ();
5361
}
5362
 
5363
/* Remove the REF and ADDRESS edges from GRAPH, as well as all the
5364
   predecessor edges.  */
5365
 
5366
static void
5367
remove_preds_and_fake_succs (constraint_graph_t graph)
5368
{
5369
  unsigned int i;
5370
 
5371
  /* Clear the implicit ref and address nodes from the successor
5372
     lists.  */
5373
  for (i = 0; i < FIRST_REF_NODE; i++)
5374
    {
5375
      if (graph->succs[i])
5376
        bitmap_clear_range (graph->succs[i], FIRST_REF_NODE,
5377
                            FIRST_REF_NODE * 2);
5378
    }
5379
 
5380
  /* Free the successor list for the non-ref nodes.  */
5381
  for (i = FIRST_REF_NODE; i < graph->size; i++)
5382
    {
5383
      if (graph->succs[i])
5384
        BITMAP_FREE (graph->succs[i]);
5385
    }
5386
 
5387
  /* Now reallocate the size of the successor list as, and blow away
5388
     the predecessor bitmaps.  */
5389
  graph->size = VEC_length (varinfo_t, varmap);
5390
  graph->succs = XRESIZEVEC (bitmap, graph->succs, graph->size);
5391
 
5392
  free (graph->implicit_preds);
5393
  graph->implicit_preds = NULL;
5394
  free (graph->preds);
5395
  graph->preds = NULL;
5396
  bitmap_obstack_release (&predbitmap_obstack);
5397
}
5398
 
5399
/* Initialize the heapvar for statement mapping.  */
5400
 
5401
static void
5402
init_alias_heapvars (void)
5403
{
5404
  if (!heapvar_for_stmt)
5405
    heapvar_for_stmt = htab_create_ggc (11, tree_map_hash, heapvar_map_eq,
5406
                                        NULL);
5407
}
5408
 
5409
/* Delete the heapvar for statement mapping.  */
5410
 
5411
void
5412
delete_alias_heapvars (void)
5413
{
5414
  if (heapvar_for_stmt)
5415
    htab_delete (heapvar_for_stmt);
5416
  heapvar_for_stmt = NULL;
5417
}
5418
 
5419
/* Solve the constraint set.  */
5420
 
5421
static void
5422
solve_constraints (void)
5423
{
5424
  struct scc_info *si;
5425
 
5426
  if (dump_file)
5427
    {
5428
      fprintf (dump_file, "Points-to analysis\n\nConstraints:\n\n");
5429
      dump_constraints (dump_file);
5430
    }
5431
 
5432
  if (dump_file)
5433
    fprintf (dump_file,
5434
             "\nCollapsing static cycles and doing variable "
5435
             "substitution\n");
5436
 
5437
  init_graph (VEC_length (varinfo_t, varmap) * 2);
5438
 
5439
  if (dump_file)
5440
    fprintf (dump_file, "Building predecessor graph\n");
5441
  build_pred_graph ();
5442
 
5443
  if (dump_file)
5444
    fprintf (dump_file, "Detecting pointer and location "
5445
             "equivalences\n");
5446
  si = perform_var_substitution (graph);
5447
 
5448
  if (dump_file)
5449
    fprintf (dump_file, "Rewriting constraints and unifying "
5450
             "variables\n");
5451
  rewrite_constraints (graph, si);
5452
 
5453
  build_succ_graph ();
5454
  free_var_substitution_info (si);
5455
 
5456
  if (dump_file && (dump_flags & TDF_GRAPH))
5457
    dump_constraint_graph (dump_file);
5458
 
5459
  move_complex_constraints (graph);
5460
 
5461
  if (dump_file)
5462
    fprintf (dump_file, "Uniting pointer but not location equivalent "
5463
             "variables\n");
5464
  unite_pointer_equivalences (graph);
5465
 
5466
  if (dump_file)
5467
    fprintf (dump_file, "Finding indirect cycles\n");
5468
  find_indirect_cycles (graph);
5469
 
5470
  /* Implicit nodes and predecessors are no longer necessary at this
5471
     point. */
5472
  remove_preds_and_fake_succs (graph);
5473
 
5474
  if (dump_file)
5475
    fprintf (dump_file, "Solving graph\n");
5476
 
5477
  solve_graph (graph);
5478
 
5479
  if (dump_file)
5480
    dump_sa_points_to_info (dump_file);
5481
}
5482
 
5483
/* Create points-to sets for the current function.  See the comments
5484
   at the start of the file for an algorithmic overview.  */
5485
 
5486
static void
5487
compute_points_to_sets (void)
5488
{
5489
  basic_block bb;
5490
  unsigned i;
5491
  varinfo_t vi;
5492
 
5493
  timevar_push (TV_TREE_PTA);
5494
 
5495
  init_alias_vars ();
5496
  init_alias_heapvars ();
5497
 
5498
  intra_create_variable_infos ();
5499
 
5500
  /* Now walk all statements and derive aliases.  */
5501
  FOR_EACH_BB (bb)
5502
    {
5503
      gimple_stmt_iterator gsi;
5504
 
5505
      for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
5506
        {
5507
          gimple phi = gsi_stmt (gsi);
5508
 
5509
          if (is_gimple_reg (gimple_phi_result (phi)))
5510
            find_func_aliases (phi);
5511
        }
5512
 
5513
      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
5514
        {
5515
          gimple stmt = gsi_stmt (gsi);
5516
 
5517
          find_func_aliases (stmt);
5518
        }
5519
    }
5520
 
5521
  /* From the constraints compute the points-to sets.  */
5522
  solve_constraints ();
5523
 
5524
  /* Compute the points-to sets for ESCAPED and CALLUSED used for
5525
     call-clobber analysis.  */
5526
  find_what_var_points_to (get_varinfo (escaped_id),
5527
                           &cfun->gimple_df->escaped);
5528
  find_what_var_points_to (get_varinfo (callused_id),
5529
                           &cfun->gimple_df->callused);
5530
 
5531
  /* Make sure the ESCAPED solution (which is used as placeholder in
5532
     other solutions) does not reference itself.  This simplifies
5533
     points-to solution queries.  */
5534
  cfun->gimple_df->escaped.escaped = 0;
5535
 
5536
  /* Mark escaped HEAP variables as global.  */
5537
  for (i = 0; VEC_iterate (varinfo_t, varmap, i, vi); ++i)
5538
    if (vi->is_heap_var
5539
        && !vi->is_restrict_var
5540
        && !vi->is_global_var)
5541
      DECL_EXTERNAL (vi->decl) = vi->is_global_var
5542
        = pt_solution_includes (&cfun->gimple_df->escaped, vi->decl);
5543
 
5544
  /* Compute the points-to sets for pointer SSA_NAMEs.  */
5545
  for (i = 0; i < num_ssa_names; ++i)
5546
    {
5547
      tree ptr = ssa_name (i);
5548
      if (ptr
5549
          && POINTER_TYPE_P (TREE_TYPE (ptr)))
5550
        find_what_p_points_to (ptr);
5551
    }
5552
 
5553
  timevar_pop (TV_TREE_PTA);
5554
}
5555
 
5556
 
5557
/* Delete created points-to sets.  */
5558
 
5559
static void
5560
delete_points_to_sets (void)
5561
{
5562
  unsigned int i;
5563
 
5564
  htab_delete (shared_bitmap_table);
5565
  if (dump_file && (dump_flags & TDF_STATS))
5566
    fprintf (dump_file, "Points to sets created:%d\n",
5567
             stats.points_to_sets_created);
5568
 
5569
  pointer_map_destroy (vi_for_tree);
5570
  bitmap_obstack_release (&pta_obstack);
5571
  VEC_free (constraint_t, heap, constraints);
5572
 
5573
  for (i = 0; i < graph->size; i++)
5574
    VEC_free (constraint_t, heap, graph->complex[i]);
5575
  free (graph->complex);
5576
 
5577
  free (graph->rep);
5578
  free (graph->succs);
5579
  free (graph->pe);
5580
  free (graph->pe_rep);
5581
  free (graph->indirect_cycles);
5582
  free (graph);
5583
 
5584
  VEC_free (varinfo_t, heap, varmap);
5585
  free_alloc_pool (variable_info_pool);
5586
  free_alloc_pool (constraint_pool);
5587
}
5588
 
5589
 
5590
/* Compute points-to information for every SSA_NAME pointer in the
5591
   current function and compute the transitive closure of escaped
5592
   variables to re-initialize the call-clobber states of local variables.  */
5593
 
5594
unsigned int
5595
compute_may_aliases (void)
5596
{
5597
  /* For each pointer P_i, determine the sets of variables that P_i may
5598
     point-to.  Compute the reachability set of escaped and call-used
5599
     variables.  */
5600
  compute_points_to_sets ();
5601
 
5602
  /* Debugging dumps.  */
5603
  if (dump_file)
5604
    {
5605
      dump_alias_info (dump_file);
5606
 
5607
      if (dump_flags & TDF_DETAILS)
5608
        dump_referenced_vars (dump_file);
5609
    }
5610
 
5611
  /* Deallocate memory used by aliasing data structures and the internal
5612
     points-to solution.  */
5613
  delete_points_to_sets ();
5614
 
5615
  gcc_assert (!need_ssa_update_p (cfun));
5616
 
5617
  return 0;
5618
}
5619
 
5620
static bool
5621
gate_tree_pta (void)
5622
{
5623
  return flag_tree_pta;
5624
}
5625
 
5626
/* A dummy pass to cause points-to information to be computed via
5627
   TODO_rebuild_alias.  */
5628
 
5629
struct gimple_opt_pass pass_build_alias =
5630
{
5631
 {
5632
  GIMPLE_PASS,
5633
  "alias",                  /* name */
5634
  gate_tree_pta,            /* gate */
5635
  NULL,                     /* execute */
5636
  NULL,                     /* sub */
5637
  NULL,                     /* next */
5638
  0,                        /* static_pass_number */
5639
  TV_NONE,                  /* tv_id */
5640
  PROP_cfg | PROP_ssa,      /* properties_required */
5641
  0,                         /* properties_provided */
5642
  0,                        /* properties_destroyed */
5643
  0,                        /* todo_flags_start */
5644
  TODO_rebuild_alias | TODO_dump_func  /* todo_flags_finish */
5645
 }
5646
};
5647
 
5648
/* A dummy pass to cause points-to information to be computed via
5649
   TODO_rebuild_alias.  */
5650
 
5651
struct gimple_opt_pass pass_build_ealias =
5652
{
5653
 {
5654
  GIMPLE_PASS,
5655
  "ealias",                 /* name */
5656
  gate_tree_pta,            /* gate */
5657
  NULL,                     /* execute */
5658
  NULL,                     /* sub */
5659
  NULL,                     /* next */
5660
  0,                        /* static_pass_number */
5661
  TV_NONE,                  /* tv_id */
5662
  PROP_cfg | PROP_ssa,      /* properties_required */
5663
  0,                         /* properties_provided */
5664
  0,                        /* properties_destroyed */
5665
  0,                        /* todo_flags_start */
5666
  TODO_rebuild_alias | TODO_dump_func  /* todo_flags_finish */
5667
 }
5668
};
5669
 
5670
 
5671
/* Return true if we should execute IPA PTA.  */
5672
static bool
5673
gate_ipa_pta (void)
5674
{
5675
  return (optimize
5676
          && flag_ipa_pta
5677
          /* Don't bother doing anything if the program has errors.  */
5678
          && !(errorcount || sorrycount));
5679
}
5680
 
5681
/* Execute the driver for IPA PTA.  */
5682
static unsigned int
5683
ipa_pta_execute (void)
5684
{
5685
  struct cgraph_node *node;
5686
 
5687
  in_ipa_mode = 1;
5688
 
5689
  init_alias_heapvars ();
5690
  init_alias_vars ();
5691
 
5692
  /* Build the constraints.  */
5693
  for (node = cgraph_nodes; node; node = node->next)
5694
    {
5695
      /* Nodes without a body are not interesting.  Especially do not
5696
         visit clones at this point for now - we get duplicate decls
5697
         there for inline clones at least.  */
5698
      if (!gimple_has_body_p (node->decl)
5699
          || node->clone_of)
5700
        continue;
5701
 
5702
      /* It does not make sense to have graph edges into or out of
5703
         externally visible functions.  There is no extra information
5704
         we can gather from them.  */
5705
      if (node->local.externally_visible)
5706
        continue;
5707
 
5708
      create_function_info_for (node->decl,
5709
                                cgraph_node_name (node));
5710
    }
5711
 
5712
  for (node = cgraph_nodes; node; node = node->next)
5713
    {
5714
      struct function *func;
5715
      basic_block bb;
5716
      tree old_func_decl;
5717
 
5718
      /* Nodes without a body are not interesting.  */
5719
      if (!gimple_has_body_p (node->decl)
5720
          || node->clone_of)
5721
        continue;
5722
 
5723
      if (dump_file)
5724
        fprintf (dump_file,
5725
                 "Generating constraints for %s\n",
5726
                 cgraph_node_name (node));
5727
 
5728
      func = DECL_STRUCT_FUNCTION (node->decl);
5729
      old_func_decl = current_function_decl;
5730
      push_cfun (func);
5731
      current_function_decl = node->decl;
5732
 
5733
      /* For externally visible functions use local constraints for
5734
         their arguments.  For local functions we see all callers
5735
         and thus do not need initial constraints for parameters.  */
5736
      if (node->local.externally_visible)
5737
        intra_create_variable_infos ();
5738
 
5739
      /* Build constriants for the function body.  */
5740
      FOR_EACH_BB_FN (bb, func)
5741
        {
5742
          gimple_stmt_iterator gsi;
5743
 
5744
          for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
5745
               gsi_next (&gsi))
5746
            {
5747
              gimple phi = gsi_stmt (gsi);
5748
 
5749
              if (is_gimple_reg (gimple_phi_result (phi)))
5750
                find_func_aliases (phi);
5751
            }
5752
 
5753
          for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
5754
            {
5755
              gimple stmt = gsi_stmt (gsi);
5756
 
5757
              find_func_aliases (stmt);
5758
            }
5759
        }
5760
 
5761
      current_function_decl = old_func_decl;
5762
      pop_cfun ();
5763
    }
5764
 
5765
  /* From the constraints compute the points-to sets.  */
5766
  solve_constraints ();
5767
 
5768
  delete_points_to_sets ();
5769
 
5770
  in_ipa_mode = 0;
5771
 
5772
  return 0;
5773
}
5774
 
5775
struct simple_ipa_opt_pass pass_ipa_pta =
5776
{
5777
 {
5778
  SIMPLE_IPA_PASS,
5779
  "pta",                                /* name */
5780
  gate_ipa_pta,                 /* gate */
5781
  ipa_pta_execute,                      /* execute */
5782
  NULL,                                 /* sub */
5783
  NULL,                                 /* next */
5784
  0,                                     /* static_pass_number */
5785
  TV_IPA_PTA,                   /* tv_id */
5786
  0,                                     /* properties_required */
5787
  0,                                     /* properties_provided */
5788
  0,                                     /* properties_destroyed */
5789
  0,                                     /* todo_flags_start */
5790
  TODO_update_ssa                       /* todo_flags_finish */
5791
 }
5792
};
5793
 
5794
 
5795
#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.