1 /* Tree based points-to analysis
2    Copyright (C) 2005-2018 Free Software Foundation, Inc.
3    Contributed by Daniel Berlin <dberlin@dberlin.org>
4 
5    This file is part of GCC.
6 
7    GCC is free software; you can redistribute it and/or modify
8    under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11 
12    GCC is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with GCC; see the file COPYING3.  If not see
19    <http://www.gnu.org/licenses/>.  */
20 
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "backend.h"
25 #include "rtl.h"
26 #include "tree.h"
27 #include "gimple.h"
28 #include "alloc-pool.h"
29 #include "tree-pass.h"
30 #include "ssa.h"
31 #include "cgraph.h"
32 #include "tree-pretty-print.h"
33 #include "diagnostic-core.h"
34 #include "fold-const.h"
35 #include "stor-layout.h"
36 #include "stmt.h"
37 #include "gimple-iterator.h"
38 #include "tree-into-ssa.h"
39 #include "tree-dfa.h"
40 #include "params.h"
41 #include "gimple-walk.h"
42 #include "varasm.h"
43 #include "stringpool.h"
44 #include "attribs.h"
45 
46 /* The idea behind this analyzer is to generate set constraints from the
47    program, then solve the resulting constraints in order to generate the
48    points-to sets.
49 
50    Set constraints are a way of modeling program analysis problems that
51    involve sets.  They consist of an inclusion constraint language,
52    describing the variables (each variable is a set) and operations that
53    are involved on the variables, and a set of rules that derive facts
54    from these operations.  To solve a system of set constraints, you derive
55    all possible facts under the rules, which gives you the correct sets
56    as a consequence.
57 
58    See  "Efficient Field-sensitive pointer analysis for C" by "David
59    J. Pearce and Paul H. J. Kelly and Chris Hankin, at
60    http://citeseer.ist.psu.edu/pearce04efficient.html
61 
62    Also see "Ultra-fast Aliasing Analysis using CLA: A Million Lines
63    of C Code in a Second" by ""Nevin Heintze and Olivier Tardieu" at
64    http://citeseer.ist.psu.edu/heintze01ultrafast.html
65 
66    There are three types of real constraint expressions, DEREF,
67    ADDRESSOF, and SCALAR.  Each constraint expression consists
68    of a constraint type, a variable, and an offset.
69 
70    SCALAR is a constraint expression type used to represent x, whether
71    it appears on the LHS or the RHS of a statement.
72    DEREF is a constraint expression type used to represent *x, whether
73    it appears on the LHS or the RHS of a statement.
74    ADDRESSOF is a constraint expression used to represent &x, whether
75    it appears on the LHS or the RHS of a statement.
76 
77    Each pointer variable in the program is assigned an integer id, and
78    each field of a structure variable is assigned an integer id as well.
79 
80    Structure variables are linked to their list of fields through a "next
81    field" in each variable that points to the next field in offset
82    order.
83    Each variable for a structure field has
84 
85    1. "size", that tells the size in bits of that field.
86    2. "fullsize, that tells the size in bits of the entire structure.
87    3. "offset", that tells the offset in bits from the beginning of the
88    structure to this field.
89 
90    Thus,
91    struct f
92    {
93      int a;
94      int b;
95    } foo;
96    int *bar;
97 
98    looks like
99 
100    foo.a -> id 1, size 32, offset 0, fullsize 64, next foo.b
101    foo.b -> id 2, size 32, offset 32, fullsize 64, next NULL
102    bar -> id 3, size 32, offset 0, fullsize 32, next NULL
103 
104 
105   In order to solve the system of set constraints, the following is
106   done:
107 
108   1. Each constraint variable x has a solution set associated with it,
109   Sol(x).
110 
111   2. Constraints are separated into direct, copy, and complex.
112   Direct constraints are ADDRESSOF constraints that require no extra
113   processing, such as P = &Q
114   Copy constraints are those of the form P = Q.
115   Complex constraints are all the constraints involving dereferences
116   and offsets (including offsetted copies).
117 
118   3. All direct constraints of the form P = &Q are processed, such
119   that Q is added to Sol(P)
120 
121   4. All complex constraints for a given constraint variable are stored in a
122   linked list attached to that variable's node.
123 
124   5. A directed graph is built out of the copy constraints. Each
125   constraint variable is a node in the graph, and an edge from
126   Q to P is added for each copy constraint of the form P = Q
127 
128   6. The graph is then walked, and solution sets are
129   propagated along the copy edges, such that an edge from Q to P
130   causes Sol(P) <- Sol(P) union Sol(Q).
131 
132   7.  As we visit each node, all complex constraints associated with
133   that node are processed by adding appropriate copy edges to the graph, or the
134   appropriate variables to the solution set.
135 
136   8. The process of walking the graph is iterated until no solution
137   sets change.
138 
139   Prior to walking the graph in steps 6 and 7, We perform static
140   cycle elimination on the constraint graph, as well
141   as off-line variable substitution.
142 
143   TODO: Adding offsets to pointer-to-structures can be handled (IE not punted
144   on and turned into anything), but isn't.  You can just see what offset
145   inside the pointed-to struct it's going to access.
146 
147   TODO: Constant bounded arrays can be handled as if they were structs of the
148   same number of elements.
149 
150   TODO: Modeling heap and incoming pointers becomes much better if we
151   add fields to them as we discover them, which we could do.
152 
153   TODO: We could handle unions, but to be honest, it's probably not
154   worth the pain or slowdown.  */
155 
156 /* IPA-PTA optimizations possible.
157 
158    When the indirect function called is ANYTHING we can add disambiguation
159    based on the function signatures (or simply the parameter count which
160    is the varinfo size).  We also do not need to consider functions that
161    do not have their address taken.
162 
163    The is_global_var bit which marks escape points is overly conservative
164    in IPA mode.  Split it to is_escape_point and is_global_var - only
165    externally visible globals are escape points in IPA mode.
166    There is now is_ipa_escape_point but this is only used in a few
167    selected places.
168 
169    The way we introduce DECL_PT_UID to avoid fixing up all points-to
170    sets in the translation unit when we copy a DECL during inlining
171    pessimizes precision.  The advantage is that the DECL_PT_UID keeps
172    compile-time and memory usage overhead low - the points-to sets
173    do not grow or get unshared as they would during a fixup phase.
174    An alternative solution is to delay IPA PTA until after all
175    inlining transformations have been applied.
176 
177    The way we propagate clobber/use information isn't optimized.
178    It should use a new complex constraint that properly filters
179    out local variables of the callee (though that would make
180    the sets invalid after inlining).  OTOH we might as well
181    admit defeat to WHOPR and simply do all the clobber/use analysis
182    and propagation after PTA finished but before we threw away
183    points-to information for memory variables.  WHOPR and PTA
184    do not play along well anyway - the whole constraint solving
185    would need to be done in WPA phase and it will be very interesting
186    to apply the results to local SSA names during LTRANS phase.
187 
188    We probably should compute a per-function unit-ESCAPE solution
189    propagating it simply like the clobber / uses solutions.  The
190    solution can go alongside the non-IPA espaced solution and be
191    used to query which vars escape the unit through a function.
192    This is also required to make the escaped-HEAP trick work in IPA mode.
193 
194    We never put function decls in points-to sets so we do not
195    keep the set of called functions for indirect calls.
196 
197    And probably more.  */
198 
199 static bool use_field_sensitive = true;
200 static int in_ipa_mode = 0;
201 
202 /* Used for predecessor bitmaps. */
203 static bitmap_obstack predbitmap_obstack;
204 
205 /* Used for points-to sets.  */
206 static bitmap_obstack pta_obstack;
207 
208 /* Used for oldsolution members of variables. */
209 static bitmap_obstack oldpta_obstack;
210 
211 /* Used for per-solver-iteration bitmaps.  */
212 static bitmap_obstack iteration_obstack;
213 
214 static unsigned int create_variable_info_for (tree, const char *, bool);
215 typedef struct constraint_graph *constraint_graph_t;
216 static void unify_nodes (constraint_graph_t, unsigned int, unsigned int, bool);
217 
218 struct constraint;
219 typedef struct constraint *constraint_t;
220 
221 
222 #define EXECUTE_IF_IN_NONNULL_BITMAP(a, b, c, d)	\
223   if (a)						\
224     EXECUTE_IF_SET_IN_BITMAP (a, b, c, d)
225 
226 static struct constraint_stats
227 {
228   unsigned int total_vars;
229   unsigned int nonpointer_vars;
230   unsigned int unified_vars_static;
231   unsigned int unified_vars_dynamic;
232   unsigned int iterations;
233   unsigned int num_edges;
234   unsigned int num_implicit_edges;
235   unsigned int points_to_sets_created;
236 } stats;
237 
238 struct variable_info
239 {
240   /* ID of this variable  */
241   unsigned int id;
242 
243   /* True if this is a variable created by the constraint analysis, such as
244      heap variables and constraints we had to break up.  */
245   unsigned int is_artificial_var : 1;
246 
247   /* True if this is a special variable whose solution set should not be
248      changed.  */
249   unsigned int is_special_var : 1;
250 
251   /* True for variables whose size is not known or variable.  */
252   unsigned int is_unknown_size_var : 1;
253 
254   /* True for (sub-)fields that represent a whole variable.  */
255   unsigned int is_full_var : 1;
256 
257   /* True if this is a heap variable.  */
258   unsigned int is_heap_var : 1;
259 
260   /* True if this is a register variable.  */
261   unsigned int is_reg_var : 1;
262 
263   /* True if this field may contain pointers.  */
264   unsigned int may_have_pointers : 1;
265 
266   /* True if this field has only restrict qualified pointers.  */
267   unsigned int only_restrict_pointers : 1;
268 
269   /* True if this represents a heap var created for a restrict qualified
270      pointer.  */
271   unsigned int is_restrict_var : 1;
272 
273   /* True if this represents a global variable.  */
274   unsigned int is_global_var : 1;
275 
276   /* True if this represents a module escape point for IPA analysis.  */
277   unsigned int is_ipa_escape_point : 1;
278 
279   /* True if this represents a IPA function info.  */
280   unsigned int is_fn_info : 1;
281 
282   /* ???  Store somewhere better.  */
283   unsigned short ruid;
284 
285   /* The ID of the variable for the next field in this structure
286      or zero for the last field in this structure.  */
287   unsigned next;
288 
289   /* The ID of the variable for the first field in this structure.  */
290   unsigned head;
291 
292   /* Offset of this variable, in bits, from the base variable  */
293   unsigned HOST_WIDE_INT offset;
294 
295   /* Size of the variable, in bits.  */
296   unsigned HOST_WIDE_INT size;
297 
298   /* Full size of the base variable, in bits.  */
299   unsigned HOST_WIDE_INT fullsize;
300 
301   /* Name of this variable */
302   const char *name;
303 
304   /* Tree that this variable is associated with.  */
305   tree decl;
306 
307   /* Points-to set for this variable.  */
308   bitmap solution;
309 
310   /* Old points-to set for this variable.  */
311   bitmap oldsolution;
312 };
313 typedef struct variable_info *varinfo_t;
314 
315 static varinfo_t first_vi_for_offset (varinfo_t, unsigned HOST_WIDE_INT);
316 static varinfo_t first_or_preceding_vi_for_offset (varinfo_t,
317 						   unsigned HOST_WIDE_INT);
318 static varinfo_t lookup_vi_for_tree (tree);
319 static inline bool type_can_have_subvars (const_tree);
320 static void make_param_constraints (varinfo_t);
321 
322 /* Pool of variable info structures.  */
323 static object_allocator<variable_info> variable_info_pool
324   ("Variable info pool");
325 
326 /* Map varinfo to final pt_solution.  */
327 static hash_map<varinfo_t, pt_solution *> *final_solutions;
328 struct obstack final_solutions_obstack;
329 
330 /* Table of variable info structures for constraint variables.
331    Indexed directly by variable info id.  */
332 static vec<varinfo_t> varmap;
333 
334 /* Return the varmap element N */
335 
336 static inline varinfo_t
get_varinfo(unsigned int n)337 get_varinfo (unsigned int n)
338 {
339   return varmap[n];
340 }
341 
342 /* Return the next variable in the list of sub-variables of VI
343    or NULL if VI is the last sub-variable.  */
344 
345 static inline varinfo_t
vi_next(varinfo_t vi)346 vi_next (varinfo_t vi)
347 {
348   return get_varinfo (vi->next);
349 }
350 
351 /* Static IDs for the special variables.  Variable ID zero is unused
352    and used as terminator for the sub-variable chain.  */
353 enum { nothing_id = 1, anything_id = 2, string_id = 3,
354        escaped_id = 4, nonlocal_id = 5,
355        storedanything_id = 6, integer_id = 7 };
356 
357 /* Return a new variable info structure consisting for a variable
358    named NAME, and using constraint graph node NODE.  Append it
359    to the vector of variable info structures.  */
360 
361 static varinfo_t
new_var_info(tree t,const char * name,bool add_id)362 new_var_info (tree t, const char *name, bool add_id)
363 {
364   unsigned index = varmap.length ();
365   varinfo_t ret = variable_info_pool.allocate ();
366 
367   if (dump_file && add_id)
368     {
369       char *tempname = xasprintf ("%s(%d)", name, index);
370       name = ggc_strdup (tempname);
371       free (tempname);
372     }
373 
374   ret->id = index;
375   ret->name = name;
376   ret->decl = t;
377   /* Vars without decl are artificial and do not have sub-variables.  */
378   ret->is_artificial_var = (t == NULL_TREE);
379   ret->is_special_var = false;
380   ret->is_unknown_size_var = false;
381   ret->is_full_var = (t == NULL_TREE);
382   ret->is_heap_var = false;
383   ret->may_have_pointers = true;
384   ret->only_restrict_pointers = false;
385   ret->is_restrict_var = false;
386   ret->ruid = 0;
387   ret->is_global_var = (t == NULL_TREE);
388   ret->is_ipa_escape_point = false;
389   ret->is_fn_info = false;
390   if (t && DECL_P (t))
391     ret->is_global_var = (is_global_var (t)
392 			  /* We have to treat even local register variables
393 			     as escape points.  */
394 			  || (VAR_P (t) && DECL_HARD_REGISTER (t)));
395   ret->is_reg_var = (t && TREE_CODE (t) == SSA_NAME);
396   ret->solution = BITMAP_ALLOC (&pta_obstack);
397   ret->oldsolution = NULL;
398   ret->next = 0;
399   ret->head = ret->id;
400 
401   stats.total_vars++;
402 
403   varmap.safe_push (ret);
404 
405   return ret;
406 }
407 
408 /* A map mapping call statements to per-stmt variables for uses
409    and clobbers specific to the call.  */
410 static hash_map<gimple *, varinfo_t> *call_stmt_vars;
411 
412 /* Lookup or create the variable for the call statement CALL.  */
413 
414 static varinfo_t
get_call_vi(gcall * call)415 get_call_vi (gcall *call)
416 {
417   varinfo_t vi, vi2;
418 
419   bool existed;
420   varinfo_t *slot_p = &call_stmt_vars->get_or_insert (call, &existed);
421   if (existed)
422     return *slot_p;
423 
424   vi = new_var_info (NULL_TREE, "CALLUSED", true);
425   vi->offset = 0;
426   vi->size = 1;
427   vi->fullsize = 2;
428   vi->is_full_var = true;
429   vi->is_reg_var = true;
430 
431   vi2 = new_var_info (NULL_TREE, "CALLCLOBBERED", true);
432   vi2->offset = 1;
433   vi2->size = 1;
434   vi2->fullsize = 2;
435   vi2->is_full_var = true;
436   vi2->is_reg_var = true;
437 
438   vi->next = vi2->id;
439 
440   *slot_p = vi;
441   return vi;
442 }
443 
444 /* Lookup the variable for the call statement CALL representing
445    the uses.  Returns NULL if there is nothing special about this call.  */
446 
447 static varinfo_t
lookup_call_use_vi(gcall * call)448 lookup_call_use_vi (gcall *call)
449 {
450   varinfo_t *slot_p = call_stmt_vars->get (call);
451   if (slot_p)
452     return *slot_p;
453 
454   return NULL;
455 }
456 
457 /* Lookup the variable for the call statement CALL representing
458    the clobbers.  Returns NULL if there is nothing special about this call.  */
459 
460 static varinfo_t
lookup_call_clobber_vi(gcall * call)461 lookup_call_clobber_vi (gcall *call)
462 {
463   varinfo_t uses = lookup_call_use_vi (call);
464   if (!uses)
465     return NULL;
466 
467   return vi_next (uses);
468 }
469 
470 /* Lookup or create the variable for the call statement CALL representing
471    the uses.  */
472 
473 static varinfo_t
get_call_use_vi(gcall * call)474 get_call_use_vi (gcall *call)
475 {
476   return get_call_vi (call);
477 }
478 
479 /* Lookup or create the variable for the call statement CALL representing
480    the clobbers.  */
481 
482 static varinfo_t ATTRIBUTE_UNUSED
get_call_clobber_vi(gcall * call)483 get_call_clobber_vi (gcall *call)
484 {
485   return vi_next (get_call_vi (call));
486 }
487 
488 
489 enum constraint_expr_type {SCALAR, DEREF, ADDRESSOF};
490 
491 /* An expression that appears in a constraint.  */
492 
493 struct constraint_expr
494 {
495   /* Constraint type.  */
496   constraint_expr_type type;
497 
498   /* Variable we are referring to in the constraint.  */
499   unsigned int var;
500 
501   /* Offset, in bits, of this constraint from the beginning of
502      variables it ends up referring to.
503 
504      IOW, in a deref constraint, we would deref, get the result set,
505      then add OFFSET to each member.   */
506   HOST_WIDE_INT offset;
507 };
508 
509 /* Use 0x8000... as special unknown offset.  */
510 #define UNKNOWN_OFFSET HOST_WIDE_INT_MIN
511 
512 typedef struct constraint_expr ce_s;
513 static void get_constraint_for_1 (tree, vec<ce_s> *, bool, bool);
514 static void get_constraint_for (tree, vec<ce_s> *);
515 static void get_constraint_for_rhs (tree, vec<ce_s> *);
516 static void do_deref (vec<ce_s> *);
517 
518 /* Our set constraints are made up of two constraint expressions, one
519    LHS, and one RHS.
520 
521    As described in the introduction, our set constraints each represent an
522    operation between set valued variables.
523 */
524 struct constraint
525 {
526   struct constraint_expr lhs;
527   struct constraint_expr rhs;
528 };
529 
530 /* List of constraints that we use to build the constraint graph from.  */
531 
532 static vec<constraint_t> constraints;
533 static object_allocator<constraint> constraint_pool ("Constraint pool");
534 
535 /* The constraint graph is represented as an array of bitmaps
536    containing successor nodes.  */
537 
538 struct constraint_graph
539 {
540   /* Size of this graph, which may be different than the number of
541      nodes in the variable map.  */
542   unsigned int size;
543 
544   /* Explicit successors of each node. */
545   bitmap *succs;
546 
547   /* Implicit predecessors of each node (Used for variable
548      substitution). */
549   bitmap *implicit_preds;
550 
551   /* Explicit predecessors of each node (Used for variable substitution).  */
552   bitmap *preds;
553 
554   /* Indirect cycle representatives, or -1 if the node has no indirect
555      cycles.  */
556   int *indirect_cycles;
557 
558   /* Representative node for a node.  rep[a] == a unless the node has
559      been unified. */
560   unsigned int *rep;
561 
562   /* Equivalence class representative for a label.  This is used for
563      variable substitution.  */
564   int *eq_rep;
565 
566   /* Pointer equivalence label for a node.  All nodes with the same
567      pointer equivalence label can be unified together at some point
568      (either during constraint optimization or after the constraint
569      graph is built).  */
570   unsigned int *pe;
571 
572   /* Pointer equivalence representative for a label.  This is used to
573      handle nodes that are pointer equivalent but not location
574      equivalent.  We can unite these once the addressof constraints
575      are transformed into initial points-to sets.  */
576   int *pe_rep;
577 
578   /* Pointer equivalence label for each node, used during variable
579      substitution.  */
580   unsigned int *pointer_label;
581 
582   /* Location equivalence label for each node, used during location
583      equivalence finding.  */
584   unsigned int *loc_label;
585 
586   /* Pointed-by set for each node, used during location equivalence
587      finding.  This is pointed-by rather than pointed-to, because it
588      is constructed using the predecessor graph.  */
589   bitmap *pointed_by;
590 
591   /* Points to sets for pointer equivalence.  This is *not* the actual
592      points-to sets for nodes.  */
593   bitmap *points_to;
594 
595   /* Bitmap of nodes where the bit is set if the node is a direct
596      node.  Used for variable substitution.  */
597   sbitmap direct_nodes;
598 
599   /* Bitmap of nodes where the bit is set if the node is address
600      taken.  Used for variable substitution.  */
601   bitmap address_taken;
602 
603   /* Vector of complex constraints for each graph node.  Complex
604      constraints are those involving dereferences or offsets that are
605      not 0.  */
606   vec<constraint_t> *complex;
607 };
608 
609 static constraint_graph_t graph;
610 
611 /* During variable substitution and the offline version of indirect
612    cycle finding, we create nodes to represent dereferences and
613    address taken constraints.  These represent where these start and
614    end.  */
615 #define FIRST_REF_NODE (varmap).length ()
616 #define LAST_REF_NODE (FIRST_REF_NODE + (FIRST_REF_NODE - 1))
617 
618 /* Return the representative node for NODE, if NODE has been unioned
619    with another NODE.
620    This function performs path compression along the way to finding
621    the representative.  */
622 
623 static unsigned int
find(unsigned int node)624 find (unsigned int node)
625 {
626   gcc_checking_assert (node < graph->size);
627   if (graph->rep[node] != node)
628     return graph->rep[node] = find (graph->rep[node]);
629   return node;
630 }
631 
632 /* Union the TO and FROM nodes to the TO nodes.
633    Note that at some point in the future, we may want to do
634    union-by-rank, in which case we are going to have to return the
635    node we unified to.  */
636 
637 static bool
unite(unsigned int to,unsigned int from)638 unite (unsigned int to, unsigned int from)
639 {
640   gcc_checking_assert (to < graph->size && from < graph->size);
641   if (to != from && graph->rep[from] != to)
642     {
643       graph->rep[from] = to;
644       return true;
645     }
646   return false;
647 }
648 
649 /* Create a new constraint consisting of LHS and RHS expressions.  */
650 
651 static constraint_t
new_constraint(const struct constraint_expr lhs,const struct constraint_expr rhs)652 new_constraint (const struct constraint_expr lhs,
653 		const struct constraint_expr rhs)
654 {
655   constraint_t ret = constraint_pool.allocate ();
656   ret->lhs = lhs;
657   ret->rhs = rhs;
658   return ret;
659 }
660 
661 /* Print out constraint C to FILE.  */
662 
663 static void
dump_constraint(FILE * file,constraint_t c)664 dump_constraint (FILE *file, constraint_t c)
665 {
666   if (c->lhs.type == ADDRESSOF)
667     fprintf (file, "&");
668   else if (c->lhs.type == DEREF)
669     fprintf (file, "*");
670   fprintf (file, "%s", get_varinfo (c->lhs.var)->name);
671   if (c->lhs.offset == UNKNOWN_OFFSET)
672     fprintf (file, " + UNKNOWN");
673   else if (c->lhs.offset != 0)
674     fprintf (file, " + " HOST_WIDE_INT_PRINT_DEC, c->lhs.offset);
675   fprintf (file, " = ");
676   if (c->rhs.type == ADDRESSOF)
677     fprintf (file, "&");
678   else if (c->rhs.type == DEREF)
679     fprintf (file, "*");
680   fprintf (file, "%s", get_varinfo (c->rhs.var)->name);
681   if (c->rhs.offset == UNKNOWN_OFFSET)
682     fprintf (file, " + UNKNOWN");
683   else if (c->rhs.offset != 0)
684     fprintf (file, " + " HOST_WIDE_INT_PRINT_DEC, c->rhs.offset);
685 }
686 
687 
688 void debug_constraint (constraint_t);
689 void debug_constraints (void);
690 void debug_constraint_graph (void);
691 void debug_solution_for_var (unsigned int);
692 void debug_sa_points_to_info (void);
693 void debug_varinfo (varinfo_t);
694 void debug_varmap (void);
695 
696 /* Print out constraint C to stderr.  */
697 
698 DEBUG_FUNCTION void
debug_constraint(constraint_t c)699 debug_constraint (constraint_t c)
700 {
701   dump_constraint (stderr, c);
702   fprintf (stderr, "\n");
703 }
704 
705 /* Print out all constraints to FILE */
706 
707 static void
dump_constraints(FILE * file,int from)708 dump_constraints (FILE *file, int from)
709 {
710   int i;
711   constraint_t c;
712   for (i = from; constraints.iterate (i, &c); i++)
713     if (c)
714       {
715 	dump_constraint (file, c);
716 	fprintf (file, "\n");
717       }
718 }
719 
720 /* Print out all constraints to stderr.  */
721 
722 DEBUG_FUNCTION void
debug_constraints(void)723 debug_constraints (void)
724 {
725   dump_constraints (stderr, 0);
726 }
727 
728 /* Print the constraint graph in dot format.  */
729 
730 static void
dump_constraint_graph(FILE * file)731 dump_constraint_graph (FILE *file)
732 {
733   unsigned int i;
734 
735   /* Only print the graph if it has already been initialized:  */
736   if (!graph)
737     return;
738 
739   /* Prints the header of the dot file:  */
740   fprintf (file, "strict digraph {\n");
741   fprintf (file, "  node [\n    shape = box\n  ]\n");
742   fprintf (file, "  edge [\n    fontsize = \"12\"\n  ]\n");
743   fprintf (file, "\n  // List of nodes and complex constraints in "
744 	   "the constraint graph:\n");
745 
746   /* The next lines print the nodes in the graph together with the
747      complex constraints attached to them.  */
748   for (i = 1; i < graph->size; i++)
749     {
750       if (i == FIRST_REF_NODE)
751 	continue;
752       if (find (i) != i)
753 	continue;
754       if (i < FIRST_REF_NODE)
755 	fprintf (file, "\"%s\"", get_varinfo (i)->name);
756       else
757 	fprintf (file, "\"*%s\"", get_varinfo (i - FIRST_REF_NODE)->name);
758       if (graph->complex[i].exists ())
759 	{
760 	  unsigned j;
761 	  constraint_t c;
762 	  fprintf (file, " [label=\"\\N\\n");
763 	  for (j = 0; graph->complex[i].iterate (j, &c); ++j)
764 	    {
765 	      dump_constraint (file, c);
766 	      fprintf (file, "\\l");
767 	    }
768 	  fprintf (file, "\"]");
769 	}
770       fprintf (file, ";\n");
771     }
772 
773   /* Go over the edges.  */
774   fprintf (file, "\n  // Edges in the constraint graph:\n");
775   for (i = 1; i < graph->size; i++)
776     {
777       unsigned j;
778       bitmap_iterator bi;
779       if (find (i) != i)
780 	continue;
781       EXECUTE_IF_IN_NONNULL_BITMAP (graph->succs[i], 0, j, bi)
782 	{
783 	  unsigned to = find (j);
784 	  if (i == to)
785 	    continue;
786 	  if (i < FIRST_REF_NODE)
787 	    fprintf (file, "\"%s\"", get_varinfo (i)->name);
788 	  else
789 	    fprintf (file, "\"*%s\"", get_varinfo (i - FIRST_REF_NODE)->name);
790 	  fprintf (file, " -> ");
791 	  if (to < FIRST_REF_NODE)
792 	    fprintf (file, "\"%s\"", get_varinfo (to)->name);
793 	  else
794 	    fprintf (file, "\"*%s\"", get_varinfo (to - FIRST_REF_NODE)->name);
795 	  fprintf (file, ";\n");
796 	}
797     }
798 
799   /* Prints the tail of the dot file.  */
800   fprintf (file, "}\n");
801 }
802 
803 /* Print out the constraint graph to stderr.  */
804 
805 DEBUG_FUNCTION void
debug_constraint_graph(void)806 debug_constraint_graph (void)
807 {
808   dump_constraint_graph (stderr);
809 }
810 
811 /* SOLVER FUNCTIONS
812 
813    The solver is a simple worklist solver, that works on the following
814    algorithm:
815 
816    sbitmap changed_nodes = all zeroes;
817    changed_count = 0;
818    For each node that is not already collapsed:
819        changed_count++;
820        set bit in changed nodes
821 
822    while (changed_count > 0)
823    {
824      compute topological ordering for constraint graph
825 
826      find and collapse cycles in the constraint graph (updating
827      changed if necessary)
828 
829      for each node (n) in the graph in topological order:
830        changed_count--;
831 
832        Process each complex constraint associated with the node,
833        updating changed if necessary.
834 
835        For each outgoing edge from n, propagate the solution from n to
836        the destination of the edge, updating changed as necessary.
837 
838    }  */
839 
840 /* Return true if two constraint expressions A and B are equal.  */
841 
842 static bool
constraint_expr_equal(struct constraint_expr a,struct constraint_expr b)843 constraint_expr_equal (struct constraint_expr a, struct constraint_expr b)
844 {
845   return a.type == b.type && a.var == b.var && a.offset == b.offset;
846 }
847 
848 /* Return true if constraint expression A is less than constraint expression
849    B.  This is just arbitrary, but consistent, in order to give them an
850    ordering.  */
851 
852 static bool
constraint_expr_less(struct constraint_expr a,struct constraint_expr b)853 constraint_expr_less (struct constraint_expr a, struct constraint_expr b)
854 {
855   if (a.type == b.type)
856     {
857       if (a.var == b.var)
858 	return a.offset < b.offset;
859       else
860 	return a.var < b.var;
861     }
862   else
863     return a.type < b.type;
864 }
865 
866 /* Return true if constraint A is less than constraint B.  This is just
867    arbitrary, but consistent, in order to give them an ordering.  */
868 
869 static bool
constraint_less(const constraint_t & a,const constraint_t & b)870 constraint_less (const constraint_t &a, const constraint_t &b)
871 {
872   if (constraint_expr_less (a->lhs, b->lhs))
873     return true;
874   else if (constraint_expr_less (b->lhs, a->lhs))
875     return false;
876   else
877     return constraint_expr_less (a->rhs, b->rhs);
878 }
879 
880 /* Return true if two constraints A and B are equal.  */
881 
882 static bool
constraint_equal(struct constraint a,struct constraint b)883 constraint_equal (struct constraint a, struct constraint b)
884 {
885   return constraint_expr_equal (a.lhs, b.lhs)
886     && constraint_expr_equal (a.rhs, b.rhs);
887 }
888 
889 
890 /* Find a constraint LOOKFOR in the sorted constraint vector VEC */
891 
892 static constraint_t
constraint_vec_find(vec<constraint_t> vec,struct constraint lookfor)893 constraint_vec_find (vec<constraint_t> vec,
894 		     struct constraint lookfor)
895 {
896   unsigned int place;
897   constraint_t found;
898 
899   if (!vec.exists ())
900     return NULL;
901 
902   place = vec.lower_bound (&lookfor, constraint_less);
903   if (place >= vec.length ())
904     return NULL;
905   found = vec[place];
906   if (!constraint_equal (*found, lookfor))
907     return NULL;
908   return found;
909 }
910 
911 /* Union two constraint vectors, TO and FROM.  Put the result in TO.
912    Returns true of TO set is changed.  */
913 
914 static bool
constraint_set_union(vec<constraint_t> * to,vec<constraint_t> * from)915 constraint_set_union (vec<constraint_t> *to,
916 		      vec<constraint_t> *from)
917 {
918   int i;
919   constraint_t c;
920   bool any_change = false;
921 
922   FOR_EACH_VEC_ELT (*from, i, c)
923     {
924       if (constraint_vec_find (*to, *c) == NULL)
925 	{
926 	  unsigned int place = to->lower_bound (c, constraint_less);
927 	  to->safe_insert (place, c);
928           any_change = true;
929 	}
930     }
931   return any_change;
932 }
933 
934 /* Expands the solution in SET to all sub-fields of variables included.  */
935 
936 static bitmap
solution_set_expand(bitmap set,bitmap * expanded)937 solution_set_expand (bitmap set, bitmap *expanded)
938 {
939   bitmap_iterator bi;
940   unsigned j;
941 
942   if (*expanded)
943     return *expanded;
944 
945   *expanded = BITMAP_ALLOC (&iteration_obstack);
946 
947   /* In a first pass expand to the head of the variables we need to
948      add all sub-fields off.  This avoids quadratic behavior.  */
949   EXECUTE_IF_SET_IN_BITMAP (set, 0, j, bi)
950     {
951       varinfo_t v = get_varinfo (j);
952       if (v->is_artificial_var
953 	  || v->is_full_var)
954 	continue;
955       bitmap_set_bit (*expanded, v->head);
956     }
957 
958   /* In the second pass now expand all head variables with subfields.  */
959   EXECUTE_IF_SET_IN_BITMAP (*expanded, 0, j, bi)
960     {
961       varinfo_t v = get_varinfo (j);
962       if (v->head != j)
963 	continue;
964       for (v = vi_next (v); v != NULL; v = vi_next (v))
965 	bitmap_set_bit (*expanded, v->id);
966     }
967 
968   /* And finally set the rest of the bits from SET.  */
969   bitmap_ior_into (*expanded, set);
970 
971   return *expanded;
972 }
973 
974 /* Union solution sets TO and DELTA, and add INC to each member of DELTA in the
975    process.  */
976 
977 static bool
set_union_with_increment(bitmap to,bitmap delta,HOST_WIDE_INT inc,bitmap * expanded_delta)978 set_union_with_increment  (bitmap to, bitmap delta, HOST_WIDE_INT inc,
979 			   bitmap *expanded_delta)
980 {
981   bool changed = false;
982   bitmap_iterator bi;
983   unsigned int i;
984 
985   /* If the solution of DELTA contains anything it is good enough to transfer
986      this to TO.  */
987   if (bitmap_bit_p (delta, anything_id))
988     return bitmap_set_bit (to, anything_id);
989 
990   /* If the offset is unknown we have to expand the solution to
991      all subfields.  */
992   if (inc == UNKNOWN_OFFSET)
993     {
994       delta = solution_set_expand (delta, expanded_delta);
995       changed |= bitmap_ior_into (to, delta);
996       return changed;
997     }
998 
999   /* For non-zero offset union the offsetted solution into the destination.  */
1000   EXECUTE_IF_SET_IN_BITMAP (delta, 0, i, bi)
1001     {
1002       varinfo_t vi = get_varinfo (i);
1003 
1004       /* If this is a variable with just one field just set its bit
1005          in the result.  */
1006       if (vi->is_artificial_var
1007 	  || vi->is_unknown_size_var
1008 	  || vi->is_full_var)
1009 	changed |= bitmap_set_bit (to, i);
1010       else
1011 	{
1012 	  HOST_WIDE_INT fieldoffset = vi->offset + inc;
1013 	  unsigned HOST_WIDE_INT size = vi->size;
1014 
1015 	  /* If the offset makes the pointer point to before the
1016 	     variable use offset zero for the field lookup.  */
1017 	  if (fieldoffset < 0)
1018 	    vi = get_varinfo (vi->head);
1019 	  else
1020 	    vi = first_or_preceding_vi_for_offset (vi, fieldoffset);
1021 
1022 	  do
1023 	    {
1024 	      changed |= bitmap_set_bit (to, vi->id);
1025 	      if (vi->is_full_var
1026 		  || vi->next == 0)
1027 		break;
1028 
1029 	      /* We have to include all fields that overlap the current field
1030 	         shifted by inc.  */
1031 	      vi = vi_next (vi);
1032 	    }
1033 	  while (vi->offset < fieldoffset + size);
1034 	}
1035     }
1036 
1037   return changed;
1038 }
1039 
1040 /* Insert constraint C into the list of complex constraints for graph
1041    node VAR.  */
1042 
1043 static void
insert_into_complex(constraint_graph_t graph,unsigned int var,constraint_t c)1044 insert_into_complex (constraint_graph_t graph,
1045 		     unsigned int var, constraint_t c)
1046 {
1047   vec<constraint_t> complex = graph->complex[var];
1048   unsigned int place = complex.lower_bound (c, constraint_less);
1049 
1050   /* Only insert constraints that do not already exist.  */
1051   if (place >= complex.length ()
1052       || !constraint_equal (*c, *complex[place]))
1053     graph->complex[var].safe_insert (place, c);
1054 }
1055 
1056 
1057 /* Condense two variable nodes into a single variable node, by moving
1058    all associated info from FROM to TO. Returns true if TO node's
1059    constraint set changes after the merge.  */
1060 
1061 static bool
merge_node_constraints(constraint_graph_t graph,unsigned int to,unsigned int from)1062 merge_node_constraints (constraint_graph_t graph, unsigned int to,
1063 			unsigned int from)
1064 {
1065   unsigned int i;
1066   constraint_t c;
1067   bool any_change = false;
1068 
1069   gcc_checking_assert (find (from) == to);
1070 
1071   /* Move all complex constraints from src node into to node  */
1072   FOR_EACH_VEC_ELT (graph->complex[from], i, c)
1073     {
1074       /* In complex constraints for node FROM, we may have either
1075 	 a = *FROM, and *FROM = a, or an offseted constraint which are
1076 	 always added to the rhs node's constraints.  */
1077 
1078       if (c->rhs.type == DEREF)
1079 	c->rhs.var = to;
1080       else if (c->lhs.type == DEREF)
1081 	c->lhs.var = to;
1082       else
1083 	c->rhs.var = to;
1084 
1085     }
1086   any_change = constraint_set_union (&graph->complex[to],
1087 				     &graph->complex[from]);
1088   graph->complex[from].release ();
1089   return any_change;
1090 }
1091 
1092 
1093 /* Remove edges involving NODE from GRAPH.  */
1094 
1095 static void
clear_edges_for_node(constraint_graph_t graph,unsigned int node)1096 clear_edges_for_node (constraint_graph_t graph, unsigned int node)
1097 {
1098   if (graph->succs[node])
1099     BITMAP_FREE (graph->succs[node]);
1100 }
1101 
1102 /* Merge GRAPH nodes FROM and TO into node TO.  */
1103 
1104 static void
merge_graph_nodes(constraint_graph_t graph,unsigned int to,unsigned int from)1105 merge_graph_nodes (constraint_graph_t graph, unsigned int to,
1106 		   unsigned int from)
1107 {
1108   if (graph->indirect_cycles[from] != -1)
1109     {
1110       /* If we have indirect cycles with the from node, and we have
1111 	 none on the to node, the to node has indirect cycles from the
1112 	 from node now that they are unified.
1113 	 If indirect cycles exist on both, unify the nodes that they
1114 	 are in a cycle with, since we know they are in a cycle with
1115 	 each other.  */
1116       if (graph->indirect_cycles[to] == -1)
1117 	graph->indirect_cycles[to] = graph->indirect_cycles[from];
1118     }
1119 
1120   /* Merge all the successor edges.  */
1121   if (graph->succs[from])
1122     {
1123       if (!graph->succs[to])
1124 	graph->succs[to] = BITMAP_ALLOC (&pta_obstack);
1125       bitmap_ior_into (graph->succs[to],
1126 		       graph->succs[from]);
1127     }
1128 
1129   clear_edges_for_node (graph, from);
1130 }
1131 
1132 
1133 /* Add an indirect graph edge to GRAPH, going from TO to FROM if
1134    it doesn't exist in the graph already.  */
1135 
1136 static void
add_implicit_graph_edge(constraint_graph_t graph,unsigned int to,unsigned int from)1137 add_implicit_graph_edge (constraint_graph_t graph, unsigned int to,
1138 			 unsigned int from)
1139 {
1140   if (to == from)
1141     return;
1142 
1143   if (!graph->implicit_preds[to])
1144     graph->implicit_preds[to] = BITMAP_ALLOC (&predbitmap_obstack);
1145 
1146   if (bitmap_set_bit (graph->implicit_preds[to], from))
1147     stats.num_implicit_edges++;
1148 }
1149 
1150 /* Add a predecessor graph edge to GRAPH, going from TO to FROM if
1151    it doesn't exist in the graph already.
1152    Return false if the edge already existed, true otherwise.  */
1153 
1154 static void
add_pred_graph_edge(constraint_graph_t graph,unsigned int to,unsigned int from)1155 add_pred_graph_edge (constraint_graph_t graph, unsigned int to,
1156 		     unsigned int from)
1157 {
1158   if (!graph->preds[to])
1159     graph->preds[to] = BITMAP_ALLOC (&predbitmap_obstack);
1160   bitmap_set_bit (graph->preds[to], from);
1161 }
1162 
1163 /* Add a graph edge to GRAPH, going from FROM to TO if
1164    it doesn't exist in the graph already.
1165    Return false if the edge already existed, true otherwise.  */
1166 
1167 static bool
add_graph_edge(constraint_graph_t graph,unsigned int to,unsigned int from)1168 add_graph_edge (constraint_graph_t graph, unsigned int to,
1169 		unsigned int from)
1170 {
1171   if (to == from)
1172     {
1173       return false;
1174     }
1175   else
1176     {
1177       bool r = false;
1178 
1179       if (!graph->succs[from])
1180 	graph->succs[from] = BITMAP_ALLOC (&pta_obstack);
1181       if (bitmap_set_bit (graph->succs[from], to))
1182 	{
1183 	  r = true;
1184 	  if (to < FIRST_REF_NODE && from < FIRST_REF_NODE)
1185 	    stats.num_edges++;
1186 	}
1187       return r;
1188     }
1189 }
1190 
1191 
1192 /* Initialize the constraint graph structure to contain SIZE nodes.  */
1193 
1194 static void
init_graph(unsigned int size)1195 init_graph (unsigned int size)
1196 {
1197   unsigned int j;
1198 
1199   graph = XCNEW (struct constraint_graph);
1200   graph->size = size;
1201   graph->succs = XCNEWVEC (bitmap, graph->size);
1202   graph->indirect_cycles = XNEWVEC (int, graph->size);
1203   graph->rep = XNEWVEC (unsigned int, graph->size);
1204   /* ??? Macros do not support template types with multiple arguments,
1205      so we use a typedef to work around it.  */
1206   typedef vec<constraint_t> vec_constraint_t_heap;
1207   graph->complex = XCNEWVEC (vec_constraint_t_heap, size);
1208   graph->pe = XCNEWVEC (unsigned int, graph->size);
1209   graph->pe_rep = XNEWVEC (int, graph->size);
1210 
1211   for (j = 0; j < graph->size; j++)
1212     {
1213       graph->rep[j] = j;
1214       graph->pe_rep[j] = -1;
1215       graph->indirect_cycles[j] = -1;
1216     }
1217 }
1218 
1219 /* Build the constraint graph, adding only predecessor edges right now.  */
1220 
1221 static void
build_pred_graph(void)1222 build_pred_graph (void)
1223 {
1224   int i;
1225   constraint_t c;
1226   unsigned int j;
1227 
1228   graph->implicit_preds = XCNEWVEC (bitmap, graph->size);
1229   graph->preds = XCNEWVEC (bitmap, graph->size);
1230   graph->pointer_label = XCNEWVEC (unsigned int, graph->size);
1231   graph->loc_label = XCNEWVEC (unsigned int, graph->size);
1232   graph->pointed_by = XCNEWVEC (bitmap, graph->size);
1233   graph->points_to = XCNEWVEC (bitmap, graph->size);
1234   graph->eq_rep = XNEWVEC (int, graph->size);
1235   graph->direct_nodes = sbitmap_alloc (graph->size);
1236   graph->address_taken = BITMAP_ALLOC (&predbitmap_obstack);
1237   bitmap_clear (graph->direct_nodes);
1238 
1239   for (j = 1; j < FIRST_REF_NODE; j++)
1240     {
1241       if (!get_varinfo (j)->is_special_var)
1242 	bitmap_set_bit (graph->direct_nodes, j);
1243     }
1244 
1245   for (j = 0; j < graph->size; j++)
1246     graph->eq_rep[j] = -1;
1247 
1248   for (j = 0; j < varmap.length (); j++)
1249     graph->indirect_cycles[j] = -1;
1250 
1251   FOR_EACH_VEC_ELT (constraints, i, c)
1252     {
1253       struct constraint_expr lhs = c->lhs;
1254       struct constraint_expr rhs = c->rhs;
1255       unsigned int lhsvar = lhs.var;
1256       unsigned int rhsvar = rhs.var;
1257 
1258       if (lhs.type == DEREF)
1259 	{
1260 	  /* *x = y.  */
1261 	  if (rhs.offset == 0 && lhs.offset == 0 && rhs.type == SCALAR)
1262 	    add_pred_graph_edge (graph, FIRST_REF_NODE + lhsvar, rhsvar);
1263 	}
1264       else if (rhs.type == DEREF)
1265 	{
1266 	  /* x = *y */
1267 	  if (rhs.offset == 0 && lhs.offset == 0 && lhs.type == SCALAR)
1268 	    add_pred_graph_edge (graph, lhsvar, FIRST_REF_NODE + rhsvar);
1269 	  else
1270 	    bitmap_clear_bit (graph->direct_nodes, lhsvar);
1271 	}
1272       else if (rhs.type == ADDRESSOF)
1273 	{
1274 	  varinfo_t v;
1275 
1276 	  /* x = &y */
1277 	  if (graph->points_to[lhsvar] == NULL)
1278 	    graph->points_to[lhsvar] = BITMAP_ALLOC (&predbitmap_obstack);
1279 	  bitmap_set_bit (graph->points_to[lhsvar], rhsvar);
1280 
1281 	  if (graph->pointed_by[rhsvar] == NULL)
1282 	    graph->pointed_by[rhsvar] = BITMAP_ALLOC (&predbitmap_obstack);
1283 	  bitmap_set_bit (graph->pointed_by[rhsvar], lhsvar);
1284 
1285 	  /* Implicitly, *x = y */
1286 	  add_implicit_graph_edge (graph, FIRST_REF_NODE + lhsvar, rhsvar);
1287 
1288 	  /* All related variables are no longer direct nodes.  */
1289 	  bitmap_clear_bit (graph->direct_nodes, rhsvar);
1290           v = get_varinfo (rhsvar);
1291           if (!v->is_full_var)
1292             {
1293               v = get_varinfo (v->head);
1294               do
1295                 {
1296                   bitmap_clear_bit (graph->direct_nodes, v->id);
1297                   v = vi_next (v);
1298                 }
1299               while (v != NULL);
1300             }
1301 	  bitmap_set_bit (graph->address_taken, rhsvar);
1302 	}
1303       else if (lhsvar > anything_id
1304 	       && lhsvar != rhsvar && lhs.offset == 0 && rhs.offset == 0)
1305 	{
1306 	  /* x = y */
1307 	  add_pred_graph_edge (graph, lhsvar, rhsvar);
1308 	  /* Implicitly, *x = *y */
1309 	  add_implicit_graph_edge (graph, FIRST_REF_NODE + lhsvar,
1310 				   FIRST_REF_NODE + rhsvar);
1311 	}
1312       else if (lhs.offset != 0 || rhs.offset != 0)
1313 	{
1314 	  if (rhs.offset != 0)
1315 	    bitmap_clear_bit (graph->direct_nodes, lhs.var);
1316 	  else if (lhs.offset != 0)
1317 	    bitmap_clear_bit (graph->direct_nodes, rhs.var);
1318 	}
1319     }
1320 }
1321 
1322 /* Build the constraint graph, adding successor edges.  */
1323 
1324 static void
build_succ_graph(void)1325 build_succ_graph (void)
1326 {
1327   unsigned i, t;
1328   constraint_t c;
1329 
1330   FOR_EACH_VEC_ELT (constraints, i, c)
1331     {
1332       struct constraint_expr lhs;
1333       struct constraint_expr rhs;
1334       unsigned int lhsvar;
1335       unsigned int rhsvar;
1336 
1337       if (!c)
1338 	continue;
1339 
1340       lhs = c->lhs;
1341       rhs = c->rhs;
1342       lhsvar = find (lhs.var);
1343       rhsvar = find (rhs.var);
1344 
1345       if (lhs.type == DEREF)
1346 	{
1347 	  if (rhs.offset == 0 && lhs.offset == 0 && rhs.type == SCALAR)
1348 	    add_graph_edge (graph, FIRST_REF_NODE + lhsvar, rhsvar);
1349 	}
1350       else if (rhs.type == DEREF)
1351 	{
1352 	  if (rhs.offset == 0 && lhs.offset == 0 && lhs.type == SCALAR)
1353 	    add_graph_edge (graph, lhsvar, FIRST_REF_NODE + rhsvar);
1354 	}
1355       else if (rhs.type == ADDRESSOF)
1356 	{
1357 	  /* x = &y */
1358 	  gcc_checking_assert (find (rhs.var) == rhs.var);
1359 	  bitmap_set_bit (get_varinfo (lhsvar)->solution, rhsvar);
1360 	}
1361       else if (lhsvar > anything_id
1362 	       && lhsvar != rhsvar && lhs.offset == 0 && rhs.offset == 0)
1363 	{
1364 	  add_graph_edge (graph, lhsvar, rhsvar);
1365 	}
1366     }
1367 
1368   /* Add edges from STOREDANYTHING to all non-direct nodes that can
1369      receive pointers.  */
1370   t = find (storedanything_id);
1371   for (i = integer_id + 1; i < FIRST_REF_NODE; ++i)
1372     {
1373       if (!bitmap_bit_p (graph->direct_nodes, i)
1374 	  && get_varinfo (i)->may_have_pointers)
1375 	add_graph_edge (graph, find (i), t);
1376     }
1377 
1378   /* Everything stored to ANYTHING also potentially escapes.  */
1379   add_graph_edge (graph, find (escaped_id), t);
1380 }
1381 
1382 
1383 /* Changed variables on the last iteration.  */
1384 static bitmap changed;
1385 
1386 /* Strongly Connected Component visitation info.  */
1387 
1388 struct scc_info
1389 {
1390   scc_info (size_t size);
1391   ~scc_info ();
1392 
1393   auto_sbitmap visited;
1394   auto_sbitmap deleted;
1395   unsigned int *dfs;
1396   unsigned int *node_mapping;
1397   int current_index;
1398   auto_vec<unsigned> scc_stack;
1399 };
1400 
1401 
1402 /* Recursive routine to find strongly connected components in GRAPH.
1403    SI is the SCC info to store the information in, and N is the id of current
1404    graph node we are processing.
1405 
1406    This is Tarjan's strongly connected component finding algorithm, as
1407    modified by Nuutila to keep only non-root nodes on the stack.
1408    The algorithm can be found in "On finding the strongly connected
1409    connected components in a directed graph" by Esko Nuutila and Eljas
1410    Soisalon-Soininen, in Information Processing Letters volume 49,
1411    number 1, pages 9-14.  */
1412 
1413 static void
scc_visit(constraint_graph_t graph,struct scc_info * si,unsigned int n)1414 scc_visit (constraint_graph_t graph, struct scc_info *si, unsigned int n)
1415 {
1416   unsigned int i;
1417   bitmap_iterator bi;
1418   unsigned int my_dfs;
1419 
1420   bitmap_set_bit (si->visited, n);
1421   si->dfs[n] = si->current_index ++;
1422   my_dfs = si->dfs[n];
1423 
1424   /* Visit all the successors.  */
1425   EXECUTE_IF_IN_NONNULL_BITMAP (graph->succs[n], 0, i, bi)
1426     {
1427       unsigned int w;
1428 
1429       if (i > LAST_REF_NODE)
1430 	break;
1431 
1432       w = find (i);
1433       if (bitmap_bit_p (si->deleted, w))
1434 	continue;
1435 
1436       if (!bitmap_bit_p (si->visited, w))
1437 	scc_visit (graph, si, w);
1438 
1439       unsigned int t = find (w);
1440       gcc_checking_assert (find (n) == n);
1441       if (si->dfs[t] < si->dfs[n])
1442 	si->dfs[n] = si->dfs[t];
1443     }
1444 
1445   /* See if any components have been identified.  */
1446   if (si->dfs[n] == my_dfs)
1447     {
1448       if (si->scc_stack.length () > 0
1449 	  && si->dfs[si->scc_stack.last ()] >= my_dfs)
1450 	{
1451 	  bitmap scc = BITMAP_ALLOC (NULL);
1452 	  unsigned int lowest_node;
1453 	  bitmap_iterator bi;
1454 
1455 	  bitmap_set_bit (scc, n);
1456 
1457 	  while (si->scc_stack.length () != 0
1458 		 && si->dfs[si->scc_stack.last ()] >= my_dfs)
1459 	    {
1460 	      unsigned int w = si->scc_stack.pop ();
1461 
1462 	      bitmap_set_bit (scc, w);
1463 	    }
1464 
1465 	  lowest_node = bitmap_first_set_bit (scc);
1466 	  gcc_assert (lowest_node < FIRST_REF_NODE);
1467 
1468 	  /* Collapse the SCC nodes into a single node, and mark the
1469 	     indirect cycles.  */
1470 	  EXECUTE_IF_SET_IN_BITMAP (scc, 0, i, bi)
1471 	    {
1472 	      if (i < FIRST_REF_NODE)
1473 		{
1474 		  if (unite (lowest_node, i))
1475 		    unify_nodes (graph, lowest_node, i, false);
1476 		}
1477 	      else
1478 		{
1479 		  unite (lowest_node, i);
1480 		  graph->indirect_cycles[i - FIRST_REF_NODE] = lowest_node;
1481 		}
1482 	    }
1483 	}
1484       bitmap_set_bit (si->deleted, n);
1485     }
1486   else
1487     si->scc_stack.safe_push (n);
1488 }
1489 
1490 /* Unify node FROM into node TO, updating the changed count if
1491    necessary when UPDATE_CHANGED is true.  */
1492 
1493 static void
unify_nodes(constraint_graph_t graph,unsigned int to,unsigned int from,bool update_changed)1494 unify_nodes (constraint_graph_t graph, unsigned int to, unsigned int from,
1495 	     bool update_changed)
1496 {
1497   gcc_checking_assert (to != from && find (to) == to);
1498 
1499   if (dump_file && (dump_flags & TDF_DETAILS))
1500     fprintf (dump_file, "Unifying %s to %s\n",
1501 	     get_varinfo (from)->name,
1502 	     get_varinfo (to)->name);
1503 
1504   if (update_changed)
1505     stats.unified_vars_dynamic++;
1506   else
1507     stats.unified_vars_static++;
1508 
1509   merge_graph_nodes (graph, to, from);
1510   if (merge_node_constraints (graph, to, from))
1511     {
1512       if (update_changed)
1513 	bitmap_set_bit (changed, to);
1514     }
1515 
1516   /* Mark TO as changed if FROM was changed. If TO was already marked
1517      as changed, decrease the changed count.  */
1518 
1519   if (update_changed
1520       && bitmap_clear_bit (changed, from))
1521     bitmap_set_bit (changed, to);
1522   varinfo_t fromvi = get_varinfo (from);
1523   if (fromvi->solution)
1524     {
1525       /* If the solution changes because of the merging, we need to mark
1526 	 the variable as changed.  */
1527       varinfo_t tovi = get_varinfo (to);
1528       if (bitmap_ior_into (tovi->solution, fromvi->solution))
1529 	{
1530 	  if (update_changed)
1531 	    bitmap_set_bit (changed, to);
1532 	}
1533 
1534       BITMAP_FREE (fromvi->solution);
1535       if (fromvi->oldsolution)
1536 	BITMAP_FREE (fromvi->oldsolution);
1537 
1538       if (stats.iterations > 0
1539 	  && tovi->oldsolution)
1540 	BITMAP_FREE (tovi->oldsolution);
1541     }
1542   if (graph->succs[to])
1543     bitmap_clear_bit (graph->succs[to], to);
1544 }
1545 
1546 /* Information needed to compute the topological ordering of a graph.  */
1547 
1548 struct topo_info
1549 {
1550   /* sbitmap of visited nodes.  */
1551   sbitmap visited;
1552   /* Array that stores the topological order of the graph, *in
1553      reverse*.  */
1554   vec<unsigned> topo_order;
1555 };
1556 
1557 
1558 /* Initialize and return a topological info structure.  */
1559 
1560 static struct topo_info *
init_topo_info(void)1561 init_topo_info (void)
1562 {
1563   size_t size = graph->size;
1564   struct topo_info *ti = XNEW (struct topo_info);
1565   ti->visited = sbitmap_alloc (size);
1566   bitmap_clear (ti->visited);
1567   ti->topo_order.create (1);
1568   return ti;
1569 }
1570 
1571 
1572 /* Free the topological sort info pointed to by TI.  */
1573 
1574 static void
free_topo_info(struct topo_info * ti)1575 free_topo_info (struct topo_info *ti)
1576 {
1577   sbitmap_free (ti->visited);
1578   ti->topo_order.release ();
1579   free (ti);
1580 }
1581 
1582 /* Visit the graph in topological order, and store the order in the
1583    topo_info structure.  */
1584 
1585 static void
topo_visit(constraint_graph_t graph,struct topo_info * ti,unsigned int n)1586 topo_visit (constraint_graph_t graph, struct topo_info *ti,
1587 	    unsigned int n)
1588 {
1589   bitmap_iterator bi;
1590   unsigned int j;
1591 
1592   bitmap_set_bit (ti->visited, n);
1593 
1594   if (graph->succs[n])
1595     EXECUTE_IF_SET_IN_BITMAP (graph->succs[n], 0, j, bi)
1596       {
1597 	if (!bitmap_bit_p (ti->visited, j))
1598 	  topo_visit (graph, ti, j);
1599       }
1600 
1601   ti->topo_order.safe_push (n);
1602 }
1603 
1604 /* Process a constraint C that represents x = *(y + off), using DELTA as the
1605    starting solution for y.  */
1606 
1607 static void
do_sd_constraint(constraint_graph_t graph,constraint_t c,bitmap delta,bitmap * expanded_delta)1608 do_sd_constraint (constraint_graph_t graph, constraint_t c,
1609 		  bitmap delta, bitmap *expanded_delta)
1610 {
1611   unsigned int lhs = c->lhs.var;
1612   bool flag = false;
1613   bitmap sol = get_varinfo (lhs)->solution;
1614   unsigned int j;
1615   bitmap_iterator bi;
1616   HOST_WIDE_INT roffset = c->rhs.offset;
1617 
1618   /* Our IL does not allow this.  */
1619   gcc_checking_assert (c->lhs.offset == 0);
1620 
1621   /* If the solution of Y contains anything it is good enough to transfer
1622      this to the LHS.  */
1623   if (bitmap_bit_p (delta, anything_id))
1624     {
1625       flag |= bitmap_set_bit (sol, anything_id);
1626       goto done;
1627     }
1628 
1629   /* If we do not know at with offset the rhs is dereferenced compute
1630      the reachability set of DELTA, conservatively assuming it is
1631      dereferenced at all valid offsets.  */
1632   if (roffset == UNKNOWN_OFFSET)
1633     {
1634       delta = solution_set_expand (delta, expanded_delta);
1635       /* No further offset processing is necessary.  */
1636       roffset = 0;
1637     }
1638 
1639   /* For each variable j in delta (Sol(y)), add
1640      an edge in the graph from j to x, and union Sol(j) into Sol(x).  */
1641   EXECUTE_IF_SET_IN_BITMAP (delta, 0, j, bi)
1642     {
1643       varinfo_t v = get_varinfo (j);
1644       HOST_WIDE_INT fieldoffset = v->offset + roffset;
1645       unsigned HOST_WIDE_INT size = v->size;
1646       unsigned int t;
1647 
1648       if (v->is_full_var)
1649 	;
1650       else if (roffset != 0)
1651 	{
1652 	  if (fieldoffset < 0)
1653 	    v = get_varinfo (v->head);
1654 	  else
1655 	    v = first_or_preceding_vi_for_offset (v, fieldoffset);
1656 	}
1657 
1658       /* We have to include all fields that overlap the current field
1659 	 shifted by roffset.  */
1660       do
1661 	{
1662 	  t = find (v->id);
1663 
1664 	  /* Adding edges from the special vars is pointless.
1665 	     They don't have sets that can change.  */
1666 	  if (get_varinfo (t)->is_special_var)
1667 	    flag |= bitmap_ior_into (sol, get_varinfo (t)->solution);
1668 	  /* Merging the solution from ESCAPED needlessly increases
1669 	     the set.  Use ESCAPED as representative instead.  */
1670 	  else if (v->id == escaped_id)
1671 	    flag |= bitmap_set_bit (sol, escaped_id);
1672 	  else if (v->may_have_pointers
1673 		   && add_graph_edge (graph, lhs, t))
1674 	    flag |= bitmap_ior_into (sol, get_varinfo (t)->solution);
1675 
1676 	  if (v->is_full_var
1677 	      || v->next == 0)
1678 	    break;
1679 
1680 	  v = vi_next (v);
1681 	}
1682       while (v->offset < fieldoffset + size);
1683     }
1684 
1685 done:
1686   /* If the LHS solution changed, mark the var as changed.  */
1687   if (flag)
1688     {
1689       get_varinfo (lhs)->solution = sol;
1690       bitmap_set_bit (changed, lhs);
1691     }
1692 }
1693 
1694 /* Process a constraint C that represents *(x + off) = y using DELTA
1695    as the starting solution for x.  */
1696 
1697 static void
do_ds_constraint(constraint_t c,bitmap delta,bitmap * expanded_delta)1698 do_ds_constraint (constraint_t c, bitmap delta, bitmap *expanded_delta)
1699 {
1700   unsigned int rhs = c->rhs.var;
1701   bitmap sol = get_varinfo (rhs)->solution;
1702   unsigned int j;
1703   bitmap_iterator bi;
1704   HOST_WIDE_INT loff = c->lhs.offset;
1705   bool escaped_p = false;
1706 
1707   /* Our IL does not allow this.  */
1708   gcc_checking_assert (c->rhs.offset == 0);
1709 
1710   /* If the solution of y contains ANYTHING simply use the ANYTHING
1711      solution.  This avoids needlessly increasing the points-to sets.  */
1712   if (bitmap_bit_p (sol, anything_id))
1713     sol = get_varinfo (find (anything_id))->solution;
1714 
1715   /* If the solution for x contains ANYTHING we have to merge the
1716      solution of y into all pointer variables which we do via
1717      STOREDANYTHING.  */
1718   if (bitmap_bit_p (delta, anything_id))
1719     {
1720       unsigned t = find (storedanything_id);
1721       if (add_graph_edge (graph, t, rhs))
1722 	{
1723 	  if (bitmap_ior_into (get_varinfo (t)->solution, sol))
1724 	    bitmap_set_bit (changed, t);
1725 	}
1726       return;
1727     }
1728 
1729   /* If we do not know at with offset the rhs is dereferenced compute
1730      the reachability set of DELTA, conservatively assuming it is
1731      dereferenced at all valid offsets.  */
1732   if (loff == UNKNOWN_OFFSET)
1733     {
1734       delta = solution_set_expand (delta, expanded_delta);
1735       loff = 0;
1736     }
1737 
1738   /* For each member j of delta (Sol(x)), add an edge from y to j and
1739      union Sol(y) into Sol(j) */
1740   EXECUTE_IF_SET_IN_BITMAP (delta, 0, j, bi)
1741     {
1742       varinfo_t v = get_varinfo (j);
1743       unsigned int t;
1744       HOST_WIDE_INT fieldoffset = v->offset + loff;
1745       unsigned HOST_WIDE_INT size = v->size;
1746 
1747       if (v->is_full_var)
1748 	;
1749       else if (loff != 0)
1750 	{
1751 	  if (fieldoffset < 0)
1752 	    v = get_varinfo (v->head);
1753 	  else
1754 	    v = first_or_preceding_vi_for_offset (v, fieldoffset);
1755 	}
1756 
1757       /* We have to include all fields that overlap the current field
1758 	 shifted by loff.  */
1759       do
1760 	{
1761 	  if (v->may_have_pointers)
1762 	    {
1763 	      /* If v is a global variable then this is an escape point.  */
1764 	      if (v->is_global_var
1765 		  && !escaped_p)
1766 		{
1767 		  t = find (escaped_id);
1768 		  if (add_graph_edge (graph, t, rhs)
1769 		      && bitmap_ior_into (get_varinfo (t)->solution, sol))
1770 		    bitmap_set_bit (changed, t);
1771 		  /* Enough to let rhs escape once.  */
1772 		  escaped_p = true;
1773 		}
1774 
1775 	      if (v->is_special_var)
1776 		break;
1777 
1778 	      t = find (v->id);
1779 	      if (add_graph_edge (graph, t, rhs)
1780 		  && bitmap_ior_into (get_varinfo (t)->solution, sol))
1781 		bitmap_set_bit (changed, t);
1782 	    }
1783 
1784 	  if (v->is_full_var
1785 	      || v->next == 0)
1786 	    break;
1787 
1788 	  v = vi_next (v);
1789 	}
1790       while (v->offset < fieldoffset + size);
1791     }
1792 }
1793 
1794 /* Handle a non-simple (simple meaning requires no iteration),
1795    constraint (IE *x = &y, x = *y, *x = y, and x = y with offsets involved).  */
1796 
1797 static void
do_complex_constraint(constraint_graph_t graph,constraint_t c,bitmap delta,bitmap * expanded_delta)1798 do_complex_constraint (constraint_graph_t graph, constraint_t c, bitmap delta,
1799 		       bitmap *expanded_delta)
1800 {
1801   if (c->lhs.type == DEREF)
1802     {
1803       if (c->rhs.type == ADDRESSOF)
1804 	{
1805 	  gcc_unreachable ();
1806 	}
1807       else
1808 	{
1809 	  /* *x = y */
1810 	  do_ds_constraint (c, delta, expanded_delta);
1811 	}
1812     }
1813   else if (c->rhs.type == DEREF)
1814     {
1815       /* x = *y */
1816       if (!(get_varinfo (c->lhs.var)->is_special_var))
1817 	do_sd_constraint (graph, c, delta, expanded_delta);
1818     }
1819   else
1820     {
1821       bitmap tmp;
1822       bool flag = false;
1823 
1824       gcc_checking_assert (c->rhs.type == SCALAR && c->lhs.type == SCALAR
1825 			   && c->rhs.offset != 0 && c->lhs.offset == 0);
1826       tmp = get_varinfo (c->lhs.var)->solution;
1827 
1828       flag = set_union_with_increment (tmp, delta, c->rhs.offset,
1829 				       expanded_delta);
1830 
1831       if (flag)
1832 	bitmap_set_bit (changed, c->lhs.var);
1833     }
1834 }
1835 
1836 /* Initialize and return a new SCC info structure.  */
1837 
scc_info(size_t size)1838 scc_info::scc_info (size_t size) :
1839   visited (size), deleted (size), current_index (0), scc_stack (1)
1840 {
1841   bitmap_clear (visited);
1842   bitmap_clear (deleted);
1843   node_mapping = XNEWVEC (unsigned int, size);
1844   dfs = XCNEWVEC (unsigned int, size);
1845 
1846   for (size_t i = 0; i < size; i++)
1847     node_mapping[i] = i;
1848 }
1849 
1850 /* Free an SCC info structure pointed to by SI */
1851 
~scc_info()1852 scc_info::~scc_info ()
1853 {
1854   free (node_mapping);
1855   free (dfs);
1856 }
1857 
1858 
1859 /* Find indirect cycles in GRAPH that occur, using strongly connected
1860    components, and note them in the indirect cycles map.
1861 
1862    This technique comes from Ben Hardekopf and Calvin Lin,
1863    "It Pays to be Lazy: Fast and Accurate Pointer Analysis for Millions of
1864    Lines of Code", submitted to PLDI 2007.  */
1865 
1866 static void
find_indirect_cycles(constraint_graph_t graph)1867 find_indirect_cycles (constraint_graph_t graph)
1868 {
1869   unsigned int i;
1870   unsigned int size = graph->size;
1871   scc_info si (size);
1872 
1873   for (i = 0; i < MIN (LAST_REF_NODE, size); i ++ )
1874     if (!bitmap_bit_p (si.visited, i) && find (i) == i)
1875       scc_visit (graph, &si, i);
1876 }
1877 
1878 /* Compute a topological ordering for GRAPH, and store the result in the
1879    topo_info structure TI.  */
1880 
1881 static void
compute_topo_order(constraint_graph_t graph,struct topo_info * ti)1882 compute_topo_order (constraint_graph_t graph,
1883 		    struct topo_info *ti)
1884 {
1885   unsigned int i;
1886   unsigned int size = graph->size;
1887 
1888   for (i = 0; i != size; ++i)
1889     if (!bitmap_bit_p (ti->visited, i) && find (i) == i)
1890       topo_visit (graph, ti, i);
1891 }
1892 
1893 /* Structure used to for hash value numbering of pointer equivalence
1894    classes.  */
1895 
1896 typedef struct equiv_class_label
1897 {
1898   hashval_t hashcode;
1899   unsigned int equivalence_class;
1900   bitmap labels;
1901 } *equiv_class_label_t;
1902 typedef const struct equiv_class_label *const_equiv_class_label_t;
1903 
1904 /* Equiv_class_label hashtable helpers.  */
1905 
1906 struct equiv_class_hasher : free_ptr_hash <equiv_class_label>
1907 {
1908   static inline hashval_t hash (const equiv_class_label *);
1909   static inline bool equal (const equiv_class_label *,
1910 			    const equiv_class_label *);
1911 };
1912 
1913 /* Hash function for a equiv_class_label_t */
1914 
1915 inline hashval_t
hash(const equiv_class_label * ecl)1916 equiv_class_hasher::hash (const equiv_class_label *ecl)
1917 {
1918   return ecl->hashcode;
1919 }
1920 
1921 /* Equality function for two equiv_class_label_t's.  */
1922 
1923 inline bool
equal(const equiv_class_label * eql1,const equiv_class_label * eql2)1924 equiv_class_hasher::equal (const equiv_class_label *eql1,
1925 			   const equiv_class_label *eql2)
1926 {
1927   return (eql1->hashcode == eql2->hashcode
1928 	  && bitmap_equal_p (eql1->labels, eql2->labels));
1929 }
1930 
1931 /* A hashtable for mapping a bitmap of labels->pointer equivalence
1932    classes.  */
1933 static hash_table<equiv_class_hasher> *pointer_equiv_class_table;
1934 
1935 /* A hashtable for mapping a bitmap of labels->location equivalence
1936    classes.  */
1937 static hash_table<equiv_class_hasher> *location_equiv_class_table;
1938 
1939 /* Lookup a equivalence class in TABLE by the bitmap of LABELS with
1940    hash HAS it contains.  Sets *REF_LABELS to the bitmap LABELS
1941    is equivalent to.  */
1942 
1943 static equiv_class_label *
equiv_class_lookup_or_add(hash_table<equiv_class_hasher> * table,bitmap labels)1944 equiv_class_lookup_or_add (hash_table<equiv_class_hasher> *table,
1945 			   bitmap labels)
1946 {
1947   equiv_class_label **slot;
1948   equiv_class_label ecl;
1949 
1950   ecl.labels = labels;
1951   ecl.hashcode = bitmap_hash (labels);
1952   slot = table->find_slot (&ecl, INSERT);
1953   if (!*slot)
1954     {
1955       *slot = XNEW (struct equiv_class_label);
1956       (*slot)->labels = labels;
1957       (*slot)->hashcode = ecl.hashcode;
1958       (*slot)->equivalence_class = 0;
1959     }
1960 
1961   return *slot;
1962 }
1963 
1964 /* Perform offline variable substitution.
1965 
1966    This is a worst case quadratic time way of identifying variables
1967    that must have equivalent points-to sets, including those caused by
1968    static cycles, and single entry subgraphs, in the constraint graph.
1969 
1970    The technique is described in "Exploiting Pointer and Location
1971    Equivalence to Optimize Pointer Analysis. In the 14th International
1972    Static Analysis Symposium (SAS), August 2007."  It is known as the
1973    "HU" algorithm, and is equivalent to value numbering the collapsed
1974    constraint graph including evaluating unions.
1975 
1976    The general method of finding equivalence classes is as follows:
1977    Add fake nodes (REF nodes) and edges for *a = b and a = *b constraints.
1978    Initialize all non-REF nodes to be direct nodes.
1979    For each constraint a = a U {b}, we set pts(a) = pts(a) u {fresh
1980    variable}
1981    For each constraint containing the dereference, we also do the same
1982    thing.
1983 
1984    We then compute SCC's in the graph and unify nodes in the same SCC,
1985    including pts sets.
1986 
1987    For each non-collapsed node x:
1988     Visit all unvisited explicit incoming edges.
1989     Ignoring all non-pointers, set pts(x) = Union of pts(a) for y
1990     where y->x.
1991     Lookup the equivalence class for pts(x).
1992      If we found one, equivalence_class(x) = found class.
1993      Otherwise, equivalence_class(x) = new class, and new_class is
1994     added to the lookup table.
1995 
1996    All direct nodes with the same equivalence class can be replaced
1997    with a single representative node.
1998    All unlabeled nodes (label == 0) are not pointers and all edges
1999    involving them can be eliminated.
2000    We perform these optimizations during rewrite_constraints
2001 
2002    In addition to pointer equivalence class finding, we also perform
2003    location equivalence class finding.  This is the set of variables
2004    that always appear together in points-to sets.  We use this to
2005    compress the size of the points-to sets.  */
2006 
2007 /* Current maximum pointer equivalence class id.  */
2008 static int pointer_equiv_class;
2009 
2010 /* Current maximum location equivalence class id.  */
2011 static int location_equiv_class;
2012 
2013 /* Recursive routine to find strongly connected components in GRAPH,
2014    and label it's nodes with DFS numbers.  */
2015 
2016 static void
condense_visit(constraint_graph_t graph,struct scc_info * si,unsigned int n)2017 condense_visit (constraint_graph_t graph, struct scc_info *si, unsigned int n)
2018 {
2019   unsigned int i;
2020   bitmap_iterator bi;
2021   unsigned int my_dfs;
2022 
2023   gcc_checking_assert (si->node_mapping[n] == n);
2024   bitmap_set_bit (si->visited, n);
2025   si->dfs[n] = si->current_index ++;
2026   my_dfs = si->dfs[n];
2027 
2028   /* Visit all the successors.  */
2029   EXECUTE_IF_IN_NONNULL_BITMAP (graph->preds[n], 0, i, bi)
2030     {
2031       unsigned int w = si->node_mapping[i];
2032 
2033       if (bitmap_bit_p (si->deleted, w))
2034 	continue;
2035 
2036       if (!bitmap_bit_p (si->visited, w))
2037 	condense_visit (graph, si, w);
2038 
2039       unsigned int t = si->node_mapping[w];
2040       gcc_checking_assert (si->node_mapping[n] == n);
2041       if (si->dfs[t] < si->dfs[n])
2042 	si->dfs[n] = si->dfs[t];
2043     }
2044 
2045   /* Visit all the implicit predecessors.  */
2046   EXECUTE_IF_IN_NONNULL_BITMAP (graph->implicit_preds[n], 0, i, bi)
2047     {
2048       unsigned int w = si->node_mapping[i];
2049 
2050       if (bitmap_bit_p (si->deleted, w))
2051 	continue;
2052 
2053       if (!bitmap_bit_p (si->visited, w))
2054 	condense_visit (graph, si, w);
2055 
2056       unsigned int t = si->node_mapping[w];
2057       gcc_assert (si->node_mapping[n] == n);
2058       if (si->dfs[t] < si->dfs[n])
2059 	si->dfs[n] = si->dfs[t];
2060     }
2061 
2062   /* See if any components have been identified.  */
2063   if (si->dfs[n] == my_dfs)
2064     {
2065       while (si->scc_stack.length () != 0
2066 	     && si->dfs[si->scc_stack.last ()] >= my_dfs)
2067 	{
2068 	  unsigned int w = si->scc_stack.pop ();
2069 	  si->node_mapping[w] = n;
2070 
2071 	  if (!bitmap_bit_p (graph->direct_nodes, w))
2072 	    bitmap_clear_bit (graph->direct_nodes, n);
2073 
2074 	  /* Unify our nodes.  */
2075 	  if (graph->preds[w])
2076 	    {
2077 	      if (!graph->preds[n])
2078 		graph->preds[n] = BITMAP_ALLOC (&predbitmap_obstack);
2079 	      bitmap_ior_into (graph->preds[n], graph->preds[w]);
2080 	    }
2081 	  if (graph->implicit_preds[w])
2082 	    {
2083 	      if (!graph->implicit_preds[n])
2084 		graph->implicit_preds[n] = BITMAP_ALLOC (&predbitmap_obstack);
2085 	      bitmap_ior_into (graph->implicit_preds[n],
2086 			       graph->implicit_preds[w]);
2087 	    }
2088 	  if (graph->points_to[w])
2089 	    {
2090 	      if (!graph->points_to[n])
2091 		graph->points_to[n] = BITMAP_ALLOC (&predbitmap_obstack);
2092 	      bitmap_ior_into (graph->points_to[n],
2093 			       graph->points_to[w]);
2094 	    }
2095 	}
2096       bitmap_set_bit (si->deleted, n);
2097     }
2098   else
2099     si->scc_stack.safe_push (n);
2100 }
2101 
2102 /* Label pointer equivalences.
2103 
2104    This performs a value numbering of the constraint graph to
2105    discover which variables will always have the same points-to sets
2106    under the current set of constraints.
2107 
2108    The way it value numbers is to store the set of points-to bits
2109    generated by the constraints and graph edges.  This is just used as a
2110    hash and equality comparison.  The *actual set of points-to bits* is
2111    completely irrelevant, in that we don't care about being able to
2112    extract them later.
2113 
2114    The equality values (currently bitmaps) just have to satisfy a few
2115    constraints, the main ones being:
2116    1. The combining operation must be order independent.
2117    2. The end result of a given set of operations must be unique iff the
2118       combination of input values is unique
2119    3. Hashable.  */
2120 
2121 static void
label_visit(constraint_graph_t graph,struct scc_info * si,unsigned int n)2122 label_visit (constraint_graph_t graph, struct scc_info *si, unsigned int n)
2123 {
2124   unsigned int i, first_pred;
2125   bitmap_iterator bi;
2126 
2127   bitmap_set_bit (si->visited, n);
2128 
2129   /* Label and union our incoming edges's points to sets.  */
2130   first_pred = -1U;
2131   EXECUTE_IF_IN_NONNULL_BITMAP (graph->preds[n], 0, i, bi)
2132     {
2133       unsigned int w = si->node_mapping[i];
2134       if (!bitmap_bit_p (si->visited, w))
2135 	label_visit (graph, si, w);
2136 
2137       /* Skip unused edges  */
2138       if (w == n || graph->pointer_label[w] == 0)
2139 	continue;
2140 
2141       if (graph->points_to[w])
2142 	{
2143 	  if (!graph->points_to[n])
2144 	    {
2145 	      if (first_pred == -1U)
2146 		first_pred = w;
2147 	      else
2148 		{
2149 		  graph->points_to[n] = BITMAP_ALLOC (&predbitmap_obstack);
2150 		  bitmap_ior (graph->points_to[n],
2151 			      graph->points_to[first_pred],
2152 			      graph->points_to[w]);
2153 		}
2154 	    }
2155 	  else
2156 	    bitmap_ior_into (graph->points_to[n], graph->points_to[w]);
2157 	}
2158     }
2159 
2160   /* Indirect nodes get fresh variables and a new pointer equiv class.  */
2161   if (!bitmap_bit_p (graph->direct_nodes, n))
2162     {
2163       if (!graph->points_to[n])
2164 	{
2165 	  graph->points_to[n] = BITMAP_ALLOC (&predbitmap_obstack);
2166 	  if (first_pred != -1U)
2167 	    bitmap_copy (graph->points_to[n], graph->points_to[first_pred]);
2168 	}
2169       bitmap_set_bit (graph->points_to[n], FIRST_REF_NODE + n);
2170       graph->pointer_label[n] = pointer_equiv_class++;
2171       equiv_class_label_t ecl;
2172       ecl = equiv_class_lookup_or_add (pointer_equiv_class_table,
2173 				       graph->points_to[n]);
2174       ecl->equivalence_class = graph->pointer_label[n];
2175       return;
2176     }
2177 
2178   /* If there was only a single non-empty predecessor the pointer equiv
2179      class is the same.  */
2180   if (!graph->points_to[n])
2181     {
2182       if (first_pred != -1U)
2183 	{
2184 	  graph->pointer_label[n] = graph->pointer_label[first_pred];
2185 	  graph->points_to[n] = graph->points_to[first_pred];
2186 	}
2187       return;
2188     }
2189 
2190   if (!bitmap_empty_p (graph->points_to[n]))
2191     {
2192       equiv_class_label_t ecl;
2193       ecl = equiv_class_lookup_or_add (pointer_equiv_class_table,
2194 				       graph->points_to[n]);
2195       if (ecl->equivalence_class == 0)
2196 	ecl->equivalence_class = pointer_equiv_class++;
2197       else
2198 	{
2199 	  BITMAP_FREE (graph->points_to[n]);
2200 	  graph->points_to[n] = ecl->labels;
2201 	}
2202       graph->pointer_label[n] = ecl->equivalence_class;
2203     }
2204 }
2205 
2206 /* Print the pred graph in dot format.  */
2207 
2208 static void
dump_pred_graph(struct scc_info * si,FILE * file)2209 dump_pred_graph (struct scc_info *si, FILE *file)
2210 {
2211   unsigned int i;
2212 
2213   /* Only print the graph if it has already been initialized:  */
2214   if (!graph)
2215     return;
2216 
2217   /* Prints the header of the dot file:  */
2218   fprintf (file, "strict digraph {\n");
2219   fprintf (file, "  node [\n    shape = box\n  ]\n");
2220   fprintf (file, "  edge [\n    fontsize = \"12\"\n  ]\n");
2221   fprintf (file, "\n  // List of nodes and complex constraints in "
2222 	   "the constraint graph:\n");
2223 
2224   /* The next lines print the nodes in the graph together with the
2225      complex constraints attached to them.  */
2226   for (i = 1; i < graph->size; i++)
2227     {
2228       if (i == FIRST_REF_NODE)
2229 	continue;
2230       if (si->node_mapping[i] != i)
2231 	continue;
2232       if (i < FIRST_REF_NODE)
2233 	fprintf (file, "\"%s\"", get_varinfo (i)->name);
2234       else
2235 	fprintf (file, "\"*%s\"", get_varinfo (i - FIRST_REF_NODE)->name);
2236       if (graph->points_to[i]
2237 	  && !bitmap_empty_p (graph->points_to[i]))
2238 	{
2239 	  if (i < FIRST_REF_NODE)
2240 	    fprintf (file, "[label=\"%s = {", get_varinfo (i)->name);
2241 	  else
2242 	    fprintf (file, "[label=\"*%s = {",
2243 		     get_varinfo (i - FIRST_REF_NODE)->name);
2244 	  unsigned j;
2245 	  bitmap_iterator bi;
2246 	  EXECUTE_IF_SET_IN_BITMAP (graph->points_to[i], 0, j, bi)
2247 	    fprintf (file, " %d", j);
2248 	  fprintf (file, " }\"]");
2249 	}
2250       fprintf (file, ";\n");
2251     }
2252 
2253   /* Go over the edges.  */
2254   fprintf (file, "\n  // Edges in the constraint graph:\n");
2255   for (i = 1; i < graph->size; i++)
2256     {
2257       unsigned j;
2258       bitmap_iterator bi;
2259       if (si->node_mapping[i] != i)
2260 	continue;
2261       EXECUTE_IF_IN_NONNULL_BITMAP (graph->preds[i], 0, j, bi)
2262 	{
2263 	  unsigned from = si->node_mapping[j];
2264 	  if (from < FIRST_REF_NODE)
2265 	    fprintf (file, "\"%s\"", get_varinfo (from)->name);
2266 	  else
2267 	    fprintf (file, "\"*%s\"", get_varinfo (from - FIRST_REF_NODE)->name);
2268 	  fprintf (file, " -> ");
2269 	  if (i < FIRST_REF_NODE)
2270 	    fprintf (file, "\"%s\"", get_varinfo (i)->name);
2271 	  else
2272 	    fprintf (file, "\"*%s\"", get_varinfo (i - FIRST_REF_NODE)->name);
2273 	  fprintf (file, ";\n");
2274 	}
2275     }
2276 
2277   /* Prints the tail of the dot file.  */
2278   fprintf (file, "}\n");
2279 }
2280 
2281 /* Perform offline variable substitution, discovering equivalence
2282    classes, and eliminating non-pointer variables.  */
2283 
2284 static struct scc_info *
perform_var_substitution(constraint_graph_t graph)2285 perform_var_substitution (constraint_graph_t graph)
2286 {
2287   unsigned int i;
2288   unsigned int size = graph->size;
2289   scc_info *si = new scc_info (size);
2290 
2291   bitmap_obstack_initialize (&iteration_obstack);
2292   pointer_equiv_class_table = new hash_table<equiv_class_hasher> (511);
2293   location_equiv_class_table
2294     = new hash_table<equiv_class_hasher> (511);
2295   pointer_equiv_class = 1;
2296   location_equiv_class = 1;
2297 
2298   /* Condense the nodes, which means to find SCC's, count incoming
2299      predecessors, and unite nodes in SCC's.  */
2300   for (i = 1; i < FIRST_REF_NODE; i++)
2301     if (!bitmap_bit_p (si->visited, si->node_mapping[i]))
2302       condense_visit (graph, si, si->node_mapping[i]);
2303 
2304   if (dump_file && (dump_flags & TDF_GRAPH))
2305     {
2306       fprintf (dump_file, "\n\n// The constraint graph before var-substitution "
2307 	       "in dot format:\n");
2308       dump_pred_graph (si, dump_file);
2309       fprintf (dump_file, "\n\n");
2310     }
2311 
2312   bitmap_clear (si->visited);
2313   /* Actually the label the nodes for pointer equivalences  */
2314   for (i = 1; i < FIRST_REF_NODE; i++)
2315     if (!bitmap_bit_p (si->visited, si->node_mapping[i]))
2316       label_visit (graph, si, si->node_mapping[i]);
2317 
2318   /* Calculate location equivalence labels.  */
2319   for (i = 1; i < FIRST_REF_NODE; i++)
2320     {
2321       bitmap pointed_by;
2322       bitmap_iterator bi;
2323       unsigned int j;
2324 
2325       if (!graph->pointed_by[i])
2326 	continue;
2327       pointed_by = BITMAP_ALLOC (&iteration_obstack);
2328 
2329       /* Translate the pointed-by mapping for pointer equivalence
2330 	 labels.  */
2331       EXECUTE_IF_SET_IN_BITMAP (graph->pointed_by[i], 0, j, bi)
2332 	{
2333 	  bitmap_set_bit (pointed_by,
2334 			  graph->pointer_label[si->node_mapping[j]]);
2335 	}
2336       /* The original pointed_by is now dead.  */
2337       BITMAP_FREE (graph->pointed_by[i]);
2338 
2339       /* Look up the location equivalence label if one exists, or make
2340 	 one otherwise.  */
2341       equiv_class_label_t ecl;
2342       ecl = equiv_class_lookup_or_add (location_equiv_class_table, pointed_by);
2343       if (ecl->equivalence_class == 0)
2344 	ecl->equivalence_class = location_equiv_class++;
2345       else
2346 	{
2347 	  if (dump_file && (dump_flags & TDF_DETAILS))
2348 	    fprintf (dump_file, "Found location equivalence for node %s\n",
2349 		     get_varinfo (i)->name);
2350 	  BITMAP_FREE (pointed_by);
2351 	}
2352       graph->loc_label[i] = ecl->equivalence_class;
2353 
2354     }
2355 
2356   if (dump_file && (dump_flags & TDF_DETAILS))
2357     for (i = 1; i < FIRST_REF_NODE; i++)
2358       {
2359 	unsigned j = si->node_mapping[i];
2360 	if (j != i)
2361 	  {
2362 	    fprintf (dump_file, "%s node id %d ",
2363 		     bitmap_bit_p (graph->direct_nodes, i)
2364 		     ? "Direct" : "Indirect", i);
2365 	    if (i < FIRST_REF_NODE)
2366 	      fprintf (dump_file, "\"%s\"", get_varinfo (i)->name);
2367 	    else
2368 	      fprintf (dump_file, "\"*%s\"",
2369 		       get_varinfo (i - FIRST_REF_NODE)->name);
2370 	    fprintf (dump_file, " mapped to SCC leader node id %d ", j);
2371 	    if (j < FIRST_REF_NODE)
2372 	      fprintf (dump_file, "\"%s\"\n", get_varinfo (j)->name);
2373 	    else
2374 	      fprintf (dump_file, "\"*%s\"\n",
2375 		       get_varinfo (j - FIRST_REF_NODE)->name);
2376 	  }
2377 	else
2378 	  {
2379 	    fprintf (dump_file,
2380 		     "Equivalence classes for %s node id %d ",
2381 		     bitmap_bit_p (graph->direct_nodes, i)
2382 		     ? "direct" : "indirect", i);
2383 	    if (i < FIRST_REF_NODE)
2384 	      fprintf (dump_file, "\"%s\"", get_varinfo (i)->name);
2385 	    else
2386 	      fprintf (dump_file, "\"*%s\"",
2387 		       get_varinfo (i - FIRST_REF_NODE)->name);
2388 	    fprintf (dump_file,
2389 		     ": pointer %d, location %d\n",
2390 		     graph->pointer_label[i], graph->loc_label[i]);
2391 	  }
2392       }
2393 
2394   /* Quickly eliminate our non-pointer variables.  */
2395 
2396   for (i = 1; i < FIRST_REF_NODE; i++)
2397     {
2398       unsigned int node = si->node_mapping[i];
2399 
2400       if (graph->pointer_label[node] == 0)
2401 	{
2402 	  if (dump_file && (dump_flags & TDF_DETAILS))
2403 	    fprintf (dump_file,
2404 		     "%s is a non-pointer variable, eliminating edges.\n",
2405 		     get_varinfo (node)->name);
2406 	  stats.nonpointer_vars++;
2407 	  clear_edges_for_node (graph, node);
2408 	}
2409     }
2410 
2411   return si;
2412 }
2413 
2414 /* Free information that was only necessary for variable
2415    substitution.  */
2416 
2417 static void
free_var_substitution_info(struct scc_info * si)2418 free_var_substitution_info (struct scc_info *si)
2419 {
2420   delete si;
2421   free (graph->pointer_label);
2422   free (graph->loc_label);
2423   free (graph->pointed_by);
2424   free (graph->points_to);
2425   free (graph->eq_rep);
2426   sbitmap_free (graph->direct_nodes);
2427   delete pointer_equiv_class_table;
2428   pointer_equiv_class_table = NULL;
2429   delete location_equiv_class_table;
2430   location_equiv_class_table = NULL;
2431   bitmap_obstack_release (&iteration_obstack);
2432 }
2433 
2434 /* Return an existing node that is equivalent to NODE, which has
2435    equivalence class LABEL, if one exists.  Return NODE otherwise.  */
2436 
2437 static unsigned int
find_equivalent_node(constraint_graph_t graph,unsigned int node,unsigned int label)2438 find_equivalent_node (constraint_graph_t graph,
2439 		      unsigned int node, unsigned int label)
2440 {
2441   /* If the address version of this variable is unused, we can
2442      substitute it for anything else with the same label.
2443      Otherwise, we know the pointers are equivalent, but not the
2444      locations, and we can unite them later.  */
2445 
2446   if (!bitmap_bit_p (graph->address_taken, node))
2447     {
2448       gcc_checking_assert (label < graph->size);
2449 
2450       if (graph->eq_rep[label] != -1)
2451 	{
2452 	  /* Unify the two variables since we know they are equivalent.  */
2453 	  if (unite (graph->eq_rep[label], node))
2454 	    unify_nodes (graph, graph->eq_rep[label], node, false);
2455 	  return graph->eq_rep[label];
2456 	}
2457       else
2458 	{
2459 	  graph->eq_rep[label] = node;
2460 	  graph->pe_rep[label] = node;
2461 	}
2462     }
2463   else
2464     {
2465       gcc_checking_assert (label < graph->size);
2466       graph->pe[node] = label;
2467       if (graph->pe_rep[label] == -1)
2468 	graph->pe_rep[label] = node;
2469     }
2470 
2471   return node;
2472 }
2473 
2474 /* Unite pointer equivalent but not location equivalent nodes in
2475    GRAPH.  This may only be performed once variable substitution is
2476    finished.  */
2477 
2478 static void
unite_pointer_equivalences(constraint_graph_t graph)2479 unite_pointer_equivalences (constraint_graph_t graph)
2480 {
2481   unsigned int i;
2482 
2483   /* Go through the pointer equivalences and unite them to their
2484      representative, if they aren't already.  */
2485   for (i = 1; i < FIRST_REF_NODE; i++)
2486     {
2487       unsigned int label = graph->pe[i];
2488       if (label)
2489 	{
2490 	  int label_rep = graph->pe_rep[label];
2491 
2492 	  if (label_rep == -1)
2493 	    continue;
2494 
2495 	  label_rep = find (label_rep);
2496 	  if (label_rep >= 0 && unite (label_rep, find (i)))
2497 	    unify_nodes (graph, label_rep, i, false);
2498 	}
2499     }
2500 }
2501 
2502 /* Move complex constraints to the GRAPH nodes they belong to.  */
2503 
2504 static void
move_complex_constraints(constraint_graph_t graph)2505 move_complex_constraints (constraint_graph_t graph)
2506 {
2507   int i;
2508   constraint_t c;
2509 
2510   FOR_EACH_VEC_ELT (constraints, i, c)
2511     {
2512       if (c)
2513 	{
2514 	  struct constraint_expr lhs = c->lhs;
2515 	  struct constraint_expr rhs = c->rhs;
2516 
2517 	  if (lhs.type == DEREF)
2518 	    {
2519 	      insert_into_complex (graph, lhs.var, c);
2520 	    }
2521 	  else if (rhs.type == DEREF)
2522 	    {
2523 	      if (!(get_varinfo (lhs.var)->is_special_var))
2524 		insert_into_complex (graph, rhs.var, c);
2525 	    }
2526 	  else if (rhs.type != ADDRESSOF && lhs.var > anything_id
2527 		   && (lhs.offset != 0 || rhs.offset != 0))
2528 	    {
2529 	      insert_into_complex (graph, rhs.var, c);
2530 	    }
2531 	}
2532     }
2533 }
2534 
2535 
2536 /* Optimize and rewrite complex constraints while performing
2537    collapsing of equivalent nodes.  SI is the SCC_INFO that is the
2538    result of perform_variable_substitution.  */
2539 
2540 static void
rewrite_constraints(constraint_graph_t graph,struct scc_info * si)2541 rewrite_constraints (constraint_graph_t graph,
2542 		     struct scc_info *si)
2543 {
2544   int i;
2545   constraint_t c;
2546 
2547   if (flag_checking)
2548     {
2549       for (unsigned int j = 0; j < graph->size; j++)
2550 	gcc_assert (find (j) == j);
2551     }
2552 
2553   FOR_EACH_VEC_ELT (constraints, i, c)
2554     {
2555       struct constraint_expr lhs = c->lhs;
2556       struct constraint_expr rhs = c->rhs;
2557       unsigned int lhsvar = find (lhs.var);
2558       unsigned int rhsvar = find (rhs.var);
2559       unsigned int lhsnode, rhsnode;
2560       unsigned int lhslabel, rhslabel;
2561 
2562       lhsnode = si->node_mapping[lhsvar];
2563       rhsnode = si->node_mapping[rhsvar];
2564       lhslabel = graph->pointer_label[lhsnode];
2565       rhslabel = graph->pointer_label[rhsnode];
2566 
2567       /* See if it is really a non-pointer variable, and if so, ignore
2568 	 the constraint.  */
2569       if (lhslabel == 0)
2570 	{
2571 	  if (dump_file && (dump_flags & TDF_DETAILS))
2572 	    {
2573 
2574 	      fprintf (dump_file, "%s is a non-pointer variable, "
2575 		       "ignoring constraint:",
2576 		       get_varinfo (lhs.var)->name);
2577 	      dump_constraint (dump_file, c);
2578 	      fprintf (dump_file, "\n");
2579 	    }
2580 	  constraints[i] = NULL;
2581 	  continue;
2582 	}
2583 
2584       if (rhslabel == 0)
2585 	{
2586 	  if (dump_file && (dump_flags & TDF_DETAILS))
2587 	    {
2588 
2589 	      fprintf (dump_file, "%s is a non-pointer variable, "
2590 		       "ignoring constraint:",
2591 		       get_varinfo (rhs.var)->name);
2592 	      dump_constraint (dump_file, c);
2593 	      fprintf (dump_file, "\n");
2594 	    }
2595 	  constraints[i] = NULL;
2596 	  continue;
2597 	}
2598 
2599       lhsvar = find_equivalent_node (graph, lhsvar, lhslabel);
2600       rhsvar = find_equivalent_node (graph, rhsvar, rhslabel);
2601       c->lhs.var = lhsvar;
2602       c->rhs.var = rhsvar;
2603     }
2604 }
2605 
2606 /* Eliminate indirect cycles involving NODE.  Return true if NODE was
2607    part of an SCC, false otherwise.  */
2608 
2609 static bool
eliminate_indirect_cycles(unsigned int node)2610 eliminate_indirect_cycles (unsigned int node)
2611 {
2612   if (graph->indirect_cycles[node] != -1
2613       && !bitmap_empty_p (get_varinfo (node)->solution))
2614     {
2615       unsigned int i;
2616       auto_vec<unsigned> queue;
2617       int queuepos;
2618       unsigned int to = find (graph->indirect_cycles[node]);
2619       bitmap_iterator bi;
2620 
2621       /* We can't touch the solution set and call unify_nodes
2622 	 at the same time, because unify_nodes is going to do
2623 	 bitmap unions into it. */
2624 
2625       EXECUTE_IF_SET_IN_BITMAP (get_varinfo (node)->solution, 0, i, bi)
2626 	{
2627 	  if (find (i) == i && i != to)
2628 	    {
2629 	      if (unite (to, i))
2630 		queue.safe_push (i);
2631 	    }
2632 	}
2633 
2634       for (queuepos = 0;
2635 	   queue.iterate (queuepos, &i);
2636 	   queuepos++)
2637 	{
2638 	  unify_nodes (graph, to, i, true);
2639 	}
2640       return true;
2641     }
2642   return false;
2643 }
2644 
2645 /* Solve the constraint graph GRAPH using our worklist solver.
2646    This is based on the PW* family of solvers from the "Efficient Field
2647    Sensitive Pointer Analysis for C" paper.
2648    It works by iterating over all the graph nodes, processing the complex
2649    constraints and propagating the copy constraints, until everything stops
2650    changed.  This corresponds to steps 6-8 in the solving list given above.  */
2651 
2652 static void
solve_graph(constraint_graph_t graph)2653 solve_graph (constraint_graph_t graph)
2654 {
2655   unsigned int size = graph->size;
2656   unsigned int i;
2657   bitmap pts;
2658 
2659   changed = BITMAP_ALLOC (NULL);
2660 
2661   /* Mark all initial non-collapsed nodes as changed.  */
2662   for (i = 1; i < size; i++)
2663     {
2664       varinfo_t ivi = get_varinfo (i);
2665       if (find (i) == i && !bitmap_empty_p (ivi->solution)
2666 	  && ((graph->succs[i] && !bitmap_empty_p (graph->succs[i]))
2667 	      || graph->complex[i].length () > 0))
2668 	bitmap_set_bit (changed, i);
2669     }
2670 
2671   /* Allocate a bitmap to be used to store the changed bits.  */
2672   pts = BITMAP_ALLOC (&pta_obstack);
2673 
2674   while (!bitmap_empty_p (changed))
2675     {
2676       unsigned int i;
2677       struct topo_info *ti = init_topo_info ();
2678       stats.iterations++;
2679 
2680       bitmap_obstack_initialize (&iteration_obstack);
2681 
2682       compute_topo_order (graph, ti);
2683 
2684       while (ti->topo_order.length () != 0)
2685 	{
2686 
2687 	  i = ti->topo_order.pop ();
2688 
2689 	  /* If this variable is not a representative, skip it.  */
2690 	  if (find (i) != i)
2691 	    continue;
2692 
2693 	  /* In certain indirect cycle cases, we may merge this
2694 	     variable to another.  */
2695 	  if (eliminate_indirect_cycles (i) && find (i) != i)
2696 	    continue;
2697 
2698 	  /* If the node has changed, we need to process the
2699 	     complex constraints and outgoing edges again.  */
2700 	  if (bitmap_clear_bit (changed, i))
2701 	    {
2702 	      unsigned int j;
2703 	      constraint_t c;
2704 	      bitmap solution;
2705 	      vec<constraint_t> complex = graph->complex[i];
2706 	      varinfo_t vi = get_varinfo (i);
2707 	      bool solution_empty;
2708 
2709 	      /* Compute the changed set of solution bits.  If anything
2710 	         is in the solution just propagate that.  */
2711 	      if (bitmap_bit_p (vi->solution, anything_id))
2712 		{
2713 		  /* If anything is also in the old solution there is
2714 		     nothing to do.
2715 		     ???  But we shouldn't ended up with "changed" set ...  */
2716 		  if (vi->oldsolution
2717 		      && bitmap_bit_p (vi->oldsolution, anything_id))
2718 		    continue;
2719 		  bitmap_copy (pts, get_varinfo (find (anything_id))->solution);
2720 		}
2721 	      else if (vi->oldsolution)
2722 		bitmap_and_compl (pts, vi->solution, vi->oldsolution);
2723 	      else
2724 		bitmap_copy (pts, vi->solution);
2725 
2726 	      if (bitmap_empty_p (pts))
2727 		continue;
2728 
2729 	      if (vi->oldsolution)
2730 		bitmap_ior_into (vi->oldsolution, pts);
2731 	      else
2732 		{
2733 		  vi->oldsolution = BITMAP_ALLOC (&oldpta_obstack);
2734 		  bitmap_copy (vi->oldsolution, pts);
2735 		}
2736 
2737 	      solution = vi->solution;
2738 	      solution_empty = bitmap_empty_p (solution);
2739 
2740 	      /* Process the complex constraints */
2741 	      bitmap expanded_pts = NULL;
2742 	      FOR_EACH_VEC_ELT (complex, j, c)
2743 		{
2744 		  /* XXX: This is going to unsort the constraints in
2745 		     some cases, which will occasionally add duplicate
2746 		     constraints during unification.  This does not
2747 		     affect correctness.  */
2748 		  c->lhs.var = find (c->lhs.var);
2749 		  c->rhs.var = find (c->rhs.var);
2750 
2751 		  /* The only complex constraint that can change our
2752 		     solution to non-empty, given an empty solution,
2753 		     is a constraint where the lhs side is receiving
2754 		     some set from elsewhere.  */
2755 		  if (!solution_empty || c->lhs.type != DEREF)
2756 		    do_complex_constraint (graph, c, pts, &expanded_pts);
2757 		}
2758 	      BITMAP_FREE (expanded_pts);
2759 
2760 	      solution_empty = bitmap_empty_p (solution);
2761 
2762 	      if (!solution_empty)
2763 		{
2764 		  bitmap_iterator bi;
2765 		  unsigned eff_escaped_id = find (escaped_id);
2766 
2767 		  /* Propagate solution to all successors.  */
2768 		  unsigned to_remove = ~0U;
2769 		  EXECUTE_IF_IN_NONNULL_BITMAP (graph->succs[i],
2770 						0, j, bi)
2771 		    {
2772 		      if (to_remove != ~0U)
2773 			{
2774 			  bitmap_clear_bit (graph->succs[i], to_remove);
2775 			  to_remove = ~0U;
2776 			}
2777 		      unsigned int to = find (j);
2778 		      if (to != j)
2779 			{
2780 			  /* Update the succ graph, avoiding duplicate
2781 			     work.  */
2782 			  to_remove = j;
2783 			  if (! bitmap_set_bit (graph->succs[i], to))
2784 			    continue;
2785 			  /* We eventually end up processing 'to' twice
2786 			     as it is undefined whether bitmap iteration
2787 			     iterates over bits set during iteration.
2788 			     Play safe instead of doing tricks.  */
2789 			}
2790 		      /* Don't try to propagate to ourselves.  */
2791 		      if (to == i)
2792 			continue;
2793 
2794 		      bitmap tmp = get_varinfo (to)->solution;
2795 		      bool flag = false;
2796 
2797 		      /* If we propagate from ESCAPED use ESCAPED as
2798 		         placeholder.  */
2799 		      if (i == eff_escaped_id)
2800 			flag = bitmap_set_bit (tmp, escaped_id);
2801 		      else
2802 			flag = bitmap_ior_into (tmp, pts);
2803 
2804 		      if (flag)
2805 			bitmap_set_bit (changed, to);
2806 		    }
2807 		  if (to_remove != ~0U)
2808 		    bitmap_clear_bit (graph->succs[i], to_remove);
2809 		}
2810 	    }
2811 	}
2812       free_topo_info (ti);
2813       bitmap_obstack_release (&iteration_obstack);
2814     }
2815 
2816   BITMAP_FREE (pts);
2817   BITMAP_FREE (changed);
2818   bitmap_obstack_release (&oldpta_obstack);
2819 }
2820 
2821 /* Map from trees to variable infos.  */
2822 static hash_map<tree, varinfo_t> *vi_for_tree;
2823 
2824 
2825 /* Insert ID as the variable id for tree T in the vi_for_tree map.  */
2826 
2827 static void
insert_vi_for_tree(tree t,varinfo_t vi)2828 insert_vi_for_tree (tree t, varinfo_t vi)
2829 {
2830   gcc_assert (vi);
2831   gcc_assert (!vi_for_tree->put (t, vi));
2832 }
2833 
2834 /* Find the variable info for tree T in VI_FOR_TREE.  If T does not
2835    exist in the map, return NULL, otherwise, return the varinfo we found.  */
2836 
2837 static varinfo_t
lookup_vi_for_tree(tree t)2838 lookup_vi_for_tree (tree t)
2839 {
2840   varinfo_t *slot = vi_for_tree->get (t);
2841   if (slot == NULL)
2842     return NULL;
2843 
2844   return *slot;
2845 }
2846 
2847 /* Return a printable name for DECL  */
2848 
2849 static const char *
alias_get_name(tree decl)2850 alias_get_name (tree decl)
2851 {
2852   const char *res = "NULL";
2853   if (dump_file)
2854     {
2855       char *temp = NULL;
2856       if (TREE_CODE (decl) == SSA_NAME)
2857 	{
2858 	  res = get_name (decl);
2859 	  temp = xasprintf ("%s_%u", res ? res : "", SSA_NAME_VERSION (decl));
2860 	}
2861       else if (HAS_DECL_ASSEMBLER_NAME_P (decl)
2862 	       && DECL_ASSEMBLER_NAME_SET_P (decl))
2863 	res = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME_RAW (decl));
2864       else if (DECL_P (decl))
2865 	{
2866 	  res = get_name (decl);
2867 	  if (!res)
2868 	    temp = xasprintf ("D.%u", DECL_UID (decl));
2869 	}
2870 
2871       if (temp)
2872 	{
2873 	  res = ggc_strdup (temp);
2874 	  free (temp);
2875 	}
2876     }
2877 
2878   return res;
2879 }
2880 
2881 /* Find the variable id for tree T in the map.
2882    If T doesn't exist in the map, create an entry for it and return it.  */
2883 
2884 static varinfo_t
get_vi_for_tree(tree t)2885 get_vi_for_tree (tree t)
2886 {
2887   varinfo_t *slot = vi_for_tree->get (t);
2888   if (slot == NULL)
2889     {
2890       unsigned int id = create_variable_info_for (t, alias_get_name (t), false);
2891       return get_varinfo (id);
2892     }
2893 
2894   return *slot;
2895 }
2896 
2897 /* Get a scalar constraint expression for a new temporary variable.  */
2898 
2899 static struct constraint_expr
new_scalar_tmp_constraint_exp(const char * name,bool add_id)2900 new_scalar_tmp_constraint_exp (const char *name, bool add_id)
2901 {
2902   struct constraint_expr tmp;
2903   varinfo_t vi;
2904 
2905   vi = new_var_info (NULL_TREE, name, add_id);
2906   vi->offset = 0;
2907   vi->size = -1;
2908   vi->fullsize = -1;
2909   vi->is_full_var = 1;
2910   vi->is_reg_var = 1;
2911 
2912   tmp.var = vi->id;
2913   tmp.type = SCALAR;
2914   tmp.offset = 0;
2915 
2916   return tmp;
2917 }
2918 
2919 /* Get a constraint expression vector from an SSA_VAR_P node.
2920    If address_p is true, the result will be taken its address of.  */
2921 
2922 static void
get_constraint_for_ssa_var(tree t,vec<ce_s> * results,bool address_p)2923 get_constraint_for_ssa_var (tree t, vec<ce_s> *results, bool address_p)
2924 {
2925   struct constraint_expr cexpr;
2926   varinfo_t vi;
2927 
2928   /* We allow FUNCTION_DECLs here even though it doesn't make much sense.  */
2929   gcc_assert (TREE_CODE (t) == SSA_NAME || DECL_P (t));
2930 
2931   /* For parameters, get at the points-to set for the actual parm
2932      decl.  */
2933   if (TREE_CODE (t) == SSA_NAME
2934       && SSA_NAME_IS_DEFAULT_DEF (t)
2935       && (TREE_CODE (SSA_NAME_VAR (t)) == PARM_DECL
2936 	  || TREE_CODE (SSA_NAME_VAR (t)) == RESULT_DECL))
2937     {
2938       get_constraint_for_ssa_var (SSA_NAME_VAR (t), results, address_p);
2939       return;
2940     }
2941 
2942   /* For global variables resort to the alias target.  */
2943   if (VAR_P (t) && (TREE_STATIC (t) || DECL_EXTERNAL (t)))
2944     {
2945       varpool_node *node = varpool_node::get (t);
2946       if (node && node->alias && node->analyzed)
2947 	{
2948 	  node = node->ultimate_alias_target ();
2949 	  /* Canonicalize the PT uid of all aliases to the ultimate target.
2950 	     ???  Hopefully the set of aliases can't change in a way that
2951 	     changes the ultimate alias target.  */
2952 	  gcc_assert ((! DECL_PT_UID_SET_P (node->decl)
2953 		       || DECL_PT_UID (node->decl) == DECL_UID (node->decl))
2954 		      && (! DECL_PT_UID_SET_P (t)
2955 			  || DECL_PT_UID (t) == DECL_UID (node->decl)));
2956 	  DECL_PT_UID (t) = DECL_UID (node->decl);
2957 	  t = node->decl;
2958 	}
2959 
2960       /* If this is decl may bind to NULL note that.  */
2961       if (address_p
2962 	  && (! node || ! node->nonzero_address ()))
2963 	{
2964 	  cexpr.var = nothing_id;
2965 	  cexpr.type = SCALAR;
2966 	  cexpr.offset = 0;
2967 	  results->safe_push (cexpr);
2968 	}
2969     }
2970 
2971   vi = get_vi_for_tree (t);
2972   cexpr.var = vi->id;
2973   cexpr.type = SCALAR;
2974   cexpr.offset = 0;
2975 
2976   /* If we are not taking the address of the constraint expr, add all
2977      sub-fiels of the variable as well.  */
2978   if (!address_p
2979       && !vi->is_full_var)
2980     {
2981       for (; vi; vi = vi_next (vi))
2982 	{
2983 	  cexpr.var = vi->id;
2984 	  results->safe_push (cexpr);
2985 	}
2986       return;
2987     }
2988 
2989   results->safe_push (cexpr);
2990 }
2991 
2992 /* Process constraint T, performing various simplifications and then
2993    adding it to our list of overall constraints.  */
2994 
2995 static void
process_constraint(constraint_t t)2996 process_constraint (constraint_t t)
2997 {
2998   struct constraint_expr rhs = t->rhs;
2999   struct constraint_expr lhs = t->lhs;
3000 
3001   gcc_assert (rhs.var < varmap.length ());
3002   gcc_assert (lhs.var < varmap.length ());
3003 
3004   /* If we didn't get any useful constraint from the lhs we get
3005      &ANYTHING as fallback from get_constraint_for.  Deal with
3006      it here by turning it into *ANYTHING.  */
3007   if (lhs.type == ADDRESSOF
3008       && lhs.var == anything_id)
3009     lhs.type = DEREF;
3010 
3011   /* ADDRESSOF on the lhs is invalid.  */
3012   gcc_assert (lhs.type != ADDRESSOF);
3013 
3014   /* We shouldn't add constraints from things that cannot have pointers.
3015      It's not completely trivial to avoid in the callers, so do it here.  */
3016   if (rhs.type != ADDRESSOF
3017       && !get_varinfo (rhs.var)->may_have_pointers)
3018     return;
3019 
3020   /* Likewise adding to the solution of a non-pointer var isn't useful.  */
3021   if (!get_varinfo (lhs.var)->may_have_pointers)
3022     return;
3023 
3024   /* This can happen in our IR with things like n->a = *p */
3025   if (rhs.type == DEREF && lhs.type == DEREF && rhs.var != anything_id)
3026     {
3027       /* Split into tmp = *rhs, *lhs = tmp */
3028       struct constraint_expr tmplhs;
3029       tmplhs = new_scalar_tmp_constraint_exp ("doubledereftmp", true);
3030       process_constraint (new_constraint (tmplhs, rhs));
3031       process_constraint (new_constraint (lhs, tmplhs));
3032     }
3033   else if ((rhs.type != SCALAR || rhs.offset != 0) && lhs.type == DEREF)
3034     {
3035       /* Split into tmp = &rhs, *lhs = tmp */
3036       struct constraint_expr tmplhs;
3037       tmplhs = new_scalar_tmp_constraint_exp ("derefaddrtmp", true);
3038       process_constraint (new_constraint (tmplhs, rhs));
3039       process_constraint (new_constraint (lhs, tmplhs));
3040     }
3041   else
3042     {
3043       gcc_assert (rhs.type != ADDRESSOF || rhs.offset == 0);
3044       constraints.safe_push (t);
3045     }
3046 }
3047 
3048 
3049 /* Return the position, in bits, of FIELD_DECL from the beginning of its
3050    structure.  */
3051 
3052 static HOST_WIDE_INT
bitpos_of_field(const tree fdecl)3053 bitpos_of_field (const tree fdecl)
3054 {
3055   if (!tree_fits_shwi_p (DECL_FIELD_OFFSET (fdecl))
3056       || !tree_fits_shwi_p (DECL_FIELD_BIT_OFFSET (fdecl)))
3057     return -1;
3058 
3059   return (tree_to_shwi (DECL_FIELD_OFFSET (fdecl)) * BITS_PER_UNIT
3060 	  + tree_to_shwi (DECL_FIELD_BIT_OFFSET (fdecl)));
3061 }
3062 
3063 
3064 /* Get constraint expressions for offsetting PTR by OFFSET.  Stores the
3065    resulting constraint expressions in *RESULTS.  */
3066 
3067 static void
get_constraint_for_ptr_offset(tree ptr,tree offset,vec<ce_s> * results)3068 get_constraint_for_ptr_offset (tree ptr, tree offset,
3069 			       vec<ce_s> *results)
3070 {
3071   struct constraint_expr c;
3072   unsigned int j, n;
3073   HOST_WIDE_INT rhsoffset;
3074 
3075   /* If we do not do field-sensitive PTA adding offsets to pointers
3076      does not change the points-to solution.  */
3077   if (!use_field_sensitive)
3078     {
3079       get_constraint_for_rhs (ptr, results);
3080       return;
3081     }
3082 
3083   /* If the offset is not a non-negative integer constant that fits
3084      in a HOST_WIDE_INT, we have to fall back to a conservative
3085      solution which includes all sub-fields of all pointed-to
3086      variables of ptr.  */
3087   if (offset == NULL_TREE
3088       || TREE_CODE (offset) != INTEGER_CST)
3089     rhsoffset = UNKNOWN_OFFSET;
3090   else
3091     {
3092       /* Sign-extend the offset.  */
3093       offset_int soffset = offset_int::from (wi::to_wide (offset), SIGNED);
3094       if (!wi::fits_shwi_p (soffset))
3095 	rhsoffset = UNKNOWN_OFFSET;
3096       else
3097 	{
3098 	  /* Make sure the bit-offset also fits.  */
3099 	  HOST_WIDE_INT rhsunitoffset = soffset.to_shwi ();
3100 	  rhsoffset = rhsunitoffset * (unsigned HOST_WIDE_INT) BITS_PER_UNIT;
3101 	  if (rhsunitoffset != rhsoffset / BITS_PER_UNIT)
3102 	    rhsoffset = UNKNOWN_OFFSET;
3103 	}
3104     }
3105 
3106   get_constraint_for_rhs (ptr, results);
3107   if (rhsoffset == 0)
3108     return;
3109 
3110   /* As we are eventually appending to the solution do not use
3111      vec::iterate here.  */
3112   n = results->length ();
3113   for (j = 0; j < n; j++)
3114     {
3115       varinfo_t curr;
3116       c = (*results)[j];
3117       curr = get_varinfo (c.var);
3118 
3119       if (c.type == ADDRESSOF
3120 	  /* If this varinfo represents a full variable just use it.  */
3121 	  && curr->is_full_var)
3122 	;
3123       else if (c.type == ADDRESSOF
3124 	       /* If we do not know the offset add all subfields.  */
3125 	       && rhsoffset == UNKNOWN_OFFSET)
3126 	{
3127 	  varinfo_t temp = get_varinfo (curr->head);
3128 	  do
3129 	    {
3130 	      struct constraint_expr c2;
3131 	      c2.var = temp->id;
3132 	      c2.type = ADDRESSOF;
3133 	      c2.offset = 0;
3134 	      if (c2.var != c.var)
3135 		results->safe_push (c2);
3136 	      temp = vi_next (temp);
3137 	    }
3138 	  while (temp);
3139 	}
3140       else if (c.type == ADDRESSOF)
3141 	{
3142 	  varinfo_t temp;
3143 	  unsigned HOST_WIDE_INT offset = curr->offset + rhsoffset;
3144 
3145 	  /* If curr->offset + rhsoffset is less than zero adjust it.  */
3146 	  if (rhsoffset < 0
3147 	      && curr->offset < offset)
3148 	    offset = 0;
3149 
3150 	  /* We have to include all fields that overlap the current
3151 	     field shifted by rhsoffset.  And we include at least
3152 	     the last or the first field of the variable to represent
3153 	     reachability of off-bound addresses, in particular &object + 1,
3154 	     conservatively correct.  */
3155 	  temp = first_or_preceding_vi_for_offset (curr, offset);
3156 	  c.var = temp->id;
3157 	  c.offset = 0;
3158 	  temp = vi_next (temp);
3159 	  while (temp
3160 		 && temp->offset < offset + curr->size)
3161 	    {
3162 	      struct constraint_expr c2;
3163 	      c2.var = temp->id;
3164 	      c2.type = ADDRESSOF;
3165 	      c2.offset = 0;
3166 	      results->safe_push (c2);
3167 	      temp = vi_next (temp);
3168 	    }
3169 	}
3170       else if (c.type == SCALAR)
3171 	{
3172 	  gcc_assert (c.offset == 0);
3173 	  c.offset = rhsoffset;
3174 	}
3175       else
3176 	/* We shouldn't get any DEREFs here.  */
3177 	gcc_unreachable ();
3178 
3179       (*results)[j] = c;
3180     }
3181 }
3182 
3183 
3184 /* Given a COMPONENT_REF T, return the constraint_expr vector for it.
3185    If address_p is true the result will be taken its address of.
3186    If lhs_p is true then the constraint expression is assumed to be used
3187    as the lhs.  */
3188 
3189 static void
get_constraint_for_component_ref(tree t,vec<ce_s> * results,bool address_p,bool lhs_p)3190 get_constraint_for_component_ref (tree t, vec<ce_s> *results,
3191 				  bool address_p, bool lhs_p)
3192 {
3193   tree orig_t = t;
3194   poly_int64 bitsize = -1;
3195   poly_int64 bitmaxsize = -1;
3196   poly_int64 bitpos;
3197   bool reverse;
3198   tree forzero;
3199 
3200   /* Some people like to do cute things like take the address of
3201      &0->a.b */
3202   forzero = t;
3203   while (handled_component_p (forzero)
3204 	 || INDIRECT_REF_P (forzero)
3205 	 || TREE_CODE (forzero) == MEM_REF)
3206     forzero = TREE_OPERAND (forzero, 0);
3207 
3208   if (CONSTANT_CLASS_P (forzero) && integer_zerop (forzero))
3209     {
3210       struct constraint_expr temp;
3211 
3212       temp.offset = 0;
3213       temp.var = integer_id;
3214       temp.type = SCALAR;
3215       results->safe_push (temp);
3216       return;
3217     }
3218 
3219   t = get_ref_base_and_extent (t, &bitpos, &bitsize, &bitmaxsize, &reverse);
3220 
3221   /* We can end up here for component references on a
3222      VIEW_CONVERT_EXPR <>(&foobar) or things like a
3223      BIT_FIELD_REF <&MEM[(void *)&b + 4B], ...>.  So for
3224      symbolic constants simply give up.  */
3225   if (TREE_CODE (t) == ADDR_EXPR)
3226     {
3227       constraint_expr result;
3228       result.type = SCALAR;
3229       result.var = anything_id;
3230       result.offset = 0;
3231       results->safe_push (result);
3232       return;
3233     }
3234 
3235   /* Avoid creating pointer-offset constraints, so handle MEM_REF
3236      offsets directly.  Pretend to take the address of the base,
3237      we'll take care of adding the required subset of sub-fields below.  */
3238   if (TREE_CODE (t) == MEM_REF
3239       && !integer_zerop (TREE_OPERAND (t, 0)))
3240     {
3241       poly_offset_int off = mem_ref_offset (t);
3242       off <<= LOG2_BITS_PER_UNIT;
3243       off += bitpos;
3244       poly_int64 off_hwi;
3245       if (off.to_shwi (&off_hwi))
3246 	bitpos = off_hwi;
3247       else
3248 	{
3249 	  bitpos = 0;
3250 	  bitmaxsize = -1;
3251 	}
3252       get_constraint_for_1 (TREE_OPERAND (t, 0), results, false, lhs_p);
3253       do_deref (results);
3254     }
3255   else
3256     get_constraint_for_1 (t, results, true, lhs_p);
3257 
3258   /* Strip off nothing_id.  */
3259   if (results->length () == 2)
3260     {
3261       gcc_assert ((*results)[0].var == nothing_id);
3262       results->unordered_remove (0);
3263     }
3264   gcc_assert (results->length () == 1);
3265   struct constraint_expr &result = results->last ();
3266 
3267   if (result.type == SCALAR
3268       && get_varinfo (result.var)->is_full_var)
3269     /* For single-field vars do not bother about the offset.  */
3270     result.offset = 0;
3271   else if (result.type == SCALAR)
3272     {
3273       /* In languages like C, you can access one past the end of an
3274 	 array.  You aren't allowed to dereference it, so we can
3275 	 ignore this constraint. When we handle pointer subtraction,
3276 	 we may have to do something cute here.  */
3277 
3278       if (maybe_lt (poly_uint64 (bitpos), get_varinfo (result.var)->fullsize)
3279 	  && maybe_ne (bitmaxsize, 0))
3280 	{
3281 	  /* It's also not true that the constraint will actually start at the
3282 	     right offset, it may start in some padding.  We only care about
3283 	     setting the constraint to the first actual field it touches, so
3284 	     walk to find it.  */
3285 	  struct constraint_expr cexpr = result;
3286 	  varinfo_t curr;
3287 	  results->pop ();
3288 	  cexpr.offset = 0;
3289 	  for (curr = get_varinfo (cexpr.var); curr; curr = vi_next (curr))
3290 	    {
3291 	      if (ranges_maybe_overlap_p (poly_int64 (curr->offset),
3292 					  curr->size, bitpos, bitmaxsize))
3293 		{
3294 		  cexpr.var = curr->id;
3295 		  results->safe_push (cexpr);
3296 		  if (address_p)
3297 		    break;
3298 		}
3299 	    }
3300 	  /* If we are going to take the address of this field then
3301 	     to be able to compute reachability correctly add at least
3302 	     the last field of the variable.  */
3303 	  if (address_p && results->length () == 0)
3304 	    {
3305 	      curr = get_varinfo (cexpr.var);
3306 	      while (curr->next != 0)
3307 		curr = vi_next (curr);
3308 	      cexpr.var = curr->id;
3309 	      results->safe_push (cexpr);
3310 	    }
3311 	  else if (results->length () == 0)
3312 	    /* Assert that we found *some* field there. The user couldn't be
3313 	       accessing *only* padding.  */
3314 	    /* Still the user could access one past the end of an array
3315 	       embedded in a struct resulting in accessing *only* padding.  */
3316 	    /* Or accessing only padding via type-punning to a type
3317 	       that has a filed just in padding space.  */
3318 	    {
3319 	      cexpr.type = SCALAR;
3320 	      cexpr.var = anything_id;
3321 	      cexpr.offset = 0;
3322 	      results->safe_push (cexpr);
3323 	    }
3324 	}
3325       else if (known_eq (bitmaxsize, 0))
3326 	{
3327 	  if (dump_file && (dump_flags & TDF_DETAILS))
3328 	    fprintf (dump_file, "Access to zero-sized part of variable, "
3329 		     "ignoring\n");
3330 	}
3331       else
3332 	if (dump_file && (dump_flags & TDF_DETAILS))
3333 	  fprintf (dump_file, "Access to past the end of variable, ignoring\n");
3334     }
3335   else if (result.type == DEREF)
3336     {
3337       /* If we do not know exactly where the access goes say so.  Note
3338 	 that only for non-structure accesses we know that we access
3339 	 at most one subfiled of any variable.  */
3340       HOST_WIDE_INT const_bitpos;
3341       if (!bitpos.is_constant (&const_bitpos)
3342 	  || const_bitpos == -1
3343 	  || maybe_ne (bitsize, bitmaxsize)
3344 	  || AGGREGATE_TYPE_P (TREE_TYPE (orig_t))
3345 	  || result.offset == UNKNOWN_OFFSET)
3346 	result.offset = UNKNOWN_OFFSET;
3347       else
3348 	result.offset += const_bitpos;
3349     }
3350   else if (result.type == ADDRESSOF)
3351     {
3352       /* We can end up here for component references on constants like
3353 	 VIEW_CONVERT_EXPR <>({ 0, 1, 2, 3 })[i].  */
3354       result.type = SCALAR;
3355       result.var = anything_id;
3356       result.offset = 0;
3357     }
3358   else
3359     gcc_unreachable ();
3360 }
3361 
3362 
3363 /* Dereference the constraint expression CONS, and return the result.
3364    DEREF (ADDRESSOF) = SCALAR
3365    DEREF (SCALAR) = DEREF
3366    DEREF (DEREF) = (temp = DEREF1; result = DEREF(temp))
3367    This is needed so that we can handle dereferencing DEREF constraints.  */
3368 
3369 static void
do_deref(vec<ce_s> * constraints)3370 do_deref (vec<ce_s> *constraints)
3371 {
3372   struct constraint_expr *c;
3373   unsigned int i = 0;
3374 
3375   FOR_EACH_VEC_ELT (*constraints, i, c)
3376     {
3377       if (c->type == SCALAR)
3378 	c->type = DEREF;
3379       else if (c->type == ADDRESSOF)
3380 	c->type = SCALAR;
3381       else if (c->type == DEREF)
3382 	{
3383 	  struct constraint_expr tmplhs;
3384 	  tmplhs = new_scalar_tmp_constraint_exp ("dereftmp", true);
3385 	  process_constraint (new_constraint (tmplhs, *c));
3386 	  c->var = tmplhs.var;
3387 	}
3388       else
3389 	gcc_unreachable ();
3390     }
3391 }
3392 
3393 /* Given a tree T, return the constraint expression for taking the
3394    address of it.  */
3395 
3396 static void
get_constraint_for_address_of(tree t,vec<ce_s> * results)3397 get_constraint_for_address_of (tree t, vec<ce_s> *results)
3398 {
3399   struct constraint_expr *c;
3400   unsigned int i;
3401 
3402   get_constraint_for_1 (t, results, true, true);
3403 
3404   FOR_EACH_VEC_ELT (*results, i, c)
3405     {
3406       if (c->type == DEREF)
3407 	c->type = SCALAR;
3408       else
3409 	c->type = ADDRESSOF;
3410     }
3411 }
3412 
3413 /* Given a tree T, return the constraint expression for it.  */
3414 
3415 static void
get_constraint_for_1(tree t,vec<ce_s> * results,bool address_p,bool lhs_p)3416 get_constraint_for_1 (tree t, vec<ce_s> *results, bool address_p,
3417 		      bool lhs_p)
3418 {
3419   struct constraint_expr temp;
3420 
3421   /* x = integer is all glommed to a single variable, which doesn't
3422      point to anything by itself.  That is, of course, unless it is an
3423      integer constant being treated as a pointer, in which case, we
3424      will return that this is really the addressof anything.  This
3425      happens below, since it will fall into the default case. The only
3426      case we know something about an integer treated like a pointer is
3427      when it is the NULL pointer, and then we just say it points to
3428      NULL.
3429 
3430      Do not do that if -fno-delete-null-pointer-checks though, because
3431      in that case *NULL does not fail, so it _should_ alias *anything.
3432      It is not worth adding a new option or renaming the existing one,
3433      since this case is relatively obscure.  */
3434   if ((TREE_CODE (t) == INTEGER_CST
3435        && integer_zerop (t))
3436       /* The only valid CONSTRUCTORs in gimple with pointer typed
3437 	 elements are zero-initializer.  But in IPA mode we also
3438 	 process global initializers, so verify at least.  */
3439       || (TREE_CODE (t) == CONSTRUCTOR
3440 	  && CONSTRUCTOR_NELTS (t) == 0))
3441     {
3442       if (flag_delete_null_pointer_checks)
3443 	temp.var = nothing_id;
3444       else
3445 	temp.var = nonlocal_id;
3446       temp.type = ADDRESSOF;
3447       temp.offset = 0;
3448       results->safe_push (temp);
3449       return;
3450     }
3451 
3452   /* String constants are read-only, ideally we'd have a CONST_DECL
3453      for those.  */
3454   if (TREE_CODE (t) == STRING_CST)
3455     {
3456       temp.var = string_id;
3457       temp.type = SCALAR;
3458       temp.offset = 0;
3459       results->safe_push (temp);
3460       return;
3461     }
3462 
3463   switch (TREE_CODE_CLASS (TREE_CODE (t)))
3464     {
3465     case tcc_expression:
3466       {
3467 	switch (TREE_CODE (t))
3468 	  {
3469 	  case ADDR_EXPR:
3470 	    get_constraint_for_address_of (TREE_OPERAND (t, 0), results);
3471 	    return;
3472 	  default:;
3473 	  }
3474 	break;
3475       }
3476     case tcc_reference:
3477       {
3478 	switch (TREE_CODE (t))
3479 	  {
3480 	  case MEM_REF:
3481 	    {
3482 	      struct constraint_expr cs;
3483 	      varinfo_t vi, curr;
3484 	      get_constraint_for_ptr_offset (TREE_OPERAND (t, 0),
3485 					     TREE_OPERAND (t, 1), results);
3486 	      do_deref (results);
3487 
3488 	      /* If we are not taking the address then make sure to process
3489 		 all subvariables we might access.  */
3490 	      if (address_p)
3491 		return;
3492 
3493 	      cs = results->last ();
3494 	      if (cs.type == DEREF
3495 		  && type_can_have_subvars (TREE_TYPE (t)))
3496 		{
3497 		  /* For dereferences this means we have to defer it
3498 		     to solving time.  */
3499 		  results->last ().offset = UNKNOWN_OFFSET;
3500 		  return;
3501 		}
3502 	      if (cs.type != SCALAR)
3503 		return;
3504 
3505 	      vi = get_varinfo (cs.var);
3506 	      curr = vi_next (vi);
3507 	      if (!vi->is_full_var
3508 		  && curr)
3509 		{
3510 		  unsigned HOST_WIDE_INT size;
3511 		  if (tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (t))))
3512 		    size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (t)));
3513 		  else
3514 		    size = -1;
3515 		  for (; curr; curr = vi_next (curr))
3516 		    {
3517 		      if (curr->offset - vi->offset < size)
3518 			{
3519 			  cs.var = curr->id;
3520 			  results->safe_push (cs);
3521 			}
3522 		      else
3523 			break;
3524 		    }
3525 		}
3526 	      return;
3527 	    }
3528 	  case ARRAY_REF:
3529 	  case ARRAY_RANGE_REF:
3530 	  case COMPONENT_REF:
3531 	  case IMAGPART_EXPR:
3532 	  case REALPART_EXPR:
3533 	  case BIT_FIELD_REF:
3534 	    get_constraint_for_component_ref (t, results, address_p, lhs_p);
3535 	    return;
3536 	  case VIEW_CONVERT_EXPR:
3537 	    get_constraint_for_1 (TREE_OPERAND (t, 0), results, address_p,
3538 				  lhs_p);
3539 	    return;
3540 	  /* We are missing handling for TARGET_MEM_REF here.  */
3541 	  default:;
3542 	  }
3543 	break;
3544       }
3545     case tcc_exceptional:
3546       {
3547 	switch (TREE_CODE (t))
3548 	  {
3549 	  case SSA_NAME:
3550 	    {
3551 	      get_constraint_for_ssa_var (t, results, address_p);
3552 	      return;
3553 	    }
3554 	  case CONSTRUCTOR:
3555 	    {
3556 	      unsigned int i;
3557 	      tree val;
3558 	      auto_vec<ce_s> tmp;
3559 	      FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (t), i, val)
3560 		{
3561 		  struct constraint_expr *rhsp;
3562 		  unsigned j;
3563 		  get_constraint_for_1 (val, &tmp, address_p, lhs_p);
3564 		  FOR_EACH_VEC_ELT (tmp, j, rhsp)
3565 		    results->safe_push (*rhsp);
3566 		  tmp.truncate (0);
3567 		}
3568 	      /* We do not know whether the constructor was complete,
3569 	         so technically we have to add &NOTHING or &ANYTHING
3570 		 like we do for an empty constructor as well.  */
3571 	      return;
3572 	    }
3573 	  default:;
3574 	  }
3575 	break;
3576       }
3577     case tcc_declaration:
3578       {
3579 	get_constraint_for_ssa_var (t, results, address_p);
3580 	return;
3581       }
3582     case tcc_constant:
3583       {
3584 	/* We cannot refer to automatic variables through constants.  */
3585 	temp.type = ADDRESSOF;
3586 	temp.var = nonlocal_id;
3587 	temp.offset = 0;
3588 	results->safe_push (temp);
3589 	return;
3590       }
3591     default:;
3592     }
3593 
3594   /* The default fallback is a constraint from anything.  */
3595   temp.type = ADDRESSOF;
3596   temp.var = anything_id;
3597   temp.offset = 0;
3598   results->safe_push (temp);
3599 }
3600 
3601 /* Given a gimple tree T, return the constraint expression vector for it.  */
3602 
3603 static void
get_constraint_for(tree t,vec<ce_s> * results)3604 get_constraint_for (tree t, vec<ce_s> *results)
3605 {
3606   gcc_assert (results->length () == 0);
3607 
3608   get_constraint_for_1 (t, results, false, true);
3609 }
3610 
3611 /* Given a gimple tree T, return the constraint expression vector for it
3612    to be used as the rhs of a constraint.  */
3613 
3614 static void
get_constraint_for_rhs(tree t,vec<ce_s> * results)3615 get_constraint_for_rhs (tree t, vec<ce_s> *results)
3616 {
3617   gcc_assert (results->length () == 0);
3618 
3619   get_constraint_for_1 (t, results, false, false);
3620 }
3621 
3622 
3623 /* Efficiently generates constraints from all entries in *RHSC to all
3624    entries in *LHSC.  */
3625 
3626 static void
process_all_all_constraints(vec<ce_s> lhsc,vec<ce_s> rhsc)3627 process_all_all_constraints (vec<ce_s> lhsc,
3628 			     vec<ce_s> rhsc)
3629 {
3630   struct constraint_expr *lhsp, *rhsp;
3631   unsigned i, j;
3632 
3633   if (lhsc.length () <= 1 || rhsc.length () <= 1)
3634     {
3635       FOR_EACH_VEC_ELT (lhsc, i, lhsp)
3636 	FOR_EACH_VEC_ELT (rhsc, j, rhsp)
3637 	  process_constraint (new_constraint (*lhsp, *rhsp));
3638     }
3639   else
3640     {
3641       struct constraint_expr tmp;
3642       tmp = new_scalar_tmp_constraint_exp ("allalltmp", true);
3643       FOR_EACH_VEC_ELT (rhsc, i, rhsp)
3644 	process_constraint (new_constraint (tmp, *rhsp));
3645       FOR_EACH_VEC_ELT (lhsc, i, lhsp)
3646 	process_constraint (new_constraint (*lhsp, tmp));
3647     }
3648 }
3649 
3650 /* Handle aggregate copies by expanding into copies of the respective
3651    fields of the structures.  */
3652 
3653 static void
do_structure_copy(tree lhsop,tree rhsop)3654 do_structure_copy (tree lhsop, tree rhsop)
3655 {
3656   struct constraint_expr *lhsp, *rhsp;
3657   auto_vec<ce_s> lhsc;
3658   auto_vec<ce_s> rhsc;
3659   unsigned j;
3660 
3661   get_constraint_for (lhsop, &lhsc);
3662   get_constraint_for_rhs (rhsop, &rhsc);
3663   lhsp = &lhsc[0];
3664   rhsp = &rhsc[0];
3665   if (lhsp->type == DEREF
3666       || (lhsp->type == ADDRESSOF && lhsp->var == anything_id)
3667       || rhsp->type == DEREF)
3668     {
3669       if (lhsp->type == DEREF)
3670 	{
3671 	  gcc_assert (lhsc.length () == 1);
3672 	  lhsp->offset = UNKNOWN_OFFSET;
3673 	}
3674       if (rhsp->type == DEREF)
3675 	{
3676 	  gcc_assert (rhsc.length () == 1);
3677 	  rhsp->offset = UNKNOWN_OFFSET;
3678 	}
3679       process_all_all_constraints (lhsc, rhsc);
3680     }
3681   else if (lhsp->type == SCALAR
3682 	   && (rhsp->type == SCALAR
3683 	       || rhsp->type == ADDRESSOF))
3684     {
3685       HOST_WIDE_INT lhssize, lhsoffset;
3686       HOST_WIDE_INT rhssize, rhsoffset;
3687       bool reverse;
3688       unsigned k = 0;
3689       if (!get_ref_base_and_extent_hwi (lhsop, &lhsoffset, &lhssize, &reverse)
3690 	  || !get_ref_base_and_extent_hwi (rhsop, &rhsoffset, &rhssize,
3691 					   &reverse))
3692 	{
3693 	  process_all_all_constraints (lhsc, rhsc);
3694 	  return;
3695 	}
3696       for (j = 0; lhsc.iterate (j, &lhsp);)
3697 	{
3698 	  varinfo_t lhsv, rhsv;
3699 	  rhsp = &rhsc[k];
3700 	  lhsv = get_varinfo (lhsp->var);
3701 	  rhsv = get_varinfo (rhsp->var);
3702 	  if (lhsv->may_have_pointers
3703 	      && (lhsv->is_full_var
3704 		  || rhsv->is_full_var
3705 		  || ranges_overlap_p (lhsv->offset + rhsoffset, lhsv->size,
3706 				       rhsv->offset + lhsoffset, rhsv->size)))
3707 	    process_constraint (new_constraint (*lhsp, *rhsp));
3708 	  if (!rhsv->is_full_var
3709 	      && (lhsv->is_full_var
3710 		  || (lhsv->offset + rhsoffset + lhsv->size
3711 		      > rhsv->offset + lhsoffset + rhsv->size)))
3712 	    {
3713 	      ++k;
3714 	      if (k >= rhsc.length ())
3715 		break;
3716 	    }
3717 	  else
3718 	    ++j;
3719 	}
3720     }
3721   else
3722     gcc_unreachable ();
3723 }
3724 
3725 /* Create constraints ID = { rhsc }.  */
3726 
3727 static void
make_constraints_to(unsigned id,vec<ce_s> rhsc)3728 make_constraints_to (unsigned id, vec<ce_s> rhsc)
3729 {
3730   struct constraint_expr *c;
3731   struct constraint_expr includes;
3732   unsigned int j;
3733 
3734   includes.var = id;
3735   includes.offset = 0;
3736   includes.type = SCALAR;
3737 
3738   FOR_EACH_VEC_ELT (rhsc, j, c)
3739     process_constraint (new_constraint (includes, *c));
3740 }
3741 
3742 /* Create a constraint ID = OP.  */
3743 
3744 static void
make_constraint_to(unsigned id,tree op)3745 make_constraint_to (unsigned id, tree op)
3746 {
3747   auto_vec<ce_s> rhsc;
3748   get_constraint_for_rhs (op, &rhsc);
3749   make_constraints_to (id, rhsc);
3750 }
3751 
3752 /* Create a constraint ID = &FROM.  */
3753 
3754 static void
make_constraint_from(varinfo_t vi,int from)3755 make_constraint_from (varinfo_t vi, int from)
3756 {
3757   struct constraint_expr lhs, rhs;
3758 
3759   lhs.var = vi->id;
3760   lhs.offset = 0;
3761   lhs.type = SCALAR;
3762 
3763   rhs.var = from;
3764   rhs.offset = 0;
3765   rhs.type = ADDRESSOF;
3766   process_constraint (new_constraint (lhs, rhs));
3767 }
3768 
3769 /* Create a constraint ID = FROM.  */
3770 
3771 static void
make_copy_constraint(varinfo_t vi,int from)3772 make_copy_constraint (varinfo_t vi, int from)
3773 {
3774   struct constraint_expr lhs, rhs;
3775 
3776   lhs.var = vi->id;
3777   lhs.offset = 0;
3778   lhs.type = SCALAR;
3779 
3780   rhs.var = from;
3781   rhs.offset = 0;
3782   rhs.type = SCALAR;
3783   process_constraint (new_constraint (lhs, rhs));
3784 }
3785 
3786 /* Make constraints necessary to make OP escape.  */
3787 
3788 static void
make_escape_constraint(tree op)3789 make_escape_constraint (tree op)
3790 {
3791   make_constraint_to (escaped_id, op);
3792 }
3793 
3794 /* Add constraints to that the solution of VI is transitively closed.  */
3795 
3796 static void
make_transitive_closure_constraints(varinfo_t vi)3797 make_transitive_closure_constraints (varinfo_t vi)
3798 {
3799   struct constraint_expr lhs, rhs;
3800 
3801   /* VAR = *(VAR + UNKNOWN);  */
3802   lhs.type = SCALAR;
3803   lhs.var = vi->id;
3804   lhs.offset = 0;
3805   rhs.type = DEREF;
3806   rhs.var = vi->id;
3807   rhs.offset = UNKNOWN_OFFSET;
3808   process_constraint (new_constraint (lhs, rhs));
3809 }
3810 
3811 /* Add constraints to that the solution of VI has all subvariables added.  */
3812 
3813 static void
make_any_offset_constraints(varinfo_t vi)3814 make_any_offset_constraints (varinfo_t vi)
3815 {
3816   struct constraint_expr lhs, rhs;
3817 
3818   /* VAR = VAR + UNKNOWN;  */
3819   lhs.type = SCALAR;
3820   lhs.var = vi->id;
3821   lhs.offset = 0;
3822   rhs.type = SCALAR;
3823   rhs.var = vi->id;
3824   rhs.offset = UNKNOWN_OFFSET;
3825   process_constraint (new_constraint (lhs, rhs));
3826 }
3827 
3828 /* Temporary storage for fake var decls.  */
3829 struct obstack fake_var_decl_obstack;
3830 
3831 /* Build a fake VAR_DECL acting as referrer to a DECL_UID.  */
3832 
3833 static tree
build_fake_var_decl(tree type)3834 build_fake_var_decl (tree type)
3835 {
3836   tree decl = (tree) XOBNEW (&fake_var_decl_obstack, struct tree_var_decl);
3837   memset (decl, 0, sizeof (struct tree_var_decl));
3838   TREE_SET_CODE (decl, VAR_DECL);
3839   TREE_TYPE (decl) = type;
3840   DECL_UID (decl) = allocate_decl_uid ();
3841   SET_DECL_PT_UID (decl, -1);
3842   layout_decl (decl, 0);
3843   return decl;
3844 }
3845 
3846 /* Create a new artificial heap variable with NAME.
3847    Return the created variable.  */
3848 
3849 static varinfo_t
make_heapvar(const char * name,bool add_id)3850 make_heapvar (const char *name, bool add_id)
3851 {
3852   varinfo_t vi;
3853   tree heapvar;
3854 
3855   heapvar = build_fake_var_decl (ptr_type_node);
3856   DECL_EXTERNAL (heapvar) = 1;
3857 
3858   vi = new_var_info (heapvar, name, add_id);
3859   vi->is_artificial_var = true;
3860   vi->is_heap_var = true;
3861   vi->is_unknown_size_var = true;
3862   vi->offset = 0;
3863   vi->fullsize = ~0;
3864   vi->size = ~0;
3865   vi->is_full_var = true;
3866   insert_vi_for_tree (heapvar, vi);
3867 
3868   return vi;
3869 }
3870 
3871 /* Create a new artificial heap variable with NAME and make a
3872    constraint from it to LHS.  Set flags according to a tag used
3873    for tracking restrict pointers.  */
3874 
3875 static varinfo_t
make_constraint_from_restrict(varinfo_t lhs,const char * name,bool add_id)3876 make_constraint_from_restrict (varinfo_t lhs, const char *name, bool add_id)
3877 {
3878   varinfo_t vi = make_heapvar (name, add_id);
3879   vi->is_restrict_var = 1;
3880   vi->is_global_var = 1;
3881   vi->may_have_pointers = 1;
3882   make_constraint_from (lhs, vi->id);
3883   return vi;
3884 }
3885 
3886 /* Create a new artificial heap variable with NAME and make a
3887    constraint from it to LHS.  Set flags according to a tag used
3888    for tracking restrict pointers and make the artificial heap
3889    point to global memory.  */
3890 
3891 static varinfo_t
make_constraint_from_global_restrict(varinfo_t lhs,const char * name,bool add_id)3892 make_constraint_from_global_restrict (varinfo_t lhs, const char *name,
3893 				      bool add_id)
3894 {
3895   varinfo_t vi = make_constraint_from_restrict (lhs, name, add_id);
3896   make_copy_constraint (vi, nonlocal_id);
3897   return vi;
3898 }
3899 
3900 /* In IPA mode there are varinfos for different aspects of reach
3901    function designator.  One for the points-to set of the return
3902    value, one for the variables that are clobbered by the function,
3903    one for its uses and one for each parameter (including a single
3904    glob for remaining variadic arguments).  */
3905 
3906 enum { fi_clobbers = 1, fi_uses = 2,
3907        fi_static_chain = 3, fi_result = 4, fi_parm_base = 5 };
3908 
3909 /* Get a constraint for the requested part of a function designator FI
3910    when operating in IPA mode.  */
3911 
3912 static struct constraint_expr
get_function_part_constraint(varinfo_t fi,unsigned part)3913 get_function_part_constraint (varinfo_t fi, unsigned part)
3914 {
3915   struct constraint_expr c;
3916 
3917   gcc_assert (in_ipa_mode);
3918 
3919   if (fi->id == anything_id)
3920     {
3921       /* ???  We probably should have a ANYFN special variable.  */
3922       c.var = anything_id;
3923       c.offset = 0;
3924       c.type = SCALAR;
3925     }
3926   else if (TREE_CODE (fi->decl) == FUNCTION_DECL)
3927     {
3928       varinfo_t ai = first_vi_for_offset (fi, part);
3929       if (ai)
3930 	c.var = ai->id;
3931       else
3932 	c.var = anything_id;
3933       c.offset = 0;
3934       c.type = SCALAR;
3935     }
3936   else
3937     {
3938       c.var = fi->id;
3939       c.offset = part;
3940       c.type = DEREF;
3941     }
3942 
3943   return c;
3944 }
3945 
3946 /* For non-IPA mode, generate constraints necessary for a call on the
3947    RHS.  */
3948 
3949 static void
handle_rhs_call(gcall * stmt,vec<ce_s> * results)3950 handle_rhs_call (gcall *stmt, vec<ce_s> *results)
3951 {
3952   struct constraint_expr rhsc;
3953   unsigned i;
3954   bool returns_uses = false;
3955 
3956   for (i = 0; i < gimple_call_num_args (stmt); ++i)
3957     {
3958       tree arg = gimple_call_arg (stmt, i);
3959       int flags = gimple_call_arg_flags (stmt, i);
3960 
3961       /* If the argument is not used we can ignore it.  */
3962       if (flags & EAF_UNUSED)
3963 	continue;
3964 
3965       /* As we compute ESCAPED context-insensitive we do not gain
3966          any precision with just EAF_NOCLOBBER but not EAF_NOESCAPE
3967 	 set.  The argument would still get clobbered through the
3968 	 escape solution.  */
3969       if ((flags & EAF_NOCLOBBER)
3970 	   && (flags & EAF_NOESCAPE))
3971 	{
3972 	  varinfo_t uses = get_call_use_vi (stmt);
3973 	  varinfo_t tem = new_var_info (NULL_TREE, "callarg", true);
3974 	  tem->is_reg_var = true;
3975 	  make_constraint_to (tem->id, arg);
3976 	  make_any_offset_constraints (tem);
3977 	  if (!(flags & EAF_DIRECT))
3978 	    make_transitive_closure_constraints (tem);
3979 	  make_copy_constraint (uses, tem->id);
3980 	  returns_uses = true;
3981 	}
3982       else if (flags & EAF_NOESCAPE)
3983 	{
3984 	  struct constraint_expr lhs, rhs;
3985 	  varinfo_t uses = get_call_use_vi (stmt);
3986 	  varinfo_t clobbers = get_call_clobber_vi (stmt);
3987 	  varinfo_t tem = new_var_info (NULL_TREE, "callarg", true);
3988 	  tem->is_reg_var = true;
3989 	  make_constraint_to (tem->id, arg);
3990 	  make_any_offset_constraints (tem);
3991 	  if (!(flags & EAF_DIRECT))
3992 	    make_transitive_closure_constraints (tem);
3993 	  make_copy_constraint (uses, tem->id);
3994 	  make_copy_constraint (clobbers, tem->id);
3995 	  /* Add *tem = nonlocal, do not add *tem = callused as
3996 	     EAF_NOESCAPE parameters do not escape to other parameters
3997 	     and all other uses appear in NONLOCAL as well.  */
3998 	  lhs.type = DEREF;
3999 	  lhs.var = tem->id;
4000 	  lhs.offset = 0;
4001 	  rhs.type = SCALAR;
4002 	  rhs.var = nonlocal_id;
4003 	  rhs.offset = 0;
4004 	  process_constraint (new_constraint (lhs, rhs));
4005 	  returns_uses = true;
4006 	}
4007       else
4008 	make_escape_constraint (arg);
4009     }
4010 
4011   /* If we added to the calls uses solution make sure we account for
4012      pointers to it to be returned.  */
4013   if (returns_uses)
4014     {
4015       rhsc.var = get_call_use_vi (stmt)->id;
4016       rhsc.offset = UNKNOWN_OFFSET;
4017       rhsc.type = SCALAR;
4018       results->safe_push (rhsc);
4019     }
4020 
4021   /* The static chain escapes as well.  */
4022   if (gimple_call_chain (stmt))
4023     make_escape_constraint (gimple_call_chain (stmt));
4024 
4025   /* And if we applied NRV the address of the return slot escapes as well.  */
4026   if (gimple_call_return_slot_opt_p (stmt)
4027       && gimple_call_lhs (stmt) != NULL_TREE
4028       && TREE_ADDRESSABLE (TREE_TYPE (gimple_call_lhs (stmt))))
4029     {
4030       auto_vec<ce_s> tmpc;
4031       struct constraint_expr lhsc, *c;
4032       get_constraint_for_address_of (gimple_call_lhs (stmt), &tmpc);
4033       lhsc.var = escaped_id;
4034       lhsc.offset = 0;
4035       lhsc.type = SCALAR;
4036       FOR_EACH_VEC_ELT (tmpc, i, c)
4037 	process_constraint (new_constraint (lhsc, *c));
4038     }
4039 
4040   /* Regular functions return nonlocal memory.  */
4041   rhsc.var = nonlocal_id;
4042   rhsc.offset = 0;
4043   rhsc.type = SCALAR;
4044   results->safe_push (rhsc);
4045 }
4046 
4047 /* For non-IPA mode, generate constraints necessary for a call
4048    that returns a pointer and assigns it to LHS.  This simply makes
4049    the LHS point to global and escaped variables.  */
4050 
4051 static void
handle_lhs_call(gcall * stmt,tree lhs,int flags,vec<ce_s> rhsc,tree fndecl)4052 handle_lhs_call (gcall *stmt, tree lhs, int flags, vec<ce_s> rhsc,
4053 		 tree fndecl)
4054 {
4055   auto_vec<ce_s> lhsc;
4056 
4057   get_constraint_for (lhs, &lhsc);
4058   /* If the store is to a global decl make sure to
4059      add proper escape constraints.  */
4060   lhs = get_base_address (lhs);
4061   if (lhs
4062       && DECL_P (lhs)
4063       && is_global_var (lhs))
4064     {
4065       struct constraint_expr tmpc;
4066       tmpc.var = escaped_id;
4067       tmpc.offset = 0;
4068       tmpc.type = SCALAR;
4069       lhsc.safe_push (tmpc);
4070     }
4071 
4072   /* If the call returns an argument unmodified override the rhs
4073      constraints.  */
4074   if (flags & ERF_RETURNS_ARG
4075       && (flags & ERF_RETURN_ARG_MASK) < gimple_call_num_args (stmt))
4076     {
4077       tree arg;
4078       rhsc.create (0);
4079       arg = gimple_call_arg (stmt, flags & ERF_RETURN_ARG_MASK);
4080       get_constraint_for (arg, &rhsc);
4081       process_all_all_constraints (lhsc, rhsc);
4082       rhsc.release ();
4083     }
4084   else if (flags & ERF_NOALIAS)
4085     {
4086       varinfo_t vi;
4087       struct constraint_expr tmpc;
4088       rhsc.create (0);
4089       vi = make_heapvar ("HEAP", true);
4090       /* We are marking allocated storage local, we deal with it becoming
4091          global by escaping and setting of vars_contains_escaped_heap.  */
4092       DECL_EXTERNAL (vi->decl) = 0;
4093       vi->is_global_var = 0;
4094       /* If this is not a real malloc call assume the memory was
4095 	 initialized and thus may point to global memory.  All
4096 	 builtin functions with the malloc attribute behave in a sane way.  */
4097       if (!fndecl
4098 	  || DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL)
4099 	make_constraint_from (vi, nonlocal_id);
4100       tmpc.var = vi->id;
4101       tmpc.offset = 0;
4102       tmpc.type = ADDRESSOF;
4103       rhsc.safe_push (tmpc);
4104       process_all_all_constraints (lhsc, rhsc);
4105       rhsc.release ();
4106     }
4107   else
4108     process_all_all_constraints (lhsc, rhsc);
4109 }
4110 
4111 /* For non-IPA mode, generate constraints necessary for a call of a
4112    const function that returns a pointer in the statement STMT.  */
4113 
4114 static void
handle_const_call(gcall * stmt,vec<ce_s> * results)4115 handle_const_call (gcall *stmt, vec<ce_s> *results)
4116 {
4117   struct constraint_expr rhsc;
4118   unsigned int k;
4119   bool need_uses = false;
4120 
4121   /* Treat nested const functions the same as pure functions as far
4122      as the static chain is concerned.  */
4123   if (gimple_call_chain (stmt))
4124     {
4125       varinfo_t uses = get_call_use_vi (stmt);
4126       make_constraint_to (uses->id, gimple_call_chain (stmt));
4127       need_uses = true;
4128     }
4129 
4130   /* And if we applied NRV the address of the return slot escapes as well.  */
4131   if (gimple_call_return_slot_opt_p (stmt)
4132       && gimple_call_lhs (stmt) != NULL_TREE
4133       && TREE_ADDRESSABLE (TREE_TYPE (gimple_call_lhs (stmt))))
4134     {
4135       varinfo_t uses = get_call_use_vi (stmt);
4136       auto_vec<ce_s> tmpc;
4137       get_constraint_for_address_of (gimple_call_lhs (stmt), &tmpc);
4138       make_constraints_to (uses->id, tmpc);
4139       need_uses = true;
4140     }
4141 
4142   if (need_uses)
4143     {
4144       varinfo_t uses = get_call_use_vi (stmt);
4145       make_any_offset_constraints (uses);
4146       make_transitive_closure_constraints (uses);
4147       rhsc.var = uses->id;
4148       rhsc.offset = 0;
4149       rhsc.type = SCALAR;
4150       results->safe_push (rhsc);
4151     }
4152 
4153   /* May return offsetted arguments.  */
4154   varinfo_t tem = NULL;
4155   if (gimple_call_num_args (stmt) != 0)
4156     {
4157       tem = new_var_info (NULL_TREE, "callarg", true);
4158       tem->is_reg_var = true;
4159     }
4160   for (k = 0; k < gimple_call_num_args (stmt); ++k)
4161     {
4162       tree arg = gimple_call_arg (stmt, k);
4163       auto_vec<ce_s> argc;
4164       get_constraint_for_rhs (arg, &argc);
4165       make_constraints_to (tem->id, argc);
4166     }
4167   if (tem)
4168     {
4169       ce_s ce;
4170       ce.type = SCALAR;
4171       ce.var = tem->id;
4172       ce.offset = UNKNOWN_OFFSET;
4173       results->safe_push (ce);
4174     }
4175 
4176   /* May return addresses of globals.  */
4177   rhsc.var = nonlocal_id;
4178   rhsc.offset = 0;
4179   rhsc.type = ADDRESSOF;
4180   results->safe_push (rhsc);
4181 }
4182 
4183 /* For non-IPA mode, generate constraints necessary for a call to a
4184    pure function in statement STMT.  */
4185 
4186 static void
handle_pure_call(gcall * stmt,vec<ce_s> * results)4187 handle_pure_call (gcall *stmt, vec<ce_s> *results)
4188 {
4189   struct constraint_expr rhsc;
4190   unsigned i;
4191   varinfo_t uses = NULL;
4192 
4193   /* Memory reached from pointer arguments is call-used.  */
4194   for (i = 0; i < gimple_call_num_args (stmt); ++i)
4195     {
4196       tree arg = gimple_call_arg (stmt, i);
4197       if (!uses)
4198 	{
4199 	  uses = get_call_use_vi (stmt);
4200 	  make_any_offset_constraints (uses);
4201 	  make_transitive_closure_constraints (uses);
4202 	}
4203       make_constraint_to (uses->id, arg);
4204     }
4205 
4206   /* The static chain is used as well.  */
4207   if (gimple_call_chain (stmt))
4208     {
4209       if (!uses)
4210 	{
4211 	  uses = get_call_use_vi (stmt);
4212 	  make_any_offset_constraints (uses);
4213 	  make_transitive_closure_constraints (uses);
4214 	}
4215       make_constraint_to (uses->id, gimple_call_chain (stmt));
4216     }
4217 
4218   /* And if we applied NRV the address of the return slot.  */
4219   if (gimple_call_return_slot_opt_p (stmt)
4220       && gimple_call_lhs (stmt) != NULL_TREE
4221       && TREE_ADDRESSABLE (TREE_TYPE (gimple_call_lhs (stmt))))
4222     {
4223       if (!uses)
4224 	{
4225 	  uses = get_call_use_vi (stmt);
4226 	  make_any_offset_constraints (uses);
4227 	  make_transitive_closure_constraints (uses);
4228 	}
4229       auto_vec<ce_s> tmpc;
4230       get_constraint_for_address_of (gimple_call_lhs (stmt), &tmpc);
4231       make_constraints_to (uses->id, tmpc);
4232     }
4233 
4234   /* Pure functions may return call-used and nonlocal memory.  */
4235   if (uses)
4236     {
4237       rhsc.var = uses->id;
4238       rhsc.offset = 0;
4239       rhsc.type = SCALAR;
4240       results->safe_push (rhsc);
4241     }
4242   rhsc.var = nonlocal_id;
4243   rhsc.offset = 0;
4244   rhsc.type = SCALAR;
4245   results->safe_push (rhsc);
4246 }
4247 
4248 
4249 /* Return the varinfo for the callee of CALL.  */
4250 
4251 static varinfo_t
get_fi_for_callee(gcall * call)4252 get_fi_for_callee (gcall *call)
4253 {
4254   tree decl, fn = gimple_call_fn (call);
4255 
4256   if (fn && TREE_CODE (fn) == OBJ_TYPE_REF)
4257     fn = OBJ_TYPE_REF_EXPR (fn);
4258 
4259   /* If we can directly resolve the function being called, do so.
4260      Otherwise, it must be some sort of indirect expression that
4261      we should still be able to handle.  */
4262   decl = gimple_call_addr_fndecl (fn);
4263   if (decl)
4264     return get_vi_for_tree (decl);
4265 
4266   /* If the function is anything other than a SSA name pointer we have no
4267      clue and should be getting ANYFN (well, ANYTHING for now).  */
4268   if (!fn || TREE_CODE (fn) != SSA_NAME)
4269     return get_varinfo (anything_id);
4270 
4271   if (SSA_NAME_IS_DEFAULT_DEF (fn)
4272       && (TREE_CODE (SSA_NAME_VAR (fn)) == PARM_DECL
4273 	  || TREE_CODE (SSA_NAME_VAR (fn)) == RESULT_DECL))
4274     fn = SSA_NAME_VAR (fn);
4275 
4276   return get_vi_for_tree (fn);
4277 }
4278 
4279 /* Create constraints for assigning call argument ARG to the incoming parameter
4280    INDEX of function FI.  */
4281 
4282 static void
find_func_aliases_for_call_arg(varinfo_t fi,unsigned index,tree arg)4283 find_func_aliases_for_call_arg (varinfo_t fi, unsigned index, tree arg)
4284 {
4285   struct constraint_expr lhs;
4286   lhs = get_function_part_constraint (fi, fi_parm_base + index);
4287 
4288   auto_vec<ce_s, 2> rhsc;
4289   get_constraint_for_rhs (arg, &rhsc);
4290 
4291   unsigned j;
4292   struct constraint_expr *rhsp;
4293   FOR_EACH_VEC_ELT (rhsc, j, rhsp)
4294     process_constraint (new_constraint (lhs, *rhsp));
4295 }
4296 
4297 /* Return true if FNDECL may be part of another lto partition.  */
4298 
4299 static bool
fndecl_maybe_in_other_partition(tree fndecl)4300 fndecl_maybe_in_other_partition (tree fndecl)
4301 {
4302   cgraph_node *fn_node = cgraph_node::get (fndecl);
4303   if (fn_node == NULL)
4304     return true;
4305 
4306   return fn_node->in_other_partition;
4307 }
4308 
4309 /* Create constraints for the builtin call T.  Return true if the call
4310    was handled, otherwise false.  */
4311 
4312 static bool
find_func_aliases_for_builtin_call(struct function * fn,gcall * t)4313 find_func_aliases_for_builtin_call (struct function *fn, gcall *t)
4314 {
4315   tree fndecl = gimple_call_fndecl (t);
4316   auto_vec<ce_s, 2> lhsc;
4317   auto_vec<ce_s, 4> rhsc;
4318   varinfo_t fi;
4319 
4320   if (gimple_call_builtin_p (t, BUILT_IN_NORMAL))
4321     /* ???  All builtins that are handled here need to be handled
4322        in the alias-oracle query functions explicitly!  */
4323     switch (DECL_FUNCTION_CODE (fndecl))
4324       {
4325       /* All the following functions return a pointer to the same object
4326 	 as their first argument points to.  The functions do not add
4327 	 to the ESCAPED solution.  The functions make the first argument
4328 	 pointed to memory point to what the second argument pointed to
4329 	 memory points to.  */
4330       case BUILT_IN_STRCPY:
4331       case BUILT_IN_STRNCPY:
4332       case BUILT_IN_BCOPY:
4333       case BUILT_IN_MEMCPY:
4334       case BUILT_IN_MEMMOVE:
4335       case BUILT_IN_MEMPCPY:
4336       case BUILT_IN_STPCPY:
4337       case BUILT_IN_STPNCPY:
4338       case BUILT_IN_STRCAT:
4339       case BUILT_IN_STRNCAT:
4340       case BUILT_IN_STRCPY_CHK:
4341       case BUILT_IN_STRNCPY_CHK:
4342       case BUILT_IN_MEMCPY_CHK:
4343       case BUILT_IN_MEMMOVE_CHK:
4344       case BUILT_IN_MEMPCPY_CHK:
4345       case BUILT_IN_STPCPY_CHK:
4346       case BUILT_IN_STPNCPY_CHK:
4347       case BUILT_IN_STRCAT_CHK:
4348       case BUILT_IN_STRNCAT_CHK:
4349       case BUILT_IN_TM_MEMCPY:
4350       case BUILT_IN_TM_MEMMOVE:
4351 	{
4352 	  tree res = gimple_call_lhs (t);
4353 	  tree dest = gimple_call_arg (t, (DECL_FUNCTION_CODE (fndecl)
4354 					   == BUILT_IN_BCOPY ? 1 : 0));
4355 	  tree src = gimple_call_arg (t, (DECL_FUNCTION_CODE (fndecl)
4356 					  == BUILT_IN_BCOPY ? 0 : 1));
4357 	  if (res != NULL_TREE)
4358 	    {
4359 	      get_constraint_for (res, &lhsc);
4360 	      if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_MEMPCPY
4361 		  || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPCPY
4362 		  || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPNCPY
4363 		  || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_MEMPCPY_CHK
4364 		  || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPCPY_CHK
4365 		  || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPNCPY_CHK)
4366 		get_constraint_for_ptr_offset (dest, NULL_TREE, &rhsc);
4367 	      else
4368 		get_constraint_for (dest, &rhsc);
4369 	      process_all_all_constraints (lhsc, rhsc);
4370 	      lhsc.truncate (0);
4371 	      rhsc.truncate (0);
4372 	    }
4373 	  get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
4374 	  get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
4375 	  do_deref (&lhsc);
4376 	  do_deref (&rhsc);
4377 	  process_all_all_constraints (lhsc, rhsc);
4378 	  return true;
4379 	}
4380       case BUILT_IN_MEMSET:
4381       case BUILT_IN_MEMSET_CHK:
4382       case BUILT_IN_TM_MEMSET:
4383 	{
4384 	  tree res = gimple_call_lhs (t);
4385 	  tree dest = gimple_call_arg (t, 0);
4386 	  unsigned i;
4387 	  ce_s *lhsp;
4388 	  struct constraint_expr ac;
4389 	  if (res != NULL_TREE)
4390 	    {
4391 	      get_constraint_for (res, &lhsc);
4392 	      get_constraint_for (dest, &rhsc);
4393 	      process_all_all_constraints (lhsc, rhsc);
4394 	      lhsc.truncate (0);
4395 	    }
4396 	  get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
4397 	  do_deref (&lhsc);
4398 	  if (flag_delete_null_pointer_checks
4399 	      && integer_zerop (gimple_call_arg (t, 1)))
4400 	    {
4401 	      ac.type = ADDRESSOF;
4402 	      ac.var = nothing_id;
4403 	    }
4404 	  else
4405 	    {
4406 	      ac.type = SCALAR;
4407 	      ac.var = integer_id;
4408 	    }
4409 	  ac.offset = 0;
4410 	  FOR_EACH_VEC_ELT (lhsc, i, lhsp)
4411 	      process_constraint (new_constraint (*lhsp, ac));
4412 	  return true;
4413 	}
4414       case BUILT_IN_POSIX_MEMALIGN:
4415         {
4416 	  tree ptrptr = gimple_call_arg (t, 0);
4417 	  get_constraint_for (ptrptr, &lhsc);
4418 	  do_deref (&lhsc);
4419 	  varinfo_t vi = make_heapvar ("HEAP", true);
4420 	  /* We are marking allocated storage local, we deal with it becoming
4421 	     global by escaping and setting of vars_contains_escaped_heap.  */
4422 	  DECL_EXTERNAL (vi->decl) = 0;
4423 	  vi->is_global_var = 0;
4424 	  struct constraint_expr tmpc;
4425 	  tmpc.var = vi->id;
4426 	  tmpc.offset = 0;
4427 	  tmpc.type = ADDRESSOF;
4428 	  rhsc.safe_push (tmpc);
4429 	  process_all_all_constraints (lhsc, rhsc);
4430 	  return true;
4431 	}
4432       case BUILT_IN_ASSUME_ALIGNED:
4433 	{
4434 	  tree res = gimple_call_lhs (t);
4435 	  tree dest = gimple_call_arg (t, 0);
4436 	  if (res != NULL_TREE)
4437 	    {
4438 	      get_constraint_for (res, &lhsc);
4439 	      get_constraint_for (dest, &rhsc);
4440 	      process_all_all_constraints (lhsc, rhsc);
4441 	    }
4442 	  return true;
4443 	}
4444       /* All the following functions do not return pointers, do not
4445 	 modify the points-to sets of memory reachable from their
4446 	 arguments and do not add to the ESCAPED solution.  */
4447       case BUILT_IN_SINCOS:
4448       case BUILT_IN_SINCOSF:
4449       case BUILT_IN_SINCOSL:
4450       case BUILT_IN_FREXP:
4451       case BUILT_IN_FREXPF:
4452       case BUILT_IN_FREXPL:
4453       case BUILT_IN_GAMMA_R:
4454       case BUILT_IN_GAMMAF_R:
4455       case BUILT_IN_GAMMAL_R:
4456       case BUILT_IN_LGAMMA_R:
4457       case BUILT_IN_LGAMMAF_R:
4458       case BUILT_IN_LGAMMAL_R:
4459       case BUILT_IN_MODF:
4460       case BUILT_IN_MODFF:
4461       case BUILT_IN_MODFL:
4462       case BUILT_IN_REMQUO:
4463       case BUILT_IN_REMQUOF:
4464       case BUILT_IN_REMQUOL:
4465       case BUILT_IN_FREE:
4466 	return true;
4467       case BUILT_IN_STRDUP:
4468       case BUILT_IN_STRNDUP:
4469       case BUILT_IN_REALLOC:
4470 	if (gimple_call_lhs (t))
4471 	  {
4472 	    handle_lhs_call (t, gimple_call_lhs (t),
4473 			     gimple_call_return_flags (t) | ERF_NOALIAS,
4474 			     vNULL, fndecl);
4475 	    get_constraint_for_ptr_offset (gimple_call_lhs (t),
4476 					   NULL_TREE, &lhsc);
4477 	    get_constraint_for_ptr_offset (gimple_call_arg (t, 0),
4478 					   NULL_TREE, &rhsc);
4479 	    do_deref (&lhsc);
4480 	    do_deref (&rhsc);
4481 	    process_all_all_constraints (lhsc, rhsc);
4482 	    lhsc.truncate (0);
4483 	    rhsc.truncate (0);
4484 	    /* For realloc the resulting pointer can be equal to the
4485 	       argument as well.  But only doing this wouldn't be
4486 	       correct because with ptr == 0 realloc behaves like malloc.  */
4487 	    if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_REALLOC)
4488 	      {
4489 		get_constraint_for (gimple_call_lhs (t), &lhsc);
4490 		get_constraint_for (gimple_call_arg (t, 0), &rhsc);
4491 		process_all_all_constraints (lhsc, rhsc);
4492 	      }
4493 	    return true;
4494 	  }
4495 	break;
4496       /* String / character search functions return a pointer into the
4497          source string or NULL.  */
4498       case BUILT_IN_INDEX:
4499       case BUILT_IN_STRCHR:
4500       case BUILT_IN_STRRCHR:
4501       case BUILT_IN_MEMCHR:
4502       case BUILT_IN_STRSTR:
4503       case BUILT_IN_STRPBRK:
4504 	if (gimple_call_lhs (t))
4505 	  {
4506 	    tree src = gimple_call_arg (t, 0);
4507 	    get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
4508 	    constraint_expr nul;
4509 	    nul.var = nothing_id;
4510 	    nul.offset = 0;
4511 	    nul.type = ADDRESSOF;
4512 	    rhsc.safe_push (nul);
4513 	    get_constraint_for (gimple_call_lhs (t), &lhsc);
4514 	    process_all_all_constraints (lhsc, rhsc);
4515 	  }
4516 	return true;
4517       /* Pure functions that return something not based on any object and
4518          that use the memory pointed to by their arguments (but not
4519 	 transitively).  */
4520       case BUILT_IN_STRCMP:
4521       case BUILT_IN_STRNCMP:
4522       case BUILT_IN_STRCASECMP:
4523       case BUILT_IN_STRNCASECMP:
4524       case BUILT_IN_MEMCMP:
4525       case BUILT_IN_BCMP:
4526       case BUILT_IN_STRSPN:
4527       case BUILT_IN_STRCSPN:
4528 	{
4529 	  varinfo_t uses = get_call_use_vi (t);
4530 	  make_any_offset_constraints (uses);
4531 	  make_constraint_to (uses->id, gimple_call_arg (t, 0));
4532 	  make_constraint_to (uses->id, gimple_call_arg (t, 1));
4533 	  /* No constraints are necessary for the return value.  */
4534 	  return true;
4535 	}
4536       case BUILT_IN_STRLEN:
4537 	{
4538 	  varinfo_t uses = get_call_use_vi (t);
4539 	  make_any_offset_constraints (uses);
4540 	  make_constraint_to (uses->id, gimple_call_arg (t, 0));
4541 	  /* No constraints are necessary for the return value.  */
4542 	  return true;
4543 	}
4544       case BUILT_IN_OBJECT_SIZE:
4545       case BUILT_IN_CONSTANT_P:
4546 	{
4547 	  /* No constraints are necessary for the return value or the
4548 	     arguments.  */
4549 	  return true;
4550 	}
4551       /* Trampolines are special - they set up passing the static
4552 	 frame.  */
4553       case BUILT_IN_INIT_TRAMPOLINE:
4554 	{
4555 	  tree tramp = gimple_call_arg (t, 0);
4556 	  tree nfunc = gimple_call_arg (t, 1);
4557 	  tree frame = gimple_call_arg (t, 2);
4558 	  unsigned i;
4559 	  struct constraint_expr lhs, *rhsp;
4560 	  if (in_ipa_mode)
4561 	    {
4562 	      varinfo_t nfi = NULL;
4563 	      gcc_assert (TREE_CODE (nfunc) == ADDR_EXPR);
4564 	      nfi = lookup_vi_for_tree (TREE_OPERAND (nfunc, 0));
4565 	      if (nfi)
4566 		{
4567 		  lhs = get_function_part_constraint (nfi, fi_static_chain);
4568 		  get_constraint_for (frame, &rhsc);
4569 		  FOR_EACH_VEC_ELT (rhsc, i, rhsp)
4570 		    process_constraint (new_constraint (lhs, *rhsp));
4571 		  rhsc.truncate (0);
4572 
4573 		  /* Make the frame point to the function for
4574 		     the trampoline adjustment call.  */
4575 		  get_constraint_for (tramp, &lhsc);
4576 		  do_deref (&lhsc);
4577 		  get_constraint_for (nfunc, &rhsc);
4578 		  process_all_all_constraints (lhsc, rhsc);
4579 
4580 		  return true;
4581 		}
4582 	    }
4583 	  /* Else fallthru to generic handling which will let
4584 	     the frame escape.  */
4585 	  break;
4586 	}
4587       case BUILT_IN_ADJUST_TRAMPOLINE:
4588 	{
4589 	  tree tramp = gimple_call_arg (t, 0);
4590 	  tree res = gimple_call_lhs (t);
4591 	  if (in_ipa_mode && res)
4592 	    {
4593 	      get_constraint_for (res, &lhsc);
4594 	      get_constraint_for (tramp, &rhsc);
4595 	      do_deref (&rhsc);
4596 	      process_all_all_constraints (lhsc, rhsc);
4597 	    }
4598 	  return true;
4599 	}
4600       CASE_BUILT_IN_TM_STORE (1):
4601       CASE_BUILT_IN_TM_STORE (2):
4602       CASE_BUILT_IN_TM_STORE (4):
4603       CASE_BUILT_IN_TM_STORE (8):
4604       CASE_BUILT_IN_TM_STORE (FLOAT):
4605       CASE_BUILT_IN_TM_STORE (DOUBLE):
4606       CASE_BUILT_IN_TM_STORE (LDOUBLE):
4607       CASE_BUILT_IN_TM_STORE (M64):
4608       CASE_BUILT_IN_TM_STORE (M128):
4609       CASE_BUILT_IN_TM_STORE (M256):
4610 	{
4611 	  tree addr = gimple_call_arg (t, 0);
4612 	  tree src = gimple_call_arg (t, 1);
4613 
4614 	  get_constraint_for (addr, &lhsc);
4615 	  do_deref (&lhsc);
4616 	  get_constraint_for (src, &rhsc);
4617 	  process_all_all_constraints (lhsc, rhsc);
4618 	  return true;
4619 	}
4620       CASE_BUILT_IN_TM_LOAD (1):
4621       CASE_BUILT_IN_TM_LOAD (2):
4622       CASE_BUILT_IN_TM_LOAD (4):
4623       CASE_BUILT_IN_TM_LOAD (8):
4624       CASE_BUILT_IN_TM_LOAD (FLOAT):
4625       CASE_BUILT_IN_TM_LOAD (DOUBLE):
4626       CASE_BUILT_IN_TM_LOAD (LDOUBLE):
4627       CASE_BUILT_IN_TM_LOAD (M64):
4628       CASE_BUILT_IN_TM_LOAD (M128):
4629       CASE_BUILT_IN_TM_LOAD (M256):
4630 	{
4631 	  tree dest = gimple_call_lhs (t);
4632 	  tree addr = gimple_call_arg (t, 0);
4633 
4634 	  get_constraint_for (dest, &lhsc);
4635 	  get_constraint_for (addr, &rhsc);
4636 	  do_deref (&rhsc);
4637 	  process_all_all_constraints (lhsc, rhsc);
4638 	  return true;
4639 	}
4640       /* Variadic argument handling needs to be handled in IPA
4641 	 mode as well.  */
4642       case BUILT_IN_VA_START:
4643 	{
4644 	  tree valist = gimple_call_arg (t, 0);
4645 	  struct constraint_expr rhs, *lhsp;
4646 	  unsigned i;
4647 	  get_constraint_for_ptr_offset (valist, NULL_TREE, &lhsc);
4648 	  do_deref (&lhsc);
4649 	  /* The va_list gets access to pointers in variadic
4650 	     arguments.  Which we know in the case of IPA analysis
4651 	     and otherwise are just all nonlocal variables.  */
4652 	  if (in_ipa_mode)
4653 	    {
4654 	      fi = lookup_vi_for_tree (fn->decl);
4655 	      rhs = get_function_part_constraint (fi, ~0);
4656 	      rhs.type = ADDRESSOF;
4657 	    }
4658 	  else
4659 	    {
4660 	      rhs.var = nonlocal_id;
4661 	      rhs.type = ADDRESSOF;
4662 	      rhs.offset = 0;
4663 	    }
4664 	  FOR_EACH_VEC_ELT (lhsc, i, lhsp)
4665 	    process_constraint (new_constraint (*lhsp, rhs));
4666 	  /* va_list is clobbered.  */
4667 	  make_constraint_to (get_call_clobber_vi (t)->id, valist);
4668 	  return true;
4669 	}
4670       /* va_end doesn't have any effect that matters.  */
4671       case BUILT_IN_VA_END:
4672 	return true;
4673       /* Alternate return.  Simply give up for now.  */
4674       case BUILT_IN_RETURN:
4675 	{
4676 	  fi = NULL;
4677 	  if (!in_ipa_mode
4678 	      || !(fi = get_vi_for_tree (fn->decl)))
4679 	    make_constraint_from (get_varinfo (escaped_id), anything_id);
4680 	  else if (in_ipa_mode
4681 		   && fi != NULL)
4682 	    {
4683 	      struct constraint_expr lhs, rhs;
4684 	      lhs = get_function_part_constraint (fi, fi_result);
4685 	      rhs.var = anything_id;
4686 	      rhs.offset = 0;
4687 	      rhs.type = SCALAR;
4688 	      process_constraint (new_constraint (lhs, rhs));
4689 	    }
4690 	  return true;
4691 	}
4692       case BUILT_IN_GOMP_PARALLEL:
4693       case BUILT_IN_GOACC_PARALLEL:
4694 	{
4695 	  if (in_ipa_mode)
4696 	    {
4697 	      unsigned int fnpos, argpos;
4698 	      switch (DECL_FUNCTION_CODE (fndecl))
4699 		{
4700 		case BUILT_IN_GOMP_PARALLEL:
4701 		  /* __builtin_GOMP_parallel (fn, data, num_threads, flags).  */
4702 		  fnpos = 0;
4703 		  argpos = 1;
4704 		  break;
4705 		case BUILT_IN_GOACC_PARALLEL:
4706 		  /* __builtin_GOACC_parallel (device, fn, mapnum, hostaddrs,
4707 					       sizes, kinds, ...).  */
4708 		  fnpos = 1;
4709 		  argpos = 3;
4710 		  break;
4711 		default:
4712 		  gcc_unreachable ();
4713 		}
4714 
4715 	      tree fnarg = gimple_call_arg (t, fnpos);
4716 	      gcc_assert (TREE_CODE (fnarg) == ADDR_EXPR);
4717 	      tree fndecl = TREE_OPERAND (fnarg, 0);
4718 	      if (fndecl_maybe_in_other_partition (fndecl))
4719 		/* Fallthru to general call handling.  */
4720 		break;
4721 
4722 	      tree arg = gimple_call_arg (t, argpos);
4723 
4724 	      varinfo_t fi = get_vi_for_tree (fndecl);
4725 	      find_func_aliases_for_call_arg (fi, 0, arg);
4726 	      return true;
4727 	    }
4728 	  /* Else fallthru to generic call handling.  */
4729 	  break;
4730 	}
4731       /* printf-style functions may have hooks to set pointers to
4732 	 point to somewhere into the generated string.  Leave them
4733 	 for a later exercise...  */
4734       default:
4735 	/* Fallthru to general call handling.  */;
4736       }
4737 
4738   return false;
4739 }
4740 
4741 /* Create constraints for the call T.  */
4742 
4743 static void
find_func_aliases_for_call(struct function * fn,gcall * t)4744 find_func_aliases_for_call (struct function *fn, gcall *t)
4745 {
4746   tree fndecl = gimple_call_fndecl (t);
4747   varinfo_t fi;
4748 
4749   if (fndecl != NULL_TREE
4750       && DECL_BUILT_IN (fndecl)
4751       && find_func_aliases_for_builtin_call (fn, t))
4752     return;
4753 
4754   fi = get_fi_for_callee (t);
4755   if (!in_ipa_mode
4756       || (fndecl && !fi->is_fn_info))
4757     {
4758       auto_vec<ce_s, 16> rhsc;
4759       int flags = gimple_call_flags (t);
4760 
4761       /* Const functions can return their arguments and addresses
4762 	 of global memory but not of escaped memory.  */
4763       if (flags & (ECF_CONST|ECF_NOVOPS))
4764 	{
4765 	  if (gimple_call_lhs (t))
4766 	    handle_const_call (t, &rhsc);
4767 	}
4768       /* Pure functions can return addresses in and of memory
4769 	 reachable from their arguments, but they are not an escape
4770 	 point for reachable memory of their arguments.  */
4771       else if (flags & (ECF_PURE|ECF_LOOPING_CONST_OR_PURE))
4772 	handle_pure_call (t, &rhsc);
4773       else
4774 	handle_rhs_call (t, &rhsc);
4775       if (gimple_call_lhs (t))
4776 	handle_lhs_call (t, gimple_call_lhs (t),
4777 			 gimple_call_return_flags (t), rhsc, fndecl);
4778     }
4779   else
4780     {
4781       auto_vec<ce_s, 2> rhsc;
4782       tree lhsop;
4783       unsigned j;
4784 
4785       /* Assign all the passed arguments to the appropriate incoming
4786 	 parameters of the function.  */
4787       for (j = 0; j < gimple_call_num_args (t); j++)
4788 	{
4789 	  tree arg = gimple_call_arg (t, j);
4790 	  find_func_aliases_for_call_arg (fi, j, arg);
4791 	}
4792 
4793       /* If we are returning a value, assign it to the result.  */
4794       lhsop = gimple_call_lhs (t);
4795       if (lhsop)
4796 	{
4797 	  auto_vec<ce_s, 2> lhsc;
4798 	  struct constraint_expr rhs;
4799 	  struct constraint_expr *lhsp;
4800 	  bool aggr_p = aggregate_value_p (lhsop, gimple_call_fntype (t));
4801 
4802 	  get_constraint_for (lhsop, &lhsc);
4803 	  rhs = get_function_part_constraint (fi, fi_result);
4804 	  if (aggr_p)
4805 	    {
4806 	      auto_vec<ce_s, 2> tem;
4807 	      tem.quick_push (rhs);
4808 	      do_deref (&tem);
4809 	      gcc_checking_assert (tem.length () == 1);
4810 	      rhs = tem[0];
4811 	    }
4812 	  FOR_EACH_VEC_ELT (lhsc, j, lhsp)
4813 	    process_constraint (new_constraint (*lhsp, rhs));
4814 
4815 	  /* If we pass the result decl by reference, honor that.  */
4816 	  if (aggr_p)
4817 	    {
4818 	      struct constraint_expr lhs;
4819 	      struct constraint_expr *rhsp;
4820 
4821 	      get_constraint_for_address_of (lhsop, &rhsc);
4822 	      lhs = get_function_part_constraint (fi, fi_result);
4823 	      FOR_EACH_VEC_ELT (rhsc, j, rhsp)
4824 		  process_constraint (new_constraint (lhs, *rhsp));
4825 	      rhsc.truncate (0);
4826 	    }
4827 	}
4828 
4829       /* If we use a static chain, pass it along.  */
4830       if (gimple_call_chain (t))
4831 	{
4832 	  struct constraint_expr lhs;
4833 	  struct constraint_expr *rhsp;
4834 
4835 	  get_constraint_for (gimple_call_chain (t), &rhsc);
4836 	  lhs = get_function_part_constraint (fi, fi_static_chain);
4837 	  FOR_EACH_VEC_ELT (rhsc, j, rhsp)
4838 	    process_constraint (new_constraint (lhs, *rhsp));
4839 	}
4840     }
4841 }
4842 
4843 /* Walk statement T setting up aliasing constraints according to the
4844    references found in T.  This function is the main part of the
4845    constraint builder.  AI points to auxiliary alias information used
4846    when building alias sets and computing alias grouping heuristics.  */
4847 
4848 static void
find_func_aliases(struct function * fn,gimple * origt)4849 find_func_aliases (struct function *fn, gimple *origt)
4850 {
4851   gimple *t = origt;
4852   auto_vec<ce_s, 16> lhsc;
4853   auto_vec<ce_s, 16> rhsc;
4854   struct constraint_expr *c;
4855   varinfo_t fi;
4856 
4857   /* Now build constraints expressions.  */
4858   if (gimple_code (t) == GIMPLE_PHI)
4859     {
4860       size_t i;
4861       unsigned int j;
4862 
4863       /* For a phi node, assign all the arguments to
4864 	 the result.  */
4865       get_constraint_for (gimple_phi_result (t), &lhsc);
4866       for (i = 0; i < gimple_phi_num_args (t); i++)
4867 	{
4868 	  tree strippedrhs = PHI_ARG_DEF (t, i);
4869 
4870 	  STRIP_NOPS (strippedrhs);
4871 	  get_constraint_for_rhs (gimple_phi_arg_def (t, i), &rhsc);
4872 
4873 	  FOR_EACH_VEC_ELT (lhsc, j, c)
4874 	    {
4875 	      struct constraint_expr *c2;
4876 	      while (rhsc.length () > 0)
4877 		{
4878 		  c2 = &rhsc.last ();
4879 		  process_constraint (new_constraint (*c, *c2));
4880 		  rhsc.pop ();
4881 		}
4882 	    }
4883 	}
4884     }
4885   /* In IPA mode, we need to generate constraints to pass call
4886      arguments through their calls.   There are two cases,
4887      either a GIMPLE_CALL returning a value, or just a plain
4888      GIMPLE_CALL when we are not.
4889 
4890      In non-ipa mode, we need to generate constraints for each
4891      pointer passed by address.  */
4892   else if (is_gimple_call (t))
4893     find_func_aliases_for_call (fn, as_a <gcall *> (t));
4894 
4895   /* Otherwise, just a regular assignment statement.  Only care about
4896      operations with pointer result, others are dealt with as escape
4897      points if they have pointer operands.  */
4898   else if (is_gimple_assign (t))
4899     {
4900       /* Otherwise, just a regular assignment statement.  */
4901       tree lhsop = gimple_assign_lhs (t);
4902       tree rhsop = (gimple_num_ops (t) == 2) ? gimple_assign_rhs1 (t) : NULL;
4903 
4904       if (rhsop && TREE_CLOBBER_P (rhsop))
4905 	/* Ignore clobbers, they don't actually store anything into
4906 	   the LHS.  */
4907 	;
4908       else if (rhsop && AGGREGATE_TYPE_P (TREE_TYPE (lhsop)))
4909 	do_structure_copy (lhsop, rhsop);
4910       else
4911 	{
4912 	  enum tree_code code = gimple_assign_rhs_code (t);
4913 
4914 	  get_constraint_for (lhsop, &lhsc);
4915 
4916 	  if (code == POINTER_PLUS_EXPR)
4917 	    get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
4918 					   gimple_assign_rhs2 (t), &rhsc);
4919 	  else if (code == BIT_AND_EXPR
4920 		   && TREE_CODE (gimple_assign_rhs2 (t)) == INTEGER_CST)
4921 	    {
4922 	      /* Aligning a pointer via a BIT_AND_EXPR is offsetting
4923 		 the pointer.  Handle it by offsetting it by UNKNOWN.  */
4924 	      get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
4925 					     NULL_TREE, &rhsc);
4926 	    }
4927 	  else if (CONVERT_EXPR_CODE_P (code)
4928 		   || gimple_assign_single_p (t))
4929 	    /* See through conversions, single RHS are handled by
4930 	       get_constraint_for_rhs.  */
4931 	    get_constraint_for_rhs (rhsop, &rhsc);
4932 	  else if (code == COND_EXPR)
4933 	    {
4934 	      /* The result is a merge of both COND_EXPR arms.  */
4935 	      auto_vec<ce_s, 2> tmp;
4936 	      struct constraint_expr *rhsp;
4937 	      unsigned i;
4938 	      get_constraint_for_rhs (gimple_assign_rhs2 (t), &rhsc);
4939 	      get_constraint_for_rhs (gimple_assign_rhs3 (t), &tmp);
4940 	      FOR_EACH_VEC_ELT (tmp, i, rhsp)
4941 		rhsc.safe_push (*rhsp);
4942 	    }
4943 	  else if (truth_value_p (code))
4944 	    /* Truth value results are not pointer (parts).  Or at least
4945 	       very unreasonable obfuscation of a part.  */
4946 	    ;
4947 	  else
4948 	    {
4949 	      /* All other operations are possibly offsetting merges.  */
4950 	      auto_vec<ce_s, 4> tmp;
4951 	      struct constraint_expr *rhsp;
4952 	      unsigned i, j;
4953 	      get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
4954 					     NULL_TREE, &rhsc);
4955 	      for (i = 2; i < gimple_num_ops (t); ++i)
4956 		{
4957 		  get_constraint_for_ptr_offset (gimple_op (t, i),
4958 						 NULL_TREE, &tmp);
4959 		  FOR_EACH_VEC_ELT (tmp, j, rhsp)
4960 		    rhsc.safe_push (*rhsp);
4961 		  tmp.truncate (0);
4962 		}
4963 	    }
4964 	  process_all_all_constraints (lhsc, rhsc);
4965 	}
4966       /* If there is a store to a global variable the rhs escapes.  */
4967       if ((lhsop = get_base_address (lhsop)) != NULL_TREE
4968 	  && DECL_P (lhsop))
4969 	{
4970 	  varinfo_t vi = get_vi_for_tree (lhsop);
4971 	  if ((! in_ipa_mode && vi->is_global_var)
4972 	      || vi->is_ipa_escape_point)
4973 	    make_escape_constraint (rhsop);
4974 	}
4975     }
4976   /* Handle escapes through return.  */
4977   else if (gimple_code (t) == GIMPLE_RETURN
4978 	   && gimple_return_retval (as_a <greturn *> (t)) != NULL_TREE)
4979     {
4980       greturn *return_stmt = as_a <greturn *> (t);
4981       fi = NULL;
4982       if (!in_ipa_mode
4983 	  || !(fi = get_vi_for_tree (fn->decl)))
4984 	make_escape_constraint (gimple_return_retval (return_stmt));
4985       else if (in_ipa_mode)
4986 	{
4987 	  struct constraint_expr lhs ;
4988 	  struct constraint_expr *rhsp;
4989 	  unsigned i;
4990 
4991 	  lhs = get_function_part_constraint (fi, fi_result);
4992 	  get_constraint_for_rhs (gimple_return_retval (return_stmt), &rhsc);
4993 	  FOR_EACH_VEC_ELT (rhsc, i, rhsp)
4994 	    process_constraint (new_constraint (lhs, *rhsp));
4995 	}
4996     }
4997   /* Handle asms conservatively by adding escape constraints to everything.  */
4998   else if (gasm *asm_stmt = dyn_cast <gasm *> (t))
4999     {
5000       unsigned i, noutputs;
5001       const char **oconstraints;
5002       const char *constraint;
5003       bool allows_mem, allows_reg, is_inout;
5004 
5005       noutputs = gimple_asm_noutputs (asm_stmt);
5006       oconstraints = XALLOCAVEC (const char *, noutputs);
5007 
5008       for (i = 0; i < noutputs; ++i)
5009 	{
5010 	  tree link = gimple_asm_output_op (asm_stmt, i);
5011 	  tree op = TREE_VALUE (link);
5012 
5013 	  constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
5014 	  oconstraints[i] = constraint;
5015 	  parse_output_constraint (&constraint, i, 0, 0, &allows_mem,
5016 				   &allows_reg, &is_inout);
5017 
5018 	  /* A memory constraint makes the address of the operand escape.  */
5019 	  if (!allows_reg && allows_mem)
5020 	    make_escape_constraint (build_fold_addr_expr (op));
5021 
5022 	  /* The asm may read global memory, so outputs may point to
5023 	     any global memory.  */
5024 	  if (op)
5025 	    {
5026 	      auto_vec<ce_s, 2> lhsc;
5027 	      struct constraint_expr rhsc, *lhsp;
5028 	      unsigned j;
5029 	      get_constraint_for (op, &lhsc);
5030 	      rhsc.var = nonlocal_id;
5031 	      rhsc.offset = 0;
5032 	      rhsc.type = SCALAR;
5033 	      FOR_EACH_VEC_ELT (lhsc, j, lhsp)
5034 		process_constraint (new_constraint (*lhsp, rhsc));
5035 	    }
5036 	}
5037       for (i = 0; i < gimple_asm_ninputs (asm_stmt); ++i)
5038 	{
5039 	  tree link = gimple_asm_input_op (asm_stmt, i);
5040 	  tree op = TREE_VALUE (link);
5041 
5042 	  constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
5043 
5044 	  parse_input_constraint (&constraint, 0, 0, noutputs, 0, oconstraints,
5045 				  &allows_mem, &allows_reg);
5046 
5047 	  /* A memory constraint makes the address of the operand escape.  */
5048 	  if (!allows_reg && allows_mem)
5049 	    make_escape_constraint (build_fold_addr_expr (op));
5050 	  /* Strictly we'd only need the constraint to ESCAPED if
5051 	     the asm clobbers memory, otherwise using something
5052 	     along the lines of per-call clobbers/uses would be enough.  */
5053 	  else if (op)
5054 	    make_escape_constraint (op);
5055 	}
5056     }
5057 }
5058 
5059 
5060 /* Create a constraint adding to the clobber set of FI the memory
5061    pointed to by PTR.  */
5062 
5063 static void
process_ipa_clobber(varinfo_t fi,tree ptr)5064 process_ipa_clobber (varinfo_t fi, tree ptr)
5065 {
5066   vec<ce_s> ptrc = vNULL;
5067   struct constraint_expr *c, lhs;
5068   unsigned i;
5069   get_constraint_for_rhs (ptr, &ptrc);
5070   lhs = get_function_part_constraint (fi, fi_clobbers);
5071   FOR_EACH_VEC_ELT (ptrc, i, c)
5072     process_constraint (new_constraint (lhs, *c));
5073   ptrc.release ();
5074 }
5075 
5076 /* Walk statement T setting up clobber and use constraints according to the
5077    references found in T.  This function is a main part of the
5078    IPA constraint builder.  */
5079 
5080 static void
find_func_clobbers(struct function * fn,gimple * origt)5081 find_func_clobbers (struct function *fn, gimple *origt)
5082 {
5083   gimple *t = origt;
5084   auto_vec<ce_s, 16> lhsc;
5085   auto_vec<ce_s, 16> rhsc;
5086   varinfo_t fi;
5087 
5088   /* Add constraints for clobbered/used in IPA mode.
5089      We are not interested in what automatic variables are clobbered
5090      or used as we only use the information in the caller to which
5091      they do not escape.  */
5092   gcc_assert (in_ipa_mode);
5093 
5094   /* If the stmt refers to memory in any way it better had a VUSE.  */
5095   if (gimple_vuse (t) == NULL_TREE)
5096     return;
5097 
5098   /* We'd better have function information for the current function.  */
5099   fi = lookup_vi_for_tree (fn->decl);
5100   gcc_assert (fi != NULL);
5101 
5102   /* Account for stores in assignments and calls.  */
5103   if (gimple_vdef (t) != NULL_TREE
5104       && gimple_has_lhs (t))
5105     {
5106       tree lhs = gimple_get_lhs (t);
5107       tree tem = lhs;
5108       while (handled_component_p (tem))
5109 	tem = TREE_OPERAND (tem, 0);
5110       if ((DECL_P (tem)
5111 	   && !auto_var_in_fn_p (tem, fn->decl))
5112 	  || INDIRECT_REF_P (tem)
5113 	  || (TREE_CODE (tem) == MEM_REF
5114 	      && !(TREE_CODE (TREE_OPERAND (tem, 0)) == ADDR_EXPR
5115 		   && auto_var_in_fn_p
5116 		        (TREE_OPERAND (TREE_OPERAND (tem, 0), 0), fn->decl))))
5117 	{
5118 	  struct constraint_expr lhsc, *rhsp;
5119 	  unsigned i;
5120 	  lhsc = get_function_part_constraint (fi, fi_clobbers);
5121 	  get_constraint_for_address_of (lhs, &rhsc);
5122 	  FOR_EACH_VEC_ELT (rhsc, i, rhsp)
5123 	    process_constraint (new_constraint (lhsc, *rhsp));
5124 	  rhsc.truncate (0);
5125 	}
5126     }
5127 
5128   /* Account for uses in assigments and returns.  */
5129   if (gimple_assign_single_p (t)
5130       || (gimple_code (t) == GIMPLE_RETURN
5131 	  && gimple_return_retval (as_a <greturn *> (t)) != NULL_TREE))
5132     {
5133       tree rhs = (gimple_assign_single_p (t)
5134 		  ? gimple_assign_rhs1 (t)
5135 		  : gimple_return_retval (as_a <greturn *> (t)));
5136       tree tem = rhs;
5137       while (handled_component_p (tem))
5138 	tem = TREE_OPERAND (tem, 0);
5139       if ((DECL_P (tem)
5140 	   && !auto_var_in_fn_p (tem, fn->decl))
5141 	  || INDIRECT_REF_P (tem)
5142 	  || (TREE_CODE (tem) == MEM_REF
5143 	      && !(TREE_CODE (TREE_OPERAND (tem, 0)) == ADDR_EXPR
5144 		   && auto_var_in_fn_p
5145 		        (TREE_OPERAND (TREE_OPERAND (tem, 0), 0), fn->decl))))
5146 	{
5147 	  struct constraint_expr lhs, *rhsp;
5148 	  unsigned i;
5149 	  lhs = get_function_part_constraint (fi, fi_uses);
5150 	  get_constraint_for_address_of (rhs, &rhsc);
5151 	  FOR_EACH_VEC_ELT (rhsc, i, rhsp)
5152 	    process_constraint (new_constraint (lhs, *rhsp));
5153 	  rhsc.truncate (0);
5154 	}
5155     }
5156 
5157   if (gcall *call_stmt = dyn_cast <gcall *> (t))
5158     {
5159       varinfo_t cfi = NULL;
5160       tree decl = gimple_call_fndecl (t);
5161       struct constraint_expr lhs, rhs;
5162       unsigned i, j;
5163 
5164       /* For builtins we do not have separate function info.  For those
5165 	 we do not generate escapes for we have to generate clobbers/uses.  */
5166       if (gimple_call_builtin_p (t, BUILT_IN_NORMAL))
5167 	switch (DECL_FUNCTION_CODE (decl))
5168 	  {
5169 	  /* The following functions use and clobber memory pointed to
5170 	     by their arguments.  */
5171 	  case BUILT_IN_STRCPY:
5172 	  case BUILT_IN_STRNCPY:
5173 	  case BUILT_IN_BCOPY:
5174 	  case BUILT_IN_MEMCPY:
5175 	  case BUILT_IN_MEMMOVE:
5176 	  case BUILT_IN_MEMPCPY:
5177 	  case BUILT_IN_STPCPY:
5178 	  case BUILT_IN_STPNCPY:
5179 	  case BUILT_IN_STRCAT:
5180 	  case BUILT_IN_STRNCAT:
5181 	  case BUILT_IN_STRCPY_CHK:
5182 	  case BUILT_IN_STRNCPY_CHK:
5183 	  case BUILT_IN_MEMCPY_CHK:
5184 	  case BUILT_IN_MEMMOVE_CHK:
5185 	  case BUILT_IN_MEMPCPY_CHK:
5186 	  case BUILT_IN_STPCPY_CHK:
5187 	  case BUILT_IN_STPNCPY_CHK:
5188 	  case BUILT_IN_STRCAT_CHK:
5189 	  case BUILT_IN_STRNCAT_CHK:
5190 	    {
5191 	      tree dest = gimple_call_arg (t, (DECL_FUNCTION_CODE (decl)
5192 					       == BUILT_IN_BCOPY ? 1 : 0));
5193 	      tree src = gimple_call_arg (t, (DECL_FUNCTION_CODE (decl)
5194 					      == BUILT_IN_BCOPY ? 0 : 1));
5195 	      unsigned i;
5196 	      struct constraint_expr *rhsp, *lhsp;
5197 	      get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
5198 	      lhs = get_function_part_constraint (fi, fi_clobbers);
5199 	      FOR_EACH_VEC_ELT (lhsc, i, lhsp)
5200 		process_constraint (new_constraint (lhs, *lhsp));
5201 	      get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
5202 	      lhs = get_function_part_constraint (fi, fi_uses);
5203 	      FOR_EACH_VEC_ELT (rhsc, i, rhsp)
5204 		process_constraint (new_constraint (lhs, *rhsp));
5205 	      return;
5206 	    }
5207 	  /* The following function clobbers memory pointed to by
5208 	     its argument.  */
5209 	  case BUILT_IN_MEMSET:
5210 	  case BUILT_IN_MEMSET_CHK:
5211 	  case BUILT_IN_POSIX_MEMALIGN:
5212 	    {
5213 	      tree dest = gimple_call_arg (t, 0);
5214 	      unsigned i;
5215 	      ce_s *lhsp;
5216 	      get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
5217 	      lhs = get_function_part_constraint (fi, fi_clobbers);
5218 	      FOR_EACH_VEC_ELT (lhsc, i, lhsp)
5219 		process_constraint (new_constraint (lhs, *lhsp));
5220 	      return;
5221 	    }
5222 	  /* The following functions clobber their second and third
5223 	     arguments.  */
5224 	  case BUILT_IN_SINCOS:
5225 	  case BUILT_IN_SINCOSF:
5226 	  case BUILT_IN_SINCOSL:
5227 	    {
5228 	      process_ipa_clobber (fi, gimple_call_arg (t, 1));
5229 	      process_ipa_clobber (fi, gimple_call_arg (t, 2));
5230 	      return;
5231 	    }
5232 	  /* The following functions clobber their second argument.  */
5233 	  case BUILT_IN_FREXP:
5234 	  case BUILT_IN_FREXPF:
5235 	  case BUILT_IN_FREXPL:
5236 	  case BUILT_IN_LGAMMA_R:
5237 	  case BUILT_IN_LGAMMAF_R:
5238 	  case BUILT_IN_LGAMMAL_R:
5239 	  case BUILT_IN_GAMMA_R:
5240 	  case BUILT_IN_GAMMAF_R:
5241 	  case BUILT_IN_GAMMAL_R:
5242 	  case BUILT_IN_MODF:
5243 	  case BUILT_IN_MODFF:
5244 	  case BUILT_IN_MODFL:
5245 	    {
5246 	      process_ipa_clobber (fi, gimple_call_arg (t, 1));
5247 	      return;
5248 	    }
5249 	  /* The following functions clobber their third argument.  */
5250 	  case BUILT_IN_REMQUO:
5251 	  case BUILT_IN_REMQUOF:
5252 	  case BUILT_IN_REMQUOL:
5253 	    {
5254 	      process_ipa_clobber (fi, gimple_call_arg (t, 2));
5255 	      return;
5256 	    }
5257 	  /* The following functions neither read nor clobber memory.  */
5258 	  case BUILT_IN_ASSUME_ALIGNED:
5259 	  case BUILT_IN_FREE:
5260 	    return;
5261 	  /* Trampolines are of no interest to us.  */
5262 	  case BUILT_IN_INIT_TRAMPOLINE:
5263 	  case BUILT_IN_ADJUST_TRAMPOLINE:
5264 	    return;
5265 	  case BUILT_IN_VA_START:
5266 	  case BUILT_IN_VA_END:
5267 	    return;
5268 	  case BUILT_IN_GOMP_PARALLEL:
5269 	  case BUILT_IN_GOACC_PARALLEL:
5270 	    {
5271 	      unsigned int fnpos, argpos;
5272 	      unsigned int implicit_use_args[2];
5273 	      unsigned int num_implicit_use_args = 0;
5274 	      switch (DECL_FUNCTION_CODE (decl))
5275 		{
5276 		case BUILT_IN_GOMP_PARALLEL:
5277 		  /* __builtin_GOMP_parallel (fn, data, num_threads, flags).  */
5278 		  fnpos = 0;
5279 		  argpos = 1;
5280 		  break;
5281 		case BUILT_IN_GOACC_PARALLEL:
5282 		  /* __builtin_GOACC_parallel (device, fn, mapnum, hostaddrs,
5283 					       sizes, kinds, ...).  */
5284 		  fnpos = 1;
5285 		  argpos = 3;
5286 		  implicit_use_args[num_implicit_use_args++] = 4;
5287 		  implicit_use_args[num_implicit_use_args++] = 5;
5288 		  break;
5289 		default:
5290 		  gcc_unreachable ();
5291 		}
5292 
5293 	      tree fnarg = gimple_call_arg (t, fnpos);
5294 	      gcc_assert (TREE_CODE (fnarg) == ADDR_EXPR);
5295 	      tree fndecl = TREE_OPERAND (fnarg, 0);
5296 	      if (fndecl_maybe_in_other_partition (fndecl))
5297 		/* Fallthru to general call handling.  */
5298 		break;
5299 
5300 	      varinfo_t cfi = get_vi_for_tree (fndecl);
5301 
5302 	      tree arg = gimple_call_arg (t, argpos);
5303 
5304 	      /* Parameter passed by value is used.  */
5305 	      lhs = get_function_part_constraint (fi, fi_uses);
5306 	      struct constraint_expr *rhsp;
5307 	      get_constraint_for (arg, &rhsc);
5308 	      FOR_EACH_VEC_ELT (rhsc, j, rhsp)
5309 		process_constraint (new_constraint (lhs, *rhsp));
5310 	      rhsc.truncate (0);
5311 
5312 	      /* Handle parameters used by the call, but not used in cfi, as
5313 		 implicitly used by cfi.  */
5314 	      lhs = get_function_part_constraint (cfi, fi_uses);
5315 	      for (unsigned i = 0; i < num_implicit_use_args; ++i)
5316 		{
5317 		  tree arg = gimple_call_arg (t, implicit_use_args[i]);
5318 		  get_constraint_for (arg, &rhsc);
5319 		  FOR_EACH_VEC_ELT (rhsc, j, rhsp)
5320 		    process_constraint (new_constraint (lhs, *rhsp));
5321 		  rhsc.truncate (0);
5322 		}
5323 
5324 	      /* The caller clobbers what the callee does.  */
5325 	      lhs = get_function_part_constraint (fi, fi_clobbers);
5326 	      rhs = get_function_part_constraint (cfi, fi_clobbers);
5327 	      process_constraint (new_constraint (lhs, rhs));
5328 
5329 	      /* The caller uses what the callee does.  */
5330 	      lhs = get_function_part_constraint (fi, fi_uses);
5331 	      rhs = get_function_part_constraint (cfi, fi_uses);
5332 	      process_constraint (new_constraint (lhs, rhs));
5333 
5334 	      return;
5335 	    }
5336 	  /* printf-style functions may have hooks to set pointers to
5337 	     point to somewhere into the generated string.  Leave them
5338 	     for a later exercise...  */
5339 	  default:
5340 	    /* Fallthru to general call handling.  */;
5341 	  }
5342 
5343       /* Parameters passed by value are used.  */
5344       lhs = get_function_part_constraint (fi, fi_uses);
5345       for (i = 0; i < gimple_call_num_args (t); i++)
5346 	{
5347 	  struct constraint_expr *rhsp;
5348 	  tree arg = gimple_call_arg (t, i);
5349 
5350 	  if (TREE_CODE (arg) == SSA_NAME
5351 	      || is_gimple_min_invariant (arg))
5352 	    continue;
5353 
5354 	  get_constraint_for_address_of (arg, &rhsc);
5355 	  FOR_EACH_VEC_ELT (rhsc, j, rhsp)
5356 	    process_constraint (new_constraint (lhs, *rhsp));
5357 	  rhsc.truncate (0);
5358 	}
5359 
5360       /* Build constraints for propagating clobbers/uses along the
5361 	 callgraph edges.  */
5362       cfi = get_fi_for_callee (call_stmt);
5363       if (cfi->id == anything_id)
5364 	{
5365 	  if (gimple_vdef (t))
5366 	    make_constraint_from (first_vi_for_offset (fi, fi_clobbers),
5367 				  anything_id);
5368 	  make_constraint_from (first_vi_for_offset (fi, fi_uses),
5369 				anything_id);
5370 	  return;
5371 	}
5372 
5373       /* For callees without function info (that's external functions),
5374 	 ESCAPED is clobbered and used.  */
5375       if (gimple_call_fndecl (t)
5376 	  && !cfi->is_fn_info)
5377 	{
5378 	  varinfo_t vi;
5379 
5380 	  if (gimple_vdef (t))
5381 	    make_copy_constraint (first_vi_for_offset (fi, fi_clobbers),
5382 				  escaped_id);
5383 	  make_copy_constraint (first_vi_for_offset (fi, fi_uses), escaped_id);
5384 
5385 	  /* Also honor the call statement use/clobber info.  */
5386 	  if ((vi = lookup_call_clobber_vi (call_stmt)) != NULL)
5387 	    make_copy_constraint (first_vi_for_offset (fi, fi_clobbers),
5388 				  vi->id);
5389 	  if ((vi = lookup_call_use_vi (call_stmt)) != NULL)
5390 	    make_copy_constraint (first_vi_for_offset (fi, fi_uses),
5391 				  vi->id);
5392 	  return;
5393 	}
5394 
5395       /* Otherwise the caller clobbers and uses what the callee does.
5396 	 ???  This should use a new complex constraint that filters
5397 	 local variables of the callee.  */
5398       if (gimple_vdef (t))
5399 	{
5400 	  lhs = get_function_part_constraint (fi, fi_clobbers);
5401 	  rhs = get_function_part_constraint (cfi, fi_clobbers);
5402 	  process_constraint (new_constraint (lhs, rhs));
5403 	}
5404       lhs = get_function_part_constraint (fi, fi_uses);
5405       rhs = get_function_part_constraint (cfi, fi_uses);
5406       process_constraint (new_constraint (lhs, rhs));
5407     }
5408   else if (gimple_code (t) == GIMPLE_ASM)
5409     {
5410       /* ???  Ick.  We can do better.  */
5411       if (gimple_vdef (t))
5412 	make_constraint_from (first_vi_for_offset (fi, fi_clobbers),
5413 			      anything_id);
5414       make_constraint_from (first_vi_for_offset (fi, fi_uses),
5415 			    anything_id);
5416     }
5417 }
5418 
5419 
5420 /* Find the first varinfo in the same variable as START that overlaps with
5421    OFFSET.  Return NULL if we can't find one.  */
5422 
5423 static varinfo_t
first_vi_for_offset(varinfo_t start,unsigned HOST_WIDE_INT offset)5424 first_vi_for_offset (varinfo_t start, unsigned HOST_WIDE_INT offset)
5425 {
5426   /* If the offset is outside of the variable, bail out.  */
5427   if (offset >= start->fullsize)
5428     return NULL;
5429 
5430   /* If we cannot reach offset from start, lookup the first field
5431      and start from there.  */
5432   if (start->offset > offset)
5433     start = get_varinfo (start->head);
5434 
5435   while (start)
5436     {
5437       /* We may not find a variable in the field list with the actual
5438 	 offset when we have glommed a structure to a variable.
5439 	 In that case, however, offset should still be within the size
5440 	 of the variable. */
5441       if (offset >= start->offset
5442 	  && (offset - start->offset) < start->size)
5443 	return start;
5444 
5445       start = vi_next (start);
5446     }
5447 
5448   return NULL;
5449 }
5450 
5451 /* Find the first varinfo in the same variable as START that overlaps with
5452    OFFSET.  If there is no such varinfo the varinfo directly preceding
5453    OFFSET is returned.  */
5454 
5455 static varinfo_t
first_or_preceding_vi_for_offset(varinfo_t start,unsigned HOST_WIDE_INT offset)5456 first_or_preceding_vi_for_offset (varinfo_t start,
5457 				  unsigned HOST_WIDE_INT offset)
5458 {
5459   /* If we cannot reach offset from start, lookup the first field
5460      and start from there.  */
5461   if (start->offset > offset)
5462     start = get_varinfo (start->head);
5463 
5464   /* We may not find a variable in the field list with the actual
5465      offset when we have glommed a structure to a variable.
5466      In that case, however, offset should still be within the size
5467      of the variable.
5468      If we got beyond the offset we look for return the field
5469      directly preceding offset which may be the last field.  */
5470   while (start->next
5471 	 && offset >= start->offset
5472 	 && !((offset - start->offset) < start->size))
5473     start = vi_next (start);
5474 
5475   return start;
5476 }
5477 
5478 
5479 /* This structure is used during pushing fields onto the fieldstack
5480    to track the offset of the field, since bitpos_of_field gives it
5481    relative to its immediate containing type, and we want it relative
5482    to the ultimate containing object.  */
5483 
5484 struct fieldoff
5485 {
5486   /* Offset from the base of the base containing object to this field.  */
5487   HOST_WIDE_INT offset;
5488 
5489   /* Size, in bits, of the field.  */
5490   unsigned HOST_WIDE_INT size;
5491 
5492   unsigned has_unknown_size : 1;
5493 
5494   unsigned must_have_pointers : 1;
5495 
5496   unsigned may_have_pointers : 1;
5497 
5498   unsigned only_restrict_pointers : 1;
5499 
5500   tree restrict_pointed_type;
5501 };
5502 typedef struct fieldoff fieldoff_s;
5503 
5504 
5505 /* qsort comparison function for two fieldoff's PA and PB */
5506 
5507 static int
fieldoff_compare(const void * pa,const void * pb)5508 fieldoff_compare (const void *pa, const void *pb)
5509 {
5510   const fieldoff_s *foa = (const fieldoff_s *)pa;
5511   const fieldoff_s *fob = (const fieldoff_s *)pb;
5512   unsigned HOST_WIDE_INT foasize, fobsize;
5513 
5514   if (foa->offset < fob->offset)
5515     return -1;
5516   else if (foa->offset > fob->offset)
5517     return 1;
5518 
5519   foasize = foa->size;
5520   fobsize = fob->size;
5521   if (foasize < fobsize)
5522     return -1;
5523   else if (foasize > fobsize)
5524     return 1;
5525   return 0;
5526 }
5527 
5528 /* Sort a fieldstack according to the field offset and sizes.  */
5529 static void
sort_fieldstack(vec<fieldoff_s> fieldstack)5530 sort_fieldstack (vec<fieldoff_s> fieldstack)
5531 {
5532   fieldstack.qsort (fieldoff_compare);
5533 }
5534 
5535 /* Return true if T is a type that can have subvars.  */
5536 
5537 static inline bool
type_can_have_subvars(const_tree t)5538 type_can_have_subvars (const_tree t)
5539 {
5540   /* Aggregates without overlapping fields can have subvars.  */
5541   return TREE_CODE (t) == RECORD_TYPE;
5542 }
5543 
5544 /* Return true if V is a tree that we can have subvars for.
5545    Normally, this is any aggregate type.  Also complex
5546    types which are not gimple registers can have subvars.  */
5547 
5548 static inline bool
var_can_have_subvars(const_tree v)5549 var_can_have_subvars (const_tree v)
5550 {
5551   /* Volatile variables should never have subvars.  */
5552   if (TREE_THIS_VOLATILE (v))
5553     return false;
5554 
5555   /* Non decls or memory tags can never have subvars.  */
5556   if (!DECL_P (v))
5557     return false;
5558 
5559   return type_can_have_subvars (TREE_TYPE (v));
5560 }
5561 
5562 /* Return true if T is a type that does contain pointers.  */
5563 
5564 static bool
type_must_have_pointers(tree type)5565 type_must_have_pointers (tree type)
5566 {
5567   if (POINTER_TYPE_P (type))
5568     return true;
5569 
5570   if (TREE_CODE (type) == ARRAY_TYPE)
5571     return type_must_have_pointers (TREE_TYPE (type));
5572 
5573   /* A function or method can have pointers as arguments, so track
5574      those separately.  */
5575   if (TREE_CODE (type) == FUNCTION_TYPE
5576       || TREE_CODE (type) == METHOD_TYPE)
5577     return true;
5578 
5579   return false;
5580 }
5581 
5582 static bool
field_must_have_pointers(tree t)5583 field_must_have_pointers (tree t)
5584 {
5585   return type_must_have_pointers (TREE_TYPE (t));
5586 }
5587 
5588 /* Given a TYPE, and a vector of field offsets FIELDSTACK, push all
5589    the fields of TYPE onto fieldstack, recording their offsets along
5590    the way.
5591 
5592    OFFSET is used to keep track of the offset in this entire
5593    structure, rather than just the immediately containing structure.
5594    Returns false if the caller is supposed to handle the field we
5595    recursed for.  */
5596 
5597 static bool
push_fields_onto_fieldstack(tree type,vec<fieldoff_s> * fieldstack,HOST_WIDE_INT offset)5598 push_fields_onto_fieldstack (tree type, vec<fieldoff_s> *fieldstack,
5599 			     HOST_WIDE_INT offset)
5600 {
5601   tree field;
5602   bool empty_p = true;
5603 
5604   if (TREE_CODE (type) != RECORD_TYPE)
5605     return false;
5606 
5607   /* If the vector of fields is growing too big, bail out early.
5608      Callers check for vec::length <= MAX_FIELDS_FOR_FIELD_SENSITIVE, make
5609      sure this fails.  */
5610   if (fieldstack->length () > MAX_FIELDS_FOR_FIELD_SENSITIVE)
5611     return false;
5612 
5613   for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
5614     if (TREE_CODE (field) == FIELD_DECL)
5615       {
5616 	bool push = false;
5617 	HOST_WIDE_INT foff = bitpos_of_field (field);
5618 	tree field_type = TREE_TYPE (field);
5619 
5620 	if (!var_can_have_subvars (field)
5621 	    || TREE_CODE (field_type) == QUAL_UNION_TYPE
5622 	    || TREE_CODE (field_type) == UNION_TYPE)
5623 	  push = true;
5624 	else if (!push_fields_onto_fieldstack
5625 		    (field_type, fieldstack, offset + foff)
5626 		 && (DECL_SIZE (field)
5627 		     && !integer_zerop (DECL_SIZE (field))))
5628 	  /* Empty structures may have actual size, like in C++.  So
5629 	     see if we didn't push any subfields and the size is
5630 	     nonzero, push the field onto the stack.  */
5631 	  push = true;
5632 
5633 	if (push)
5634 	  {
5635 	    fieldoff_s *pair = NULL;
5636 	    bool has_unknown_size = false;
5637 	    bool must_have_pointers_p;
5638 
5639 	    if (!fieldstack->is_empty ())
5640 	      pair = &fieldstack->last ();
5641 
5642 	    /* If there isn't anything at offset zero, create sth.  */
5643 	    if (!pair
5644 		&& offset + foff != 0)
5645 	      {
5646 		fieldoff_s e
5647 		  = {0, offset + foff, false, false, true, false, NULL_TREE};
5648 		pair = fieldstack->safe_push (e);
5649 	      }
5650 
5651 	    if (!DECL_SIZE (field)
5652 		|| !tree_fits_uhwi_p (DECL_SIZE (field)))
5653 	      has_unknown_size = true;
5654 
5655 	    /* If adjacent fields do not contain pointers merge them.  */
5656 	    must_have_pointers_p = field_must_have_pointers (field);
5657 	    if (pair
5658 		&& !has_unknown_size
5659 		&& !must_have_pointers_p
5660 		&& !pair->must_have_pointers
5661 		&& !pair->has_unknown_size
5662 		&& pair->offset + (HOST_WIDE_INT)pair->size == offset + foff)
5663 	      {
5664 		pair->size += tree_to_uhwi (DECL_SIZE (field));
5665 	      }
5666 	    else
5667 	      {
5668 		fieldoff_s e;
5669 		e.offset = offset + foff;
5670 		e.has_unknown_size = has_unknown_size;
5671 		if (!has_unknown_size)
5672 		  e.size = tree_to_uhwi (DECL_SIZE (field));
5673 		else
5674 		  e.size = -1;
5675 		e.must_have_pointers = must_have_pointers_p;
5676 		e.may_have_pointers = true;
5677 		e.only_restrict_pointers
5678 		  = (!has_unknown_size
5679 		     && POINTER_TYPE_P (field_type)
5680 		     && TYPE_RESTRICT (field_type));
5681 		if (e.only_restrict_pointers)
5682 		  e.restrict_pointed_type = TREE_TYPE (field_type);
5683 		fieldstack->safe_push (e);
5684 	      }
5685 	  }
5686 
5687 	empty_p = false;
5688       }
5689 
5690   return !empty_p;
5691 }
5692 
5693 /* Count the number of arguments DECL has, and set IS_VARARGS to true
5694    if it is a varargs function.  */
5695 
5696 static unsigned int
count_num_arguments(tree decl,bool * is_varargs)5697 count_num_arguments (tree decl, bool *is_varargs)
5698 {
5699   unsigned int num = 0;
5700   tree t;
5701 
5702   /* Capture named arguments for K&R functions.  They do not
5703      have a prototype and thus no TYPE_ARG_TYPES.  */
5704   for (t = DECL_ARGUMENTS (decl); t; t = DECL_CHAIN (t))
5705     ++num;
5706 
5707   /* Check if the function has variadic arguments.  */
5708   for (t = TYPE_ARG_TYPES (TREE_TYPE (decl)); t; t = TREE_CHAIN (t))
5709     if (TREE_VALUE (t) == void_type_node)
5710       break;
5711   if (!t)
5712     *is_varargs = true;
5713 
5714   return num;
5715 }
5716 
5717 /* Creation function node for DECL, using NAME, and return the index
5718    of the variable we've created for the function.  If NONLOCAL_p, create
5719    initial constraints.  */
5720 
5721 static varinfo_t
create_function_info_for(tree decl,const char * name,bool add_id,bool nonlocal_p)5722 create_function_info_for (tree decl, const char *name, bool add_id,
5723 			  bool nonlocal_p)
5724 {
5725   struct function *fn = DECL_STRUCT_FUNCTION (decl);
5726   varinfo_t vi, prev_vi;
5727   tree arg;
5728   unsigned int i;
5729   bool is_varargs = false;
5730   unsigned int num_args = count_num_arguments (decl, &is_varargs);
5731 
5732   /* Create the variable info.  */
5733 
5734   vi = new_var_info (decl, name, add_id);
5735   vi->offset = 0;
5736   vi->size = 1;
5737   vi->fullsize = fi_parm_base + num_args;
5738   vi->is_fn_info = 1;
5739   vi->may_have_pointers = false;
5740   if (is_varargs)
5741     vi->fullsize = ~0;
5742   insert_vi_for_tree (vi->decl, vi);
5743 
5744   prev_vi = vi;
5745 
5746   /* Create a variable for things the function clobbers and one for
5747      things the function uses.  */
5748     {
5749       varinfo_t clobbervi, usevi;
5750       const char *newname;
5751       char *tempname;
5752 
5753       tempname = xasprintf ("%s.clobber", name);
5754       newname = ggc_strdup (tempname);
5755       free (tempname);
5756 
5757       clobbervi = new_var_info (NULL, newname, false);
5758       clobbervi->offset = fi_clobbers;
5759       clobbervi->size = 1;
5760       clobbervi->fullsize = vi->fullsize;
5761       clobbervi->is_full_var = true;
5762       clobbervi->is_global_var = false;
5763       clobbervi->is_reg_var = true;
5764 
5765       gcc_assert (prev_vi->offset < clobbervi->offset);
5766       prev_vi->next = clobbervi->id;
5767       prev_vi = clobbervi;
5768 
5769       tempname = xasprintf ("%s.use", name);
5770       newname = ggc_strdup (tempname);
5771       free (tempname);
5772 
5773       usevi = new_var_info (NULL, newname, false);
5774       usevi->offset = fi_uses;
5775       usevi->size = 1;
5776       usevi->fullsize = vi->fullsize;
5777       usevi->is_full_var = true;
5778       usevi->is_global_var = false;
5779       usevi->is_reg_var = true;
5780 
5781       gcc_assert (prev_vi->offset < usevi->offset);
5782       prev_vi->next = usevi->id;
5783       prev_vi = usevi;
5784     }
5785 
5786   /* And one for the static chain.  */
5787   if (fn->static_chain_decl != NULL_TREE)
5788     {
5789       varinfo_t chainvi;
5790       const char *newname;
5791       char *tempname;
5792 
5793       tempname = xasprintf ("%s.chain", name);
5794       newname = ggc_strdup (tempname);
5795       free (tempname);
5796 
5797       chainvi = new_var_info (fn->static_chain_decl, newname, false);
5798       chainvi->offset = fi_static_chain;
5799       chainvi->size = 1;
5800       chainvi->fullsize = vi->fullsize;
5801       chainvi->is_full_var = true;
5802       chainvi->is_global_var = false;
5803 
5804       insert_vi_for_tree (fn->static_chain_decl, chainvi);
5805 
5806       if (nonlocal_p
5807 	  && chainvi->may_have_pointers)
5808 	make_constraint_from (chainvi, nonlocal_id);
5809 
5810       gcc_assert (prev_vi->offset < chainvi->offset);
5811       prev_vi->next = chainvi->id;
5812       prev_vi = chainvi;
5813     }
5814 
5815   /* Create a variable for the return var.  */
5816   if (DECL_RESULT (decl) != NULL
5817       || !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
5818     {
5819       varinfo_t resultvi;
5820       const char *newname;
5821       char *tempname;
5822       tree resultdecl = decl;
5823 
5824       if (DECL_RESULT (decl))
5825 	resultdecl = DECL_RESULT (decl);
5826 
5827       tempname = xasprintf ("%s.result", name);
5828       newname = ggc_strdup (tempname);
5829       free (tempname);
5830 
5831       resultvi = new_var_info (resultdecl, newname, false);
5832       resultvi->offset = fi_result;
5833       resultvi->size = 1;
5834       resultvi->fullsize = vi->fullsize;
5835       resultvi->is_full_var = true;
5836       if (DECL_RESULT (decl))
5837 	resultvi->may_have_pointers = true;
5838 
5839       if (DECL_RESULT (decl))
5840 	insert_vi_for_tree (DECL_RESULT (decl), resultvi);
5841 
5842       if (nonlocal_p
5843 	  && DECL_RESULT (decl)
5844 	  && DECL_BY_REFERENCE (DECL_RESULT (decl)))
5845 	make_constraint_from (resultvi, nonlocal_id);
5846 
5847       gcc_assert (prev_vi->offset < resultvi->offset);
5848       prev_vi->next = resultvi->id;
5849       prev_vi = resultvi;
5850     }
5851 
5852   /* We also need to make function return values escape.  Nothing
5853      escapes by returning from main though.  */
5854   if (nonlocal_p
5855       && !MAIN_NAME_P (DECL_NAME (decl)))
5856     {
5857       varinfo_t fi, rvi;
5858       fi = lookup_vi_for_tree (decl);
5859       rvi = first_vi_for_offset (fi, fi_result);
5860       if (rvi && rvi->offset == fi_result)
5861 	make_copy_constraint (get_varinfo (escaped_id), rvi->id);
5862     }
5863 
5864   /* Set up variables for each argument.  */
5865   arg = DECL_ARGUMENTS (decl);
5866   for (i = 0; i < num_args; i++)
5867     {
5868       varinfo_t argvi;
5869       const char *newname;
5870       char *tempname;
5871       tree argdecl = decl;
5872 
5873       if (arg)
5874 	argdecl = arg;
5875 
5876       tempname = xasprintf ("%s.arg%d", name, i);
5877       newname = ggc_strdup (tempname);
5878       free (tempname);
5879 
5880       argvi = new_var_info (argdecl, newname, false);
5881       argvi->offset = fi_parm_base + i;
5882       argvi->size = 1;
5883       argvi->is_full_var = true;
5884       argvi->fullsize = vi->fullsize;
5885       if (arg)
5886 	argvi->may_have_pointers = true;
5887 
5888       if (arg)
5889 	insert_vi_for_tree (arg, argvi);
5890 
5891       if (nonlocal_p
5892 	  && argvi->may_have_pointers)
5893 	make_constraint_from (argvi, nonlocal_id);
5894 
5895       gcc_assert (prev_vi->offset < argvi->offset);
5896       prev_vi->next = argvi->id;
5897       prev_vi = argvi;
5898       if (arg)
5899 	arg = DECL_CHAIN (arg);
5900     }
5901 
5902   /* Add one representative for all further args.  */
5903   if (is_varargs)
5904     {
5905       varinfo_t argvi;
5906       const char *newname;
5907       char *tempname;
5908       tree decl;
5909 
5910       tempname = xasprintf ("%s.varargs", name);
5911       newname = ggc_strdup (tempname);
5912       free (tempname);
5913 
5914       /* We need sth that can be pointed to for va_start.  */
5915       decl = build_fake_var_decl (ptr_type_node);
5916 
5917       argvi = new_var_info (decl, newname, false);
5918       argvi->offset = fi_parm_base + num_args;
5919       argvi->size = ~0;
5920       argvi->is_full_var = true;
5921       argvi->is_heap_var = true;
5922       argvi->fullsize = vi->fullsize;
5923 
5924       if (nonlocal_p
5925 	  && argvi->may_have_pointers)
5926 	make_constraint_from (argvi, nonlocal_id);
5927 
5928       gcc_assert (prev_vi->offset < argvi->offset);
5929       prev_vi->next = argvi->id;
5930       prev_vi = argvi;
5931     }
5932 
5933   return vi;
5934 }
5935 
5936 
5937 /* Return true if FIELDSTACK contains fields that overlap.
5938    FIELDSTACK is assumed to be sorted by offset.  */
5939 
5940 static bool
check_for_overlaps(vec<fieldoff_s> fieldstack)5941 check_for_overlaps (vec<fieldoff_s> fieldstack)
5942 {
5943   fieldoff_s *fo = NULL;
5944   unsigned int i;
5945   HOST_WIDE_INT lastoffset = -1;
5946 
5947   FOR_EACH_VEC_ELT (fieldstack, i, fo)
5948     {
5949       if (fo->offset == lastoffset)
5950 	return true;
5951       lastoffset = fo->offset;
5952     }
5953   return false;
5954 }
5955 
5956 /* Create a varinfo structure for NAME and DECL, and add it to VARMAP.
5957    This will also create any varinfo structures necessary for fields
5958    of DECL.  DECL is a function parameter if HANDLE_PARAM is set.
5959    HANDLED_STRUCT_TYPE is used to register struct types reached by following
5960    restrict pointers.  This is needed to prevent infinite recursion.  */
5961 
5962 static varinfo_t
create_variable_info_for_1(tree decl,const char * name,bool add_id,bool handle_param,bitmap handled_struct_type)5963 create_variable_info_for_1 (tree decl, const char *name, bool add_id,
5964 			    bool handle_param, bitmap handled_struct_type)
5965 {
5966   varinfo_t vi, newvi;
5967   tree decl_type = TREE_TYPE (decl);
5968   tree declsize = DECL_P (decl) ? DECL_SIZE (decl) : TYPE_SIZE (decl_type);
5969   auto_vec<fieldoff_s> fieldstack;
5970   fieldoff_s *fo;
5971   unsigned int i;
5972 
5973   if (!declsize
5974       || !tree_fits_uhwi_p (declsize))
5975     {
5976       vi = new_var_info (decl, name, add_id);
5977       vi->offset = 0;
5978       vi->size = ~0;
5979       vi->fullsize = ~0;
5980       vi->is_unknown_size_var = true;
5981       vi->is_full_var = true;
5982       vi->may_have_pointers = true;
5983       return vi;
5984     }
5985 
5986   /* Collect field information.  */
5987   if (use_field_sensitive
5988       && var_can_have_subvars (decl)
5989       /* ???  Force us to not use subfields for globals in IPA mode.
5990 	 Else we'd have to parse arbitrary initializers.  */
5991       && !(in_ipa_mode
5992 	   && is_global_var (decl)))
5993     {
5994       fieldoff_s *fo = NULL;
5995       bool notokay = false;
5996       unsigned int i;
5997 
5998       push_fields_onto_fieldstack (decl_type, &fieldstack, 0);
5999 
6000       for (i = 0; !notokay && fieldstack.iterate (i, &fo); i++)
6001 	if (fo->has_unknown_size
6002 	    || fo->offset < 0)
6003 	  {
6004 	    notokay = true;
6005 	    break;
6006 	  }
6007 
6008       /* We can't sort them if we have a field with a variable sized type,
6009 	 which will make notokay = true.  In that case, we are going to return
6010 	 without creating varinfos for the fields anyway, so sorting them is a
6011 	 waste to boot.  */
6012       if (!notokay)
6013 	{
6014 	  sort_fieldstack (fieldstack);
6015 	  /* Due to some C++ FE issues, like PR 22488, we might end up
6016 	     what appear to be overlapping fields even though they,
6017 	     in reality, do not overlap.  Until the C++ FE is fixed,
6018 	     we will simply disable field-sensitivity for these cases.  */
6019 	  notokay = check_for_overlaps (fieldstack);
6020 	}
6021 
6022       if (notokay)
6023 	fieldstack.release ();
6024     }
6025 
6026   /* If we didn't end up collecting sub-variables create a full
6027      variable for the decl.  */
6028   if (fieldstack.length () == 0
6029       || fieldstack.length () > MAX_FIELDS_FOR_FIELD_SENSITIVE)
6030     {
6031       vi = new_var_info (decl, name, add_id);
6032       vi->offset = 0;
6033       vi->may_have_pointers = true;
6034       vi->fullsize = tree_to_uhwi (declsize);
6035       vi->size = vi->fullsize;
6036       vi->is_full_var = true;
6037       if (POINTER_TYPE_P (decl_type)
6038 	  && TYPE_RESTRICT (decl_type))
6039 	vi->only_restrict_pointers = 1;
6040       if (vi->only_restrict_pointers
6041 	  && !type_contains_placeholder_p (TREE_TYPE (decl_type))
6042 	  && handle_param
6043 	  && !bitmap_bit_p (handled_struct_type,
6044 			    TYPE_UID (TREE_TYPE (decl_type))))
6045 	{
6046 	  varinfo_t rvi;
6047 	  tree heapvar = build_fake_var_decl (TREE_TYPE (decl_type));
6048 	  DECL_EXTERNAL (heapvar) = 1;
6049 	  if (var_can_have_subvars (heapvar))
6050 	    bitmap_set_bit (handled_struct_type,
6051 			    TYPE_UID (TREE_TYPE (decl_type)));
6052 	  rvi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS", true,
6053 					    true, handled_struct_type);
6054 	  if (var_can_have_subvars (heapvar))
6055 	    bitmap_clear_bit (handled_struct_type,
6056 			      TYPE_UID (TREE_TYPE (decl_type)));
6057 	  rvi->is_restrict_var = 1;
6058 	  insert_vi_for_tree (heapvar, rvi);
6059 	  make_constraint_from (vi, rvi->id);
6060 	  make_param_constraints (rvi);
6061 	}
6062       fieldstack.release ();
6063       return vi;
6064     }
6065 
6066   vi = new_var_info (decl, name, add_id);
6067   vi->fullsize = tree_to_uhwi (declsize);
6068   if (fieldstack.length () == 1)
6069     vi->is_full_var = true;
6070   for (i = 0, newvi = vi;
6071        fieldstack.iterate (i, &fo);
6072        ++i, newvi = vi_next (newvi))
6073     {
6074       const char *newname = NULL;
6075       char *tempname;
6076 
6077       if (dump_file)
6078 	{
6079 	  if (fieldstack.length () != 1)
6080 	    {
6081 	      tempname
6082 		= xasprintf ("%s." HOST_WIDE_INT_PRINT_DEC
6083 			     "+" HOST_WIDE_INT_PRINT_DEC, name,
6084 			     fo->offset, fo->size);
6085 	      newname = ggc_strdup (tempname);
6086 	      free (tempname);
6087 	    }
6088 	}
6089       else
6090 	newname = "NULL";
6091 
6092       if (newname)
6093 	  newvi->name = newname;
6094       newvi->offset = fo->offset;
6095       newvi->size = fo->size;
6096       newvi->fullsize = vi->fullsize;
6097       newvi->may_have_pointers = fo->may_have_pointers;
6098       newvi->only_restrict_pointers = fo->only_restrict_pointers;
6099       if (handle_param
6100 	  && newvi->only_restrict_pointers
6101 	  && !type_contains_placeholder_p (fo->restrict_pointed_type)
6102 	  && !bitmap_bit_p (handled_struct_type,
6103 			    TYPE_UID (fo->restrict_pointed_type)))
6104 	{
6105 	  varinfo_t rvi;
6106 	  tree heapvar = build_fake_var_decl (fo->restrict_pointed_type);
6107 	  DECL_EXTERNAL (heapvar) = 1;
6108 	  if (var_can_have_subvars (heapvar))
6109 	    bitmap_set_bit (handled_struct_type,
6110 			    TYPE_UID (fo->restrict_pointed_type));
6111 	  rvi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS", true,
6112 					    true, handled_struct_type);
6113 	  if (var_can_have_subvars (heapvar))
6114 	    bitmap_clear_bit (handled_struct_type,
6115 			      TYPE_UID (fo->restrict_pointed_type));
6116 	  rvi->is_restrict_var = 1;
6117 	  insert_vi_for_tree (heapvar, rvi);
6118 	  make_constraint_from (newvi, rvi->id);
6119 	  make_param_constraints (rvi);
6120 	}
6121       if (i + 1 < fieldstack.length ())
6122 	{
6123 	  varinfo_t tem = new_var_info (decl, name, false);
6124 	  newvi->next = tem->id;
6125 	  tem->head = vi->id;
6126 	}
6127     }
6128 
6129   return vi;
6130 }
6131 
6132 static unsigned int
create_variable_info_for(tree decl,const char * name,bool add_id)6133 create_variable_info_for (tree decl, const char *name, bool add_id)
6134 {
6135   varinfo_t vi = create_variable_info_for_1 (decl, name, add_id, false, NULL);
6136   unsigned int id = vi->id;
6137 
6138   insert_vi_for_tree (decl, vi);
6139 
6140   if (!VAR_P (decl))
6141     return id;
6142 
6143   /* Create initial constraints for globals.  */
6144   for (; vi; vi = vi_next (vi))
6145     {
6146       if (!vi->may_have_pointers
6147 	  || !vi->is_global_var)
6148 	continue;
6149 
6150       /* Mark global restrict qualified pointers.  */
6151       if ((POINTER_TYPE_P (TREE_TYPE (decl))
6152 	   && TYPE_RESTRICT (TREE_TYPE (decl)))
6153 	  || vi->only_restrict_pointers)
6154 	{
6155 	  varinfo_t rvi
6156 	    = make_constraint_from_global_restrict (vi, "GLOBAL_RESTRICT",
6157 						    true);
6158 	  /* ???  For now exclude reads from globals as restrict sources
6159 	     if those are not (indirectly) from incoming parameters.  */
6160 	  rvi->is_restrict_var = false;
6161 	  continue;
6162 	}
6163 
6164       /* In non-IPA mode the initializer from nonlocal is all we need.  */
6165       if (!in_ipa_mode
6166 	  || DECL_HARD_REGISTER (decl))
6167 	make_copy_constraint (vi, nonlocal_id);
6168 
6169       /* In IPA mode parse the initializer and generate proper constraints
6170 	 for it.  */
6171       else
6172 	{
6173 	  varpool_node *vnode = varpool_node::get (decl);
6174 
6175 	  /* For escaped variables initialize them from nonlocal.  */
6176 	  if (!vnode->all_refs_explicit_p ())
6177 	    make_copy_constraint (vi, nonlocal_id);
6178 
6179 	  /* If this is a global variable with an initializer and we are in
6180 	     IPA mode generate constraints for it.  */
6181 	  ipa_ref *ref;
6182 	  for (unsigned idx = 0; vnode->iterate_reference (idx, ref); ++idx)
6183 	    {
6184 	      auto_vec<ce_s> rhsc;
6185 	      struct constraint_expr lhs, *rhsp;
6186 	      unsigned i;
6187 	      get_constraint_for_address_of (ref->referred->decl, &rhsc);
6188 	      lhs.var = vi->id;
6189 	      lhs.offset = 0;
6190 	      lhs.type = SCALAR;
6191 	      FOR_EACH_VEC_ELT (rhsc, i, rhsp)
6192 		process_constraint (new_constraint (lhs, *rhsp));
6193 	      /* If this is a variable that escapes from the unit
6194 		 the initializer escapes as well.  */
6195 	      if (!vnode->all_refs_explicit_p ())
6196 		{
6197 		  lhs.var = escaped_id;
6198 		  lhs.offset = 0;
6199 		  lhs.type = SCALAR;
6200 		  FOR_EACH_VEC_ELT (rhsc, i, rhsp)
6201 		    process_constraint (new_constraint (lhs, *rhsp));
6202 		}
6203 	    }
6204 	}
6205     }
6206 
6207   return id;
6208 }
6209 
6210 /* Print out the points-to solution for VAR to FILE.  */
6211 
6212 static void
dump_solution_for_var(FILE * file,unsigned int var)6213 dump_solution_for_var (FILE *file, unsigned int var)
6214 {
6215   varinfo_t vi = get_varinfo (var);
6216   unsigned int i;
6217   bitmap_iterator bi;
6218 
6219   /* Dump the solution for unified vars anyway, this avoids difficulties
6220      in scanning dumps in the testsuite.  */
6221   fprintf (file, "%s = { ", vi->name);
6222   vi = get_varinfo (find (var));
6223   EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, i, bi)
6224     fprintf (file, "%s ", get_varinfo (i)->name);
6225   fprintf (file, "}");
6226 
6227   /* But note when the variable was unified.  */
6228   if (vi->id != var)
6229     fprintf (file, " same as %s", vi->name);
6230 
6231   fprintf (file, "\n");
6232 }
6233 
6234 /* Print the points-to solution for VAR to stderr.  */
6235 
6236 DEBUG_FUNCTION void
debug_solution_for_var(unsigned int var)6237 debug_solution_for_var (unsigned int var)
6238 {
6239   dump_solution_for_var (stderr, var);
6240 }
6241 
6242 /* Register the constraints for function parameter related VI.  */
6243 
6244 static void
make_param_constraints(varinfo_t vi)6245 make_param_constraints (varinfo_t vi)
6246 {
6247   for (; vi; vi = vi_next (vi))
6248     {
6249       if (vi->only_restrict_pointers)
6250 	;
6251       else if (vi->may_have_pointers)
6252 	make_constraint_from (vi, nonlocal_id);
6253 
6254       if (vi->is_full_var)
6255 	break;
6256     }
6257 }
6258 
6259 /* Create varinfo structures for all of the variables in the
6260    function for intraprocedural mode.  */
6261 
6262 static void
intra_create_variable_infos(struct function * fn)6263 intra_create_variable_infos (struct function *fn)
6264 {
6265   tree t;
6266   bitmap handled_struct_type = NULL;
6267 
6268   /* For each incoming pointer argument arg, create the constraint ARG
6269      = NONLOCAL or a dummy variable if it is a restrict qualified
6270      passed-by-reference argument.  */
6271   for (t = DECL_ARGUMENTS (fn->decl); t; t = DECL_CHAIN (t))
6272     {
6273       if (handled_struct_type == NULL)
6274 	handled_struct_type = BITMAP_ALLOC (NULL);
6275 
6276       varinfo_t p
6277 	= create_variable_info_for_1 (t, alias_get_name (t), false, true,
6278 				      handled_struct_type);
6279       insert_vi_for_tree (t, p);
6280 
6281       make_param_constraints (p);
6282     }
6283 
6284   if (handled_struct_type != NULL)
6285     BITMAP_FREE (handled_struct_type);
6286 
6287   /* Add a constraint for a result decl that is passed by reference.  */
6288   if (DECL_RESULT (fn->decl)
6289       && DECL_BY_REFERENCE (DECL_RESULT (fn->decl)))
6290     {
6291       varinfo_t p, result_vi = get_vi_for_tree (DECL_RESULT (fn->decl));
6292 
6293       for (p = result_vi; p; p = vi_next (p))
6294 	make_constraint_from (p, nonlocal_id);
6295     }
6296 
6297   /* Add a constraint for the incoming static chain parameter.  */
6298   if (fn->static_chain_decl != NULL_TREE)
6299     {
6300       varinfo_t p, chain_vi = get_vi_for_tree (fn->static_chain_decl);
6301 
6302       for (p = chain_vi; p; p = vi_next (p))
6303 	make_constraint_from (p, nonlocal_id);
6304     }
6305 }
6306 
6307 /* Structure used to put solution bitmaps in a hashtable so they can
6308    be shared among variables with the same points-to set.  */
6309 
6310 typedef struct shared_bitmap_info
6311 {
6312   bitmap pt_vars;
6313   hashval_t hashcode;
6314 } *shared_bitmap_info_t;
6315 typedef const struct shared_bitmap_info *const_shared_bitmap_info_t;
6316 
6317 /* Shared_bitmap hashtable helpers.  */
6318 
6319 struct shared_bitmap_hasher : free_ptr_hash <shared_bitmap_info>
6320 {
6321   static inline hashval_t hash (const shared_bitmap_info *);
6322   static inline bool equal (const shared_bitmap_info *,
6323 			    const shared_bitmap_info *);
6324 };
6325 
6326 /* Hash function for a shared_bitmap_info_t */
6327 
6328 inline hashval_t
hash(const shared_bitmap_info * bi)6329 shared_bitmap_hasher::hash (const shared_bitmap_info *bi)
6330 {
6331   return bi->hashcode;
6332 }
6333 
6334 /* Equality function for two shared_bitmap_info_t's. */
6335 
6336 inline bool
equal(const shared_bitmap_info * sbi1,const shared_bitmap_info * sbi2)6337 shared_bitmap_hasher::equal (const shared_bitmap_info *sbi1,
6338 			     const shared_bitmap_info *sbi2)
6339 {
6340   return bitmap_equal_p (sbi1->pt_vars, sbi2->pt_vars);
6341 }
6342 
6343 /* Shared_bitmap hashtable.  */
6344 
6345 static hash_table<shared_bitmap_hasher> *shared_bitmap_table;
6346 
6347 /* Lookup a bitmap in the shared bitmap hashtable, and return an already
6348    existing instance if there is one, NULL otherwise.  */
6349 
6350 static bitmap
shared_bitmap_lookup(bitmap pt_vars)6351 shared_bitmap_lookup (bitmap pt_vars)
6352 {
6353   shared_bitmap_info **slot;
6354   struct shared_bitmap_info sbi;
6355 
6356   sbi.pt_vars = pt_vars;
6357   sbi.hashcode = bitmap_hash (pt_vars);
6358 
6359   slot = shared_bitmap_table->find_slot (&sbi, NO_INSERT);
6360   if (!slot)
6361     return NULL;
6362   else
6363     return (*slot)->pt_vars;
6364 }
6365 
6366 
6367 /* Add a bitmap to the shared bitmap hashtable.  */
6368 
6369 static void
shared_bitmap_add(bitmap pt_vars)6370 shared_bitmap_add (bitmap pt_vars)
6371 {
6372   shared_bitmap_info **slot;
6373   shared_bitmap_info_t sbi = XNEW (struct shared_bitmap_info);
6374 
6375   sbi->pt_vars = pt_vars;
6376   sbi->hashcode = bitmap_hash (pt_vars);
6377 
6378   slot = shared_bitmap_table->find_slot (sbi, INSERT);
6379   gcc_assert (!*slot);
6380   *slot = sbi;
6381 }
6382 
6383 
6384 /* Set bits in INTO corresponding to the variable uids in solution set FROM.  */
6385 
6386 static void
set_uids_in_ptset(bitmap into,bitmap from,struct pt_solution * pt,tree fndecl)6387 set_uids_in_ptset (bitmap into, bitmap from, struct pt_solution *pt,
6388 		   tree fndecl)
6389 {
6390   unsigned int i;
6391   bitmap_iterator bi;
6392   varinfo_t escaped_vi = get_varinfo (find (escaped_id));
6393   bool everything_escaped
6394     = escaped_vi->solution && bitmap_bit_p (escaped_vi->solution, anything_id);
6395 
6396   EXECUTE_IF_SET_IN_BITMAP (from, 0, i, bi)
6397     {
6398       varinfo_t vi = get_varinfo (i);
6399 
6400       /* The only artificial variables that are allowed in a may-alias
6401 	 set are heap variables.  */
6402       if (vi->is_artificial_var && !vi->is_heap_var)
6403 	continue;
6404 
6405       if (everything_escaped
6406 	  || (escaped_vi->solution
6407 	      && bitmap_bit_p (escaped_vi->solution, i)))
6408 	{
6409 	  pt->vars_contains_escaped = true;
6410 	  pt->vars_contains_escaped_heap |= vi->is_heap_var;
6411 	}
6412 
6413       if (vi->is_restrict_var)
6414 	pt->vars_contains_restrict = true;
6415 
6416       if (VAR_P (vi->decl)
6417 	  || TREE_CODE (vi->decl) == PARM_DECL
6418 	  || TREE_CODE (vi->decl) == RESULT_DECL)
6419 	{
6420 	  /* If we are in IPA mode we will not recompute points-to
6421 	     sets after inlining so make sure they stay valid.  */
6422 	  if (in_ipa_mode
6423 	      && !DECL_PT_UID_SET_P (vi->decl))
6424 	    SET_DECL_PT_UID (vi->decl, DECL_UID (vi->decl));
6425 
6426 	  /* Add the decl to the points-to set.  Note that the points-to
6427 	     set contains global variables.  */
6428 	  bitmap_set_bit (into, DECL_PT_UID (vi->decl));
6429 	  if (vi->is_global_var
6430 	      /* In IPA mode the escaped_heap trick doesn't work as
6431 		 ESCAPED is escaped from the unit but
6432 		 pt_solution_includes_global needs to answer true for
6433 		 all variables not automatic within a function.
6434 		 For the same reason is_global_var is not the
6435 		 correct flag to track - local variables from other
6436 		 functions also need to be considered global.
6437 		 Conveniently all HEAP vars are not put in function
6438 		 scope.  */
6439 	      || (in_ipa_mode
6440 		  && fndecl
6441 		  && ! auto_var_in_fn_p (vi->decl, fndecl)))
6442 	    pt->vars_contains_nonlocal = true;
6443 
6444 	  /* If we have a variable that is interposable record that fact
6445 	     for pointer comparison simplification.  */
6446 	  if (VAR_P (vi->decl)
6447 	      && (TREE_STATIC (vi->decl) || DECL_EXTERNAL (vi->decl))
6448 	      && ! decl_binds_to_current_def_p (vi->decl))
6449 	    pt->vars_contains_interposable = true;
6450 	}
6451 
6452       else if (TREE_CODE (vi->decl) == FUNCTION_DECL
6453 	       || TREE_CODE (vi->decl) == LABEL_DECL)
6454 	{
6455 	  /* Nothing should read/write from/to code so we can
6456 	     save bits by not including them in the points-to bitmaps.
6457 	     Still mark the points-to set as containing global memory
6458 	     to make code-patching possible - see PR70128.  */
6459 	  pt->vars_contains_nonlocal = true;
6460 	}
6461     }
6462 }
6463 
6464 
6465 /* Compute the points-to solution *PT for the variable VI.  */
6466 
6467 static struct pt_solution
find_what_var_points_to(tree fndecl,varinfo_t orig_vi)6468 find_what_var_points_to (tree fndecl, varinfo_t orig_vi)
6469 {
6470   unsigned int i;
6471   bitmap_iterator bi;
6472   bitmap finished_solution;
6473   bitmap result;
6474   varinfo_t vi;
6475   struct pt_solution *pt;
6476 
6477   /* This variable may have been collapsed, let's get the real
6478      variable.  */
6479   vi = get_varinfo (find (orig_vi->id));
6480 
6481   /* See if we have already computed the solution and return it.  */
6482   pt_solution **slot = &final_solutions->get_or_insert (vi);
6483   if (*slot != NULL)
6484     return **slot;
6485 
6486   *slot = pt = XOBNEW (&final_solutions_obstack, struct pt_solution);
6487   memset (pt, 0, sizeof (struct pt_solution));
6488 
6489   /* Translate artificial variables into SSA_NAME_PTR_INFO
6490      attributes.  */
6491   EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, i, bi)
6492     {
6493       varinfo_t vi = get_varinfo (i);
6494 
6495       if (vi->is_artificial_var)
6496 	{
6497 	  if (vi->id == nothing_id)
6498 	    pt->null = 1;
6499 	  else if (vi->id == escaped_id)
6500 	    {
6501 	      if (in_ipa_mode)
6502 		pt->ipa_escaped = 1;
6503 	      else
6504 		pt->escaped = 1;
6505 	      /* Expand some special vars of ESCAPED in-place here.  */
6506 	      varinfo_t evi = get_varinfo (find (escaped_id));
6507 	      if (bitmap_bit_p (evi->solution, nonlocal_id))
6508 		pt->nonlocal = 1;
6509 	    }
6510 	  else if (vi->id == nonlocal_id)
6511 	    pt->nonlocal = 1;
6512 	  else if (vi->is_heap_var)
6513 	    /* We represent heapvars in the points-to set properly.  */
6514 	    ;
6515 	  else if (vi->id == string_id)
6516 	    /* Nobody cares - STRING_CSTs are read-only entities.  */
6517 	    ;
6518 	  else if (vi->id == anything_id
6519 		   || vi->id == integer_id)
6520 	    pt->anything = 1;
6521 	}
6522     }
6523 
6524   /* Instead of doing extra work, simply do not create
6525      elaborate points-to information for pt_anything pointers.  */
6526   if (pt->anything)
6527     return *pt;
6528 
6529   /* Share the final set of variables when possible.  */
6530   finished_solution = BITMAP_GGC_ALLOC ();
6531   stats.points_to_sets_created++;
6532 
6533   set_uids_in_ptset (finished_solution, vi->solution, pt, fndecl);
6534   result = shared_bitmap_lookup (finished_solution);
6535   if (!result)
6536     {
6537       shared_bitmap_add (finished_solution);
6538       pt->vars = finished_solution;
6539     }
6540   else
6541     {
6542       pt->vars = result;
6543       bitmap_clear (finished_solution);
6544     }
6545 
6546   return *pt;
6547 }
6548 
6549 /* Given a pointer variable P, fill in its points-to set.  */
6550 
6551 static void
find_what_p_points_to(tree fndecl,tree p)6552 find_what_p_points_to (tree fndecl, tree p)
6553 {
6554   struct ptr_info_def *pi;
6555   tree lookup_p = p;
6556   varinfo_t vi;
6557   bool nonnull = get_ptr_nonnull (p);
6558 
6559   /* For parameters, get at the points-to set for the actual parm
6560      decl.  */
6561   if (TREE_CODE (p) == SSA_NAME
6562       && SSA_NAME_IS_DEFAULT_DEF (p)
6563       && (TREE_CODE (SSA_NAME_VAR (p)) == PARM_DECL
6564 	  || TREE_CODE (SSA_NAME_VAR (p)) == RESULT_DECL))
6565     lookup_p = SSA_NAME_VAR (p);
6566 
6567   vi = lookup_vi_for_tree (lookup_p);
6568   if (!vi)
6569     return;
6570 
6571   pi = get_ptr_info (p);
6572   pi->pt = find_what_var_points_to (fndecl, vi);
6573   /* Conservatively set to NULL from PTA (to true). */
6574   pi->pt.null = 1;
6575   /* Preserve pointer nonnull computed by VRP.  See get_ptr_nonnull
6576      in gcc/tree-ssaname.c for more information.  */
6577   if (nonnull)
6578     set_ptr_nonnull (p);
6579 }
6580 
6581 
6582 /* Query statistics for points-to solutions.  */
6583 
6584 static struct {
6585   unsigned HOST_WIDE_INT pt_solution_includes_may_alias;
6586   unsigned HOST_WIDE_INT pt_solution_includes_no_alias;
6587   unsigned HOST_WIDE_INT pt_solutions_intersect_may_alias;
6588   unsigned HOST_WIDE_INT pt_solutions_intersect_no_alias;
6589 } pta_stats;
6590 
6591 void
dump_pta_stats(FILE * s)6592 dump_pta_stats (FILE *s)
6593 {
6594   fprintf (s, "\nPTA query stats:\n");
6595   fprintf (s, "  pt_solution_includes: "
6596 	   HOST_WIDE_INT_PRINT_DEC" disambiguations, "
6597 	   HOST_WIDE_INT_PRINT_DEC" queries\n",
6598 	   pta_stats.pt_solution_includes_no_alias,
6599 	   pta_stats.pt_solution_includes_no_alias
6600 	   + pta_stats.pt_solution_includes_may_alias);
6601   fprintf (s, "  pt_solutions_intersect: "
6602 	   HOST_WIDE_INT_PRINT_DEC" disambiguations, "
6603 	   HOST_WIDE_INT_PRINT_DEC" queries\n",
6604 	   pta_stats.pt_solutions_intersect_no_alias,
6605 	   pta_stats.pt_solutions_intersect_no_alias
6606 	   + pta_stats.pt_solutions_intersect_may_alias);
6607 }
6608 
6609 
6610 /* Reset the points-to solution *PT to a conservative default
6611    (point to anything).  */
6612 
6613 void
pt_solution_reset(struct pt_solution * pt)6614 pt_solution_reset (struct pt_solution *pt)
6615 {
6616   memset (pt, 0, sizeof (struct pt_solution));
6617   pt->anything = true;
6618   pt->null = true;
6619 }
6620 
6621 /* Set the points-to solution *PT to point only to the variables
6622    in VARS.  VARS_CONTAINS_GLOBAL specifies whether that contains
6623    global variables and VARS_CONTAINS_RESTRICT specifies whether
6624    it contains restrict tag variables.  */
6625 
6626 void
pt_solution_set(struct pt_solution * pt,bitmap vars,bool vars_contains_nonlocal)6627 pt_solution_set (struct pt_solution *pt, bitmap vars,
6628 		 bool vars_contains_nonlocal)
6629 {
6630   memset (pt, 0, sizeof (struct pt_solution));
6631   pt->vars = vars;
6632   pt->vars_contains_nonlocal = vars_contains_nonlocal;
6633   pt->vars_contains_escaped
6634     = (cfun->gimple_df->escaped.anything
6635        || bitmap_intersect_p (cfun->gimple_df->escaped.vars, vars));
6636 }
6637 
6638 /* Set the points-to solution *PT to point only to the variable VAR.  */
6639 
6640 void
pt_solution_set_var(struct pt_solution * pt,tree var)6641 pt_solution_set_var (struct pt_solution *pt, tree var)
6642 {
6643   memset (pt, 0, sizeof (struct pt_solution));
6644   pt->vars = BITMAP_GGC_ALLOC ();
6645   bitmap_set_bit (pt->vars, DECL_PT_UID (var));
6646   pt->vars_contains_nonlocal = is_global_var (var);
6647   pt->vars_contains_escaped
6648     = (cfun->gimple_df->escaped.anything
6649        || bitmap_bit_p (cfun->gimple_df->escaped.vars, DECL_PT_UID (var)));
6650 }
6651 
6652 /* Computes the union of the points-to solutions *DEST and *SRC and
6653    stores the result in *DEST.  This changes the points-to bitmap
6654    of *DEST and thus may not be used if that might be shared.
6655    The points-to bitmap of *SRC and *DEST will not be shared after
6656    this function if they were not before.  */
6657 
6658 static void
pt_solution_ior_into(struct pt_solution * dest,struct pt_solution * src)6659 pt_solution_ior_into (struct pt_solution *dest, struct pt_solution *src)
6660 {
6661   dest->anything |= src->anything;
6662   if (dest->anything)
6663     {
6664       pt_solution_reset (dest);
6665       return;
6666     }
6667 
6668   dest->nonlocal |= src->nonlocal;
6669   dest->escaped |= src->escaped;
6670   dest->ipa_escaped |= src->ipa_escaped;
6671   dest->null |= src->null;
6672   dest->vars_contains_nonlocal |= src->vars_contains_nonlocal;
6673   dest->vars_contains_escaped |= src->vars_contains_escaped;
6674   dest->vars_contains_escaped_heap |= src->vars_contains_escaped_heap;
6675   if (!src->vars)
6676     return;
6677 
6678   if (!dest->vars)
6679     dest->vars = BITMAP_GGC_ALLOC ();
6680   bitmap_ior_into (dest->vars, src->vars);
6681 }
6682 
6683 /* Return true if the points-to solution *PT is empty.  */
6684 
6685 bool
pt_solution_empty_p(struct pt_solution * pt)6686 pt_solution_empty_p (struct pt_solution *pt)
6687 {
6688   if (pt->anything
6689       || pt->nonlocal)
6690     return false;
6691 
6692   if (pt->vars
6693       && !bitmap_empty_p (pt->vars))
6694     return false;
6695 
6696   /* If the solution includes ESCAPED, check if that is empty.  */
6697   if (pt->escaped
6698       && !pt_solution_empty_p (&cfun->gimple_df->escaped))
6699     return false;
6700 
6701   /* If the solution includes ESCAPED, check if that is empty.  */
6702   if (pt->ipa_escaped
6703       && !pt_solution_empty_p (&ipa_escaped_pt))
6704     return false;
6705 
6706   return true;
6707 }
6708 
6709 /* Return true if the points-to solution *PT only point to a single var, and
6710    return the var uid in *UID.  */
6711 
6712 bool
pt_solution_singleton_or_null_p(struct pt_solution * pt,unsigned * uid)6713 pt_solution_singleton_or_null_p (struct pt_solution *pt, unsigned *uid)
6714 {
6715   if (pt->anything || pt->nonlocal || pt->escaped || pt->ipa_escaped
6716       || pt->vars == NULL
6717       || !bitmap_single_bit_set_p (pt->vars))
6718     return false;
6719 
6720   *uid = bitmap_first_set_bit (pt->vars);
6721   return true;
6722 }
6723 
6724 /* Return true if the points-to solution *PT includes global memory.  */
6725 
6726 bool
pt_solution_includes_global(struct pt_solution * pt)6727 pt_solution_includes_global (struct pt_solution *pt)
6728 {
6729   if (pt->anything
6730       || pt->nonlocal
6731       || pt->vars_contains_nonlocal
6732       /* The following is a hack to make the malloc escape hack work.
6733          In reality we'd need different sets for escaped-through-return
6734 	 and escaped-to-callees and passes would need to be updated.  */
6735       || pt->vars_contains_escaped_heap)
6736     return true;
6737 
6738   /* 'escaped' is also a placeholder so we have to look into it.  */
6739   if (pt->escaped)
6740     return pt_solution_includes_global (&cfun->gimple_df->escaped);
6741 
6742   if (pt->ipa_escaped)
6743     return pt_solution_includes_global (&ipa_escaped_pt);
6744 
6745   return false;
6746 }
6747 
6748 /* Return true if the points-to solution *PT includes the variable
6749    declaration DECL.  */
6750 
6751 static bool
pt_solution_includes_1(struct pt_solution * pt,const_tree decl)6752 pt_solution_includes_1 (struct pt_solution *pt, const_tree decl)
6753 {
6754   if (pt->anything)
6755     return true;
6756 
6757   if (pt->nonlocal
6758       && is_global_var (decl))
6759     return true;
6760 
6761   if (pt->vars
6762       && bitmap_bit_p (pt->vars, DECL_PT_UID (decl)))
6763     return true;
6764 
6765   /* If the solution includes ESCAPED, check it.  */
6766   if (pt->escaped
6767       && pt_solution_includes_1 (&cfun->gimple_df->escaped, decl))
6768     return true;
6769 
6770   /* If the solution includes ESCAPED, check it.  */
6771   if (pt->ipa_escaped
6772       && pt_solution_includes_1 (&ipa_escaped_pt, decl))
6773     return true;
6774 
6775   return false;
6776 }
6777 
6778 bool
pt_solution_includes(struct pt_solution * pt,const_tree decl)6779 pt_solution_includes (struct pt_solution *pt, const_tree decl)
6780 {
6781   bool res = pt_solution_includes_1 (pt, decl);
6782   if (res)
6783     ++pta_stats.pt_solution_includes_may_alias;
6784   else
6785     ++pta_stats.pt_solution_includes_no_alias;
6786   return res;
6787 }
6788 
6789 /* Return true if both points-to solutions PT1 and PT2 have a non-empty
6790    intersection.  */
6791 
6792 static bool
pt_solutions_intersect_1(struct pt_solution * pt1,struct pt_solution * pt2)6793 pt_solutions_intersect_1 (struct pt_solution *pt1, struct pt_solution *pt2)
6794 {
6795   if (pt1->anything || pt2->anything)
6796     return true;
6797 
6798   /* If either points to unknown global memory and the other points to
6799      any global memory they alias.  */
6800   if ((pt1->nonlocal
6801        && (pt2->nonlocal
6802 	   || pt2->vars_contains_nonlocal))
6803       || (pt2->nonlocal
6804 	  && pt1->vars_contains_nonlocal))
6805     return true;
6806 
6807   /* If either points to all escaped memory and the other points to
6808      any escaped memory they alias.  */
6809   if ((pt1->escaped
6810        && (pt2->escaped
6811 	   || pt2->vars_contains_escaped))
6812       || (pt2->escaped
6813 	  && pt1->vars_contains_escaped))
6814     return true;
6815 
6816   /* Check the escaped solution if required.
6817      ???  Do we need to check the local against the IPA escaped sets?  */
6818   if ((pt1->ipa_escaped || pt2->ipa_escaped)
6819       && !pt_solution_empty_p (&ipa_escaped_pt))
6820     {
6821       /* If both point to escaped memory and that solution
6822 	 is not empty they alias.  */
6823       if (pt1->ipa_escaped && pt2->ipa_escaped)
6824 	return true;
6825 
6826       /* If either points to escaped memory see if the escaped solution
6827 	 intersects with the other.  */
6828       if ((pt1->ipa_escaped
6829 	   && pt_solutions_intersect_1 (&ipa_escaped_pt, pt2))
6830 	  || (pt2->ipa_escaped
6831 	      && pt_solutions_intersect_1 (&ipa_escaped_pt, pt1)))
6832 	return true;
6833     }
6834 
6835   /* Now both pointers alias if their points-to solution intersects.  */
6836   return (pt1->vars
6837 	  && pt2->vars
6838 	  && bitmap_intersect_p (pt1->vars, pt2->vars));
6839 }
6840 
6841 bool
pt_solutions_intersect(struct pt_solution * pt1,struct pt_solution * pt2)6842 pt_solutions_intersect (struct pt_solution *pt1, struct pt_solution *pt2)
6843 {
6844   bool res = pt_solutions_intersect_1 (pt1, pt2);
6845   if (res)
6846     ++pta_stats.pt_solutions_intersect_may_alias;
6847   else
6848     ++pta_stats.pt_solutions_intersect_no_alias;
6849   return res;
6850 }
6851 
6852 
6853 /* Dump points-to information to OUTFILE.  */
6854 
6855 static void
dump_sa_points_to_info(FILE * outfile)6856 dump_sa_points_to_info (FILE *outfile)
6857 {
6858   unsigned int i;
6859 
6860   fprintf (outfile, "\nPoints-to sets\n\n");
6861 
6862   if (dump_flags & TDF_STATS)
6863     {
6864       fprintf (outfile, "Stats:\n");
6865       fprintf (outfile, "Total vars:               %d\n", stats.total_vars);
6866       fprintf (outfile, "Non-pointer vars:          %d\n",
6867 	       stats.nonpointer_vars);
6868       fprintf (outfile, "Statically unified vars:  %d\n",
6869 	       stats.unified_vars_static);
6870       fprintf (outfile, "Dynamically unified vars: %d\n",
6871 	       stats.unified_vars_dynamic);
6872       fprintf (outfile, "Iterations:               %d\n", stats.iterations);
6873       fprintf (outfile, "Number of edges:          %d\n", stats.num_edges);
6874       fprintf (outfile, "Number of implicit edges: %d\n",
6875 	       stats.num_implicit_edges);
6876     }
6877 
6878   for (i = 1; i < varmap.length (); i++)
6879     {
6880       varinfo_t vi = get_varinfo (i);
6881       if (!vi->may_have_pointers)
6882 	continue;
6883       dump_solution_for_var (outfile, i);
6884     }
6885 }
6886 
6887 
6888 /* Debug points-to information to stderr.  */
6889 
6890 DEBUG_FUNCTION void
debug_sa_points_to_info(void)6891 debug_sa_points_to_info (void)
6892 {
6893   dump_sa_points_to_info (stderr);
6894 }
6895 
6896 
6897 /* Initialize the always-existing constraint variables for NULL
6898    ANYTHING, READONLY, and INTEGER */
6899 
6900 static void
init_base_vars(void)6901 init_base_vars (void)
6902 {
6903   struct constraint_expr lhs, rhs;
6904   varinfo_t var_anything;
6905   varinfo_t var_nothing;
6906   varinfo_t var_string;
6907   varinfo_t var_escaped;
6908   varinfo_t var_nonlocal;
6909   varinfo_t var_storedanything;
6910   varinfo_t var_integer;
6911 
6912   /* Variable ID zero is reserved and should be NULL.  */
6913   varmap.safe_push (NULL);
6914 
6915   /* Create the NULL variable, used to represent that a variable points
6916      to NULL.  */
6917   var_nothing = new_var_info (NULL_TREE, "NULL", false);
6918   gcc_assert (var_nothing->id == nothing_id);
6919   var_nothing->is_artificial_var = 1;
6920   var_nothing->offset = 0;
6921   var_nothing->size = ~0;
6922   var_nothing->fullsize = ~0;
6923   var_nothing->is_special_var = 1;
6924   var_nothing->may_have_pointers = 0;
6925   var_nothing->is_global_var = 0;
6926 
6927   /* Create the ANYTHING variable, used to represent that a variable
6928      points to some unknown piece of memory.  */
6929   var_anything = new_var_info (NULL_TREE, "ANYTHING", false);
6930   gcc_assert (var_anything->id == anything_id);
6931   var_anything->is_artificial_var = 1;
6932   var_anything->size = ~0;
6933   var_anything->offset = 0;
6934   var_anything->fullsize = ~0;
6935   var_anything->is_special_var = 1;
6936 
6937   /* Anything points to anything.  This makes deref constraints just
6938      work in the presence of linked list and other p = *p type loops,
6939      by saying that *ANYTHING = ANYTHING. */
6940   lhs.type = SCALAR;
6941   lhs.var = anything_id;
6942   lhs.offset = 0;
6943   rhs.type = ADDRESSOF;
6944   rhs.var = anything_id;
6945   rhs.offset = 0;
6946 
6947   /* This specifically does not use process_constraint because
6948      process_constraint ignores all anything = anything constraints, since all
6949      but this one are redundant.  */
6950   constraints.safe_push (new_constraint (lhs, rhs));
6951 
6952   /* Create the STRING variable, used to represent that a variable
6953      points to a string literal.  String literals don't contain
6954      pointers so STRING doesn't point to anything.  */
6955   var_string = new_var_info (NULL_TREE, "STRING", false);
6956   gcc_assert (var_string->id == string_id);
6957   var_string->is_artificial_var = 1;
6958   var_string->offset = 0;
6959   var_string->size = ~0;
6960   var_string->fullsize = ~0;
6961   var_string->is_special_var = 1;
6962   var_string->may_have_pointers = 0;
6963 
6964   /* Create the ESCAPED variable, used to represent the set of escaped
6965      memory.  */
6966   var_escaped = new_var_info (NULL_TREE, "ESCAPED", false);
6967   gcc_assert (var_escaped->id == escaped_id);
6968   var_escaped->is_artificial_var = 1;
6969   var_escaped->offset = 0;
6970   var_escaped->size = ~0;
6971   var_escaped->fullsize = ~0;
6972   var_escaped->is_special_var = 0;
6973 
6974   /* Create the NONLOCAL variable, used to represent the set of nonlocal
6975      memory.  */
6976   var_nonlocal = new_var_info (NULL_TREE, "NONLOCAL", false);
6977   gcc_assert (var_nonlocal->id == nonlocal_id);
6978   var_nonlocal->is_artificial_var = 1;
6979   var_nonlocal->offset = 0;
6980   var_nonlocal->size = ~0;
6981   var_nonlocal->fullsize = ~0;
6982   var_nonlocal->is_special_var = 1;
6983 
6984   /* ESCAPED = *ESCAPED, because escaped is may-deref'd at calls, etc.  */
6985   lhs.type = SCALAR;
6986   lhs.var = escaped_id;
6987   lhs.offset = 0;
6988   rhs.type = DEREF;
6989   rhs.var = escaped_id;
6990   rhs.offset = 0;
6991   process_constraint (new_constraint (lhs, rhs));
6992 
6993   /* ESCAPED = ESCAPED + UNKNOWN_OFFSET, because if a sub-field escapes the
6994      whole variable escapes.  */
6995   lhs.type = SCALAR;
6996   lhs.var = escaped_id;
6997   lhs.offset = 0;
6998   rhs.type = SCALAR;
6999   rhs.var = escaped_id;
7000   rhs.offset = UNKNOWN_OFFSET;
7001   process_constraint (new_constraint (lhs, rhs));
7002 
7003   /* *ESCAPED = NONLOCAL.  This is true because we have to assume
7004      everything pointed to by escaped points to what global memory can
7005      point to.  */
7006   lhs.type = DEREF;
7007   lhs.var = escaped_id;
7008   lhs.offset = 0;
7009   rhs.type = SCALAR;
7010   rhs.var = nonlocal_id;
7011   rhs.offset = 0;
7012   process_constraint (new_constraint (lhs, rhs));
7013 
7014   /* NONLOCAL = &NONLOCAL, NONLOCAL = &ESCAPED.  This is true because
7015      global memory may point to global memory and escaped memory.  */
7016   lhs.type = SCALAR;
7017   lhs.var = nonlocal_id;
7018   lhs.offset = 0;
7019   rhs.type = ADDRESSOF;
7020   rhs.var = nonlocal_id;
7021   rhs.offset = 0;
7022   process_constraint (new_constraint (lhs, rhs));
7023   rhs.type = ADDRESSOF;
7024   rhs.var = escaped_id;
7025   rhs.offset = 0;
7026   process_constraint (new_constraint (lhs, rhs));
7027 
7028   /* Create the STOREDANYTHING variable, used to represent the set of
7029      variables stored to *ANYTHING.  */
7030   var_storedanything = new_var_info (NULL_TREE, "STOREDANYTHING", false);
7031   gcc_assert (var_storedanything->id == storedanything_id);
7032   var_storedanything->is_artificial_var = 1;
7033   var_storedanything->offset = 0;
7034   var_storedanything->size = ~0;
7035   var_storedanything->fullsize = ~0;
7036   var_storedanything->is_special_var = 0;
7037 
7038   /* Create the INTEGER variable, used to represent that a variable points
7039      to what an INTEGER "points to".  */
7040   var_integer = new_var_info (NULL_TREE, "INTEGER", false);
7041   gcc_assert (var_integer->id == integer_id);
7042   var_integer->is_artificial_var = 1;
7043   var_integer->size = ~0;
7044   var_integer->fullsize = ~0;
7045   var_integer->offset = 0;
7046   var_integer->is_special_var = 1;
7047 
7048   /* INTEGER = ANYTHING, because we don't know where a dereference of
7049      a random integer will point to.  */
7050   lhs.type = SCALAR;
7051   lhs.var = integer_id;
7052   lhs.offset = 0;
7053   rhs.type = ADDRESSOF;
7054   rhs.var = anything_id;
7055   rhs.offset = 0;
7056   process_constraint (new_constraint (lhs, rhs));
7057 }
7058 
7059 /* Initialize things necessary to perform PTA */
7060 
7061 static void
init_alias_vars(void)7062 init_alias_vars (void)
7063 {
7064   use_field_sensitive = (MAX_FIELDS_FOR_FIELD_SENSITIVE > 1);
7065 
7066   bitmap_obstack_initialize (&pta_obstack);
7067   bitmap_obstack_initialize (&oldpta_obstack);
7068   bitmap_obstack_initialize (&predbitmap_obstack);
7069 
7070   constraints.create (8);
7071   varmap.create (8);
7072   vi_for_tree = new hash_map<tree, varinfo_t>;
7073   call_stmt_vars = new hash_map<gimple *, varinfo_t>;
7074 
7075   memset (&stats, 0, sizeof (stats));
7076   shared_bitmap_table = new hash_table<shared_bitmap_hasher> (511);
7077   init_base_vars ();
7078 
7079   gcc_obstack_init (&fake_var_decl_obstack);
7080 
7081   final_solutions = new hash_map<varinfo_t, pt_solution *>;
7082   gcc_obstack_init (&final_solutions_obstack);
7083 }
7084 
7085 /* Remove the REF and ADDRESS edges from GRAPH, as well as all the
7086    predecessor edges.  */
7087 
7088 static void
remove_preds_and_fake_succs(constraint_graph_t graph)7089 remove_preds_and_fake_succs (constraint_graph_t graph)
7090 {
7091   unsigned int i;
7092 
7093   /* Clear the implicit ref and address nodes from the successor
7094      lists.  */
7095   for (i = 1; i < FIRST_REF_NODE; i++)
7096     {
7097       if (graph->succs[i])
7098 	bitmap_clear_range (graph->succs[i], FIRST_REF_NODE,
7099 			    FIRST_REF_NODE * 2);
7100     }
7101 
7102   /* Free the successor list for the non-ref nodes.  */
7103   for (i = FIRST_REF_NODE + 1; i < graph->size; i++)
7104     {
7105       if (graph->succs[i])
7106 	BITMAP_FREE (graph->succs[i]);
7107     }
7108 
7109   /* Now reallocate the size of the successor list as, and blow away
7110      the predecessor bitmaps.  */
7111   graph->size = varmap.length ();
7112   graph->succs = XRESIZEVEC (bitmap, graph->succs, graph->size);
7113 
7114   free (graph->implicit_preds);
7115   graph->implicit_preds = NULL;
7116   free (graph->preds);
7117   graph->preds = NULL;
7118   bitmap_obstack_release (&predbitmap_obstack);
7119 }
7120 
7121 /* Solve the constraint set.  */
7122 
7123 static void
solve_constraints(void)7124 solve_constraints (void)
7125 {
7126   struct scc_info *si;
7127 
7128   /* Sort varinfos so that ones that cannot be pointed to are last.
7129      This makes bitmaps more efficient.  */
7130   unsigned int *map = XNEWVEC (unsigned int, varmap.length ());
7131   for (unsigned i = 0; i < integer_id + 1; ++i)
7132     map[i] = i;
7133   /* Start with non-register vars (as possibly address-taken), followed
7134      by register vars as conservative set of vars never appearing in
7135      the points-to solution bitmaps.  */
7136   unsigned j = integer_id + 1;
7137   for (unsigned i = integer_id + 1; i < varmap.length (); ++i)
7138     if (! varmap[i]->is_reg_var)
7139       map[i] = j++;
7140   for (unsigned i = integer_id + 1; i < varmap.length (); ++i)
7141     if (varmap[i]->is_reg_var)
7142       map[i] = j++;
7143   /* Shuffle varmap according to map.  */
7144   for (unsigned i = integer_id + 1; i < varmap.length (); ++i)
7145     {
7146       while (map[varmap[i]->id] != i)
7147 	std::swap (varmap[i], varmap[map[varmap[i]->id]]);
7148       gcc_assert (bitmap_empty_p (varmap[i]->solution));
7149       varmap[i]->id = i;
7150       varmap[i]->next = map[varmap[i]->next];
7151       varmap[i]->head = map[varmap[i]->head];
7152     }
7153   /* Finally rewrite constraints.  */
7154   for (unsigned i = 0; i < constraints.length (); ++i)
7155     {
7156       constraints[i]->lhs.var = map[constraints[i]->lhs.var];
7157       constraints[i]->rhs.var = map[constraints[i]->rhs.var];
7158     }
7159   free (map);
7160 
7161   if (dump_file)
7162     fprintf (dump_file,
7163 	     "\nCollapsing static cycles and doing variable "
7164 	     "substitution\n");
7165 
7166   init_graph (varmap.length () * 2);
7167 
7168   if (dump_file)
7169     fprintf (dump_file, "Building predecessor graph\n");
7170   build_pred_graph ();
7171 
7172   if (dump_file)
7173     fprintf (dump_file, "Detecting pointer and location "
7174 	     "equivalences\n");
7175   si = perform_var_substitution (graph);
7176 
7177   if (dump_file)
7178     fprintf (dump_file, "Rewriting constraints and unifying "
7179 	     "variables\n");
7180   rewrite_constraints (graph, si);
7181 
7182   build_succ_graph ();
7183 
7184   free_var_substitution_info (si);
7185 
7186   /* Attach complex constraints to graph nodes.  */
7187   move_complex_constraints (graph);
7188 
7189   if (dump_file)
7190     fprintf (dump_file, "Uniting pointer but not location equivalent "
7191 	     "variables\n");
7192   unite_pointer_equivalences (graph);
7193 
7194   if (dump_file)
7195     fprintf (dump_file, "Finding indirect cycles\n");
7196   find_indirect_cycles (graph);
7197 
7198   /* Implicit nodes and predecessors are no longer necessary at this
7199      point. */
7200   remove_preds_and_fake_succs (graph);
7201 
7202   if (dump_file && (dump_flags & TDF_GRAPH))
7203     {
7204       fprintf (dump_file, "\n\n// The constraint graph before solve-graph "
7205 	       "in dot format:\n");
7206       dump_constraint_graph (dump_file);
7207       fprintf (dump_file, "\n\n");
7208     }
7209 
7210   if (dump_file)
7211     fprintf (dump_file, "Solving graph\n");
7212 
7213   solve_graph (graph);
7214 
7215   if (dump_file && (dump_flags & TDF_GRAPH))
7216     {
7217       fprintf (dump_file, "\n\n// The constraint graph after solve-graph "
7218 	       "in dot format:\n");
7219       dump_constraint_graph (dump_file);
7220       fprintf (dump_file, "\n\n");
7221     }
7222 
7223   if (dump_file)
7224     dump_sa_points_to_info (dump_file);
7225 }
7226 
7227 /* Create points-to sets for the current function.  See the comments
7228    at the start of the file for an algorithmic overview.  */
7229 
7230 static void
compute_points_to_sets(void)7231 compute_points_to_sets (void)
7232 {
7233   basic_block bb;
7234   varinfo_t vi;
7235 
7236   timevar_push (TV_TREE_PTA);
7237 
7238   init_alias_vars ();
7239 
7240   intra_create_variable_infos (cfun);
7241 
7242   /* Now walk all statements and build the constraint set.  */
7243   FOR_EACH_BB_FN (bb, cfun)
7244     {
7245       for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
7246 	   gsi_next (&gsi))
7247 	{
7248 	  gphi *phi = gsi.phi ();
7249 
7250 	  if (! virtual_operand_p (gimple_phi_result (phi)))
7251 	    find_func_aliases (cfun, phi);
7252 	}
7253 
7254       for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
7255 	   gsi_next (&gsi))
7256 	{
7257 	  gimple *stmt = gsi_stmt (gsi);
7258 
7259 	  find_func_aliases (cfun, stmt);
7260 	}
7261     }
7262 
7263   if (dump_file)
7264     {
7265       fprintf (dump_file, "Points-to analysis\n\nConstraints:\n\n");
7266       dump_constraints (dump_file, 0);
7267     }
7268 
7269   /* From the constraints compute the points-to sets.  */
7270   solve_constraints ();
7271 
7272   /* Compute the points-to set for ESCAPED used for call-clobber analysis.  */
7273   cfun->gimple_df->escaped = find_what_var_points_to (cfun->decl,
7274 						      get_varinfo (escaped_id));
7275 
7276   /* Make sure the ESCAPED solution (which is used as placeholder in
7277      other solutions) does not reference itself.  This simplifies
7278      points-to solution queries.  */
7279   cfun->gimple_df->escaped.escaped = 0;
7280 
7281   /* Compute the points-to sets for pointer SSA_NAMEs.  */
7282   unsigned i;
7283   tree ptr;
7284 
7285   FOR_EACH_SSA_NAME (i, ptr, cfun)
7286     {
7287       if (POINTER_TYPE_P (TREE_TYPE (ptr)))
7288 	find_what_p_points_to (cfun->decl, ptr);
7289     }
7290 
7291   /* Compute the call-used/clobbered sets.  */
7292   FOR_EACH_BB_FN (bb, cfun)
7293     {
7294       gimple_stmt_iterator gsi;
7295 
7296       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
7297 	{
7298 	  gcall *stmt;
7299 	  struct pt_solution *pt;
7300 
7301 	  stmt = dyn_cast <gcall *> (gsi_stmt (gsi));
7302 	  if (!stmt)
7303 	    continue;
7304 
7305 	  pt = gimple_call_use_set (stmt);
7306 	  if (gimple_call_flags (stmt) & ECF_CONST)
7307 	    memset (pt, 0, sizeof (struct pt_solution));
7308 	  else if ((vi = lookup_call_use_vi (stmt)) != NULL)
7309 	    {
7310 	      *pt = find_what_var_points_to (cfun->decl, vi);
7311 	      /* Escaped (and thus nonlocal) variables are always
7312 	         implicitly used by calls.  */
7313 	      /* ???  ESCAPED can be empty even though NONLOCAL
7314 		 always escaped.  */
7315 	      pt->nonlocal = 1;
7316 	      pt->escaped = 1;
7317 	    }
7318 	  else
7319 	    {
7320 	      /* If there is nothing special about this call then
7321 		 we have made everything that is used also escape.  */
7322 	      *pt = cfun->gimple_df->escaped;
7323 	      pt->nonlocal = 1;
7324 	    }
7325 
7326 	  pt = gimple_call_clobber_set (stmt);
7327 	  if (gimple_call_flags (stmt) & (ECF_CONST|ECF_PURE|ECF_NOVOPS))
7328 	    memset (pt, 0, sizeof (struct pt_solution));
7329 	  else if ((vi = lookup_call_clobber_vi (stmt)) != NULL)
7330 	    {
7331 	      *pt = find_what_var_points_to (cfun->decl, vi);
7332 	      /* Escaped (and thus nonlocal) variables are always
7333 	         implicitly clobbered by calls.  */
7334 	      /* ???  ESCAPED can be empty even though NONLOCAL
7335 		 always escaped.  */
7336 	      pt->nonlocal = 1;
7337 	      pt->escaped = 1;
7338 	    }
7339 	  else
7340 	    {
7341 	      /* If there is nothing special about this call then
7342 		 we have made everything that is used also escape.  */
7343 	      *pt = cfun->gimple_df->escaped;
7344 	      pt->nonlocal = 1;
7345 	    }
7346 	}
7347     }
7348 
7349   timevar_pop (TV_TREE_PTA);
7350 }
7351 
7352 
7353 /* Delete created points-to sets.  */
7354 
7355 static void
delete_points_to_sets(void)7356 delete_points_to_sets (void)
7357 {
7358   unsigned int i;
7359 
7360   delete shared_bitmap_table;
7361   shared_bitmap_table = NULL;
7362   if (dump_file && (dump_flags & TDF_STATS))
7363     fprintf (dump_file, "Points to sets created:%d\n",
7364 	     stats.points_to_sets_created);
7365 
7366   delete vi_for_tree;
7367   delete call_stmt_vars;
7368   bitmap_obstack_release (&pta_obstack);
7369   constraints.release ();
7370 
7371   for (i = 0; i < graph->size; i++)
7372     graph->complex[i].release ();
7373   free (graph->complex);
7374 
7375   free (graph->rep);
7376   free (graph->succs);
7377   free (graph->pe);
7378   free (graph->pe_rep);
7379   free (graph->indirect_cycles);
7380   free (graph);
7381 
7382   varmap.release ();
7383   variable_info_pool.release ();
7384   constraint_pool.release ();
7385 
7386   obstack_free (&fake_var_decl_obstack, NULL);
7387 
7388   delete final_solutions;
7389   obstack_free (&final_solutions_obstack, NULL);
7390 }
7391 
7392 struct vls_data
7393 {
7394   unsigned short clique;
7395   bool escaped_p;
7396   bitmap rvars;
7397 };
7398 
7399 /* Mark "other" loads and stores as belonging to CLIQUE and with
7400    base zero.  */
7401 
7402 static bool
visit_loadstore(gimple *,tree base,tree ref,void * data)7403 visit_loadstore (gimple *, tree base, tree ref, void *data)
7404 {
7405   unsigned short clique = ((vls_data *) data)->clique;
7406   bitmap rvars = ((vls_data *) data)->rvars;
7407   bool escaped_p = ((vls_data *) data)->escaped_p;
7408   if (TREE_CODE (base) == MEM_REF
7409       || TREE_CODE (base) == TARGET_MEM_REF)
7410     {
7411       tree ptr = TREE_OPERAND (base, 0);
7412       if (TREE_CODE (ptr) == SSA_NAME)
7413 	{
7414 	  /* For parameters, get at the points-to set for the actual parm
7415 	     decl.  */
7416 	  if (SSA_NAME_IS_DEFAULT_DEF (ptr)
7417 	      && (TREE_CODE (SSA_NAME_VAR (ptr)) == PARM_DECL
7418 		  || TREE_CODE (SSA_NAME_VAR (ptr)) == RESULT_DECL))
7419 	    ptr = SSA_NAME_VAR (ptr);
7420 
7421 	  /* We need to make sure 'ptr' doesn't include any of
7422 	     the restrict tags we added bases for in its points-to set.  */
7423 	  varinfo_t vi = lookup_vi_for_tree (ptr);
7424 	  if (! vi)
7425 	    return false;
7426 
7427 	  vi = get_varinfo (find (vi->id));
7428 	  if (bitmap_intersect_p (rvars, vi->solution)
7429 	      || (escaped_p && bitmap_bit_p (vi->solution, escaped_id)))
7430 	    return false;
7431 	}
7432 
7433       /* Do not overwrite existing cliques (that includes clique, base
7434          pairs we just set).  */
7435       if (MR_DEPENDENCE_CLIQUE (base) == 0)
7436 	{
7437 	  MR_DEPENDENCE_CLIQUE (base) = clique;
7438 	  MR_DEPENDENCE_BASE (base) = 0;
7439 	}
7440     }
7441 
7442   /* For plain decl accesses see whether they are accesses to globals
7443      and rewrite them to MEM_REFs with { clique, 0 }.  */
7444   if (VAR_P (base)
7445       && is_global_var (base)
7446       /* ???  We can't rewrite a plain decl with the walk_stmt_load_store
7447 	 ops callback.  */
7448       && base != ref)
7449     {
7450       tree *basep = &ref;
7451       while (handled_component_p (*basep))
7452 	basep = &TREE_OPERAND (*basep, 0);
7453       gcc_assert (VAR_P (*basep));
7454       tree ptr = build_fold_addr_expr (*basep);
7455       tree zero = build_int_cst (TREE_TYPE (ptr), 0);
7456       *basep = build2 (MEM_REF, TREE_TYPE (*basep), ptr, zero);
7457       MR_DEPENDENCE_CLIQUE (*basep) = clique;
7458       MR_DEPENDENCE_BASE (*basep) = 0;
7459     }
7460 
7461   return false;
7462 }
7463 
7464 /* If REF is a MEM_REF then assign a clique, base pair to it, updating
7465    CLIQUE, *RESTRICT_VAR and LAST_RUID.  Return whether dependence info
7466    was assigned to REF.  */
7467 
7468 static bool
maybe_set_dependence_info(tree ref,tree ptr,unsigned short & clique,varinfo_t restrict_var,unsigned short & last_ruid)7469 maybe_set_dependence_info (tree ref, tree ptr,
7470 			   unsigned short &clique, varinfo_t restrict_var,
7471 			   unsigned short &last_ruid)
7472 {
7473   while (handled_component_p (ref))
7474     ref = TREE_OPERAND (ref, 0);
7475   if ((TREE_CODE (ref) == MEM_REF
7476        || TREE_CODE (ref) == TARGET_MEM_REF)
7477       && TREE_OPERAND (ref, 0) == ptr)
7478     {
7479       /* Do not overwrite existing cliques.  This avoids overwriting dependence
7480 	 info inlined from a function with restrict parameters inlined
7481 	 into a function with restrict parameters.  This usually means we
7482 	 prefer to be precise in innermost loops.  */
7483       if (MR_DEPENDENCE_CLIQUE (ref) == 0)
7484 	{
7485 	  if (clique == 0)
7486 	    {
7487 	      if (cfun->last_clique == 0)
7488 		cfun->last_clique = 1;
7489 	      clique = 1;
7490 	    }
7491 	  if (restrict_var->ruid == 0)
7492 	    restrict_var->ruid = ++last_ruid;
7493 	  MR_DEPENDENCE_CLIQUE (ref) = clique;
7494 	  MR_DEPENDENCE_BASE (ref) = restrict_var->ruid;
7495 	  return true;
7496 	}
7497     }
7498   return false;
7499 }
7500 
7501 /* Clear dependence info for the clique DATA.  */
7502 
7503 static bool
clear_dependence_clique(gimple *,tree base,tree,void * data)7504 clear_dependence_clique (gimple *, tree base, tree, void *data)
7505 {
7506   unsigned short clique = (uintptr_t)data;
7507   if ((TREE_CODE (base) == MEM_REF
7508        || TREE_CODE (base) == TARGET_MEM_REF)
7509       && MR_DEPENDENCE_CLIQUE (base) == clique)
7510     {
7511       MR_DEPENDENCE_CLIQUE (base) = 0;
7512       MR_DEPENDENCE_BASE (base) = 0;
7513     }
7514 
7515   return false;
7516 }
7517 
7518 /* Compute the set of independend memory references based on restrict
7519    tags and their conservative propagation to the points-to sets.  */
7520 
7521 static void
compute_dependence_clique(void)7522 compute_dependence_clique (void)
7523 {
7524   /* First clear the special "local" clique.  */
7525   basic_block bb;
7526   if (cfun->last_clique != 0)
7527     FOR_EACH_BB_FN (bb, cfun)
7528       for (gimple_stmt_iterator gsi = gsi_start_bb (bb);
7529 	   !gsi_end_p (gsi); gsi_next (&gsi))
7530 	{
7531 	  gimple *stmt = gsi_stmt (gsi);
7532 	  walk_stmt_load_store_ops (stmt, (void *)(uintptr_t) 1,
7533 				    clear_dependence_clique,
7534 				    clear_dependence_clique);
7535 	}
7536 
7537   unsigned short clique = 0;
7538   unsigned short last_ruid = 0;
7539   bitmap rvars = BITMAP_ALLOC (NULL);
7540   bool escaped_p = false;
7541   for (unsigned i = 0; i < num_ssa_names; ++i)
7542     {
7543       tree ptr = ssa_name (i);
7544       if (!ptr || !POINTER_TYPE_P (TREE_TYPE (ptr)))
7545 	continue;
7546 
7547       /* Avoid all this when ptr is not dereferenced?  */
7548       tree p = ptr;
7549       if (SSA_NAME_IS_DEFAULT_DEF (ptr)
7550 	  && (TREE_CODE (SSA_NAME_VAR (ptr)) == PARM_DECL
7551 	      || TREE_CODE (SSA_NAME_VAR (ptr)) == RESULT_DECL))
7552 	p = SSA_NAME_VAR (ptr);
7553       varinfo_t vi = lookup_vi_for_tree (p);
7554       if (!vi)
7555 	continue;
7556       vi = get_varinfo (find (vi->id));
7557       bitmap_iterator bi;
7558       unsigned j;
7559       varinfo_t restrict_var = NULL;
7560       EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, j, bi)
7561 	{
7562 	  varinfo_t oi = get_varinfo (j);
7563 	  if (oi->is_restrict_var)
7564 	    {
7565 	      if (restrict_var)
7566 		{
7567 		  if (dump_file && (dump_flags & TDF_DETAILS))
7568 		    {
7569 		      fprintf (dump_file, "found restrict pointed-to "
7570 			       "for ");
7571 		      print_generic_expr (dump_file, ptr);
7572 		      fprintf (dump_file, " but not exclusively\n");
7573 		    }
7574 		  restrict_var = NULL;
7575 		  break;
7576 		}
7577 	      restrict_var = oi;
7578 	    }
7579 	  /* NULL is the only other valid points-to entry.  */
7580 	  else if (oi->id != nothing_id)
7581 	    {
7582 	      restrict_var = NULL;
7583 	      break;
7584 	    }
7585 	}
7586       /* Ok, found that ptr must(!) point to a single(!) restrict
7587 	 variable.  */
7588       /* ???  PTA isn't really a proper propagation engine to compute
7589 	 this property.
7590 	 ???  We could handle merging of two restricts by unifying them.  */
7591       if (restrict_var)
7592 	{
7593 	  /* Now look at possible dereferences of ptr.  */
7594 	  imm_use_iterator ui;
7595 	  gimple *use_stmt;
7596 	  bool used = false;
7597 	  FOR_EACH_IMM_USE_STMT (use_stmt, ui, ptr)
7598 	    {
7599 	      /* ???  Calls and asms.  */
7600 	      if (!gimple_assign_single_p (use_stmt))
7601 		continue;
7602 	      used |= maybe_set_dependence_info (gimple_assign_lhs (use_stmt),
7603 						 ptr, clique, restrict_var,
7604 						 last_ruid);
7605 	      used |= maybe_set_dependence_info (gimple_assign_rhs1 (use_stmt),
7606 						 ptr, clique, restrict_var,
7607 						 last_ruid);
7608 	    }
7609 	  if (used)
7610 	    {
7611 	      /* Add all subvars to the set of restrict pointed-to set. */
7612 	      for (unsigned sv = restrict_var->head; sv != 0;
7613 		   sv = get_varinfo (sv)->next)
7614 		bitmap_set_bit (rvars, sv);
7615 	      varinfo_t escaped = get_varinfo (find (escaped_id));
7616 	      if (bitmap_bit_p (escaped->solution, restrict_var->id))
7617 		escaped_p = true;
7618 	    }
7619 	}
7620     }
7621 
7622   if (clique != 0)
7623     {
7624       /* Assign the BASE id zero to all accesses not based on a restrict
7625 	 pointer.  That way they get disambiguated against restrict
7626 	 accesses but not against each other.  */
7627       /* ???  For restricts derived from globals (thus not incoming
7628 	 parameters) we can't restrict scoping properly thus the following
7629 	 is too aggressive there.  For now we have excluded those globals from
7630 	 getting into the MR_DEPENDENCE machinery.  */
7631       vls_data data = { clique, escaped_p, rvars };
7632       basic_block bb;
7633       FOR_EACH_BB_FN (bb, cfun)
7634 	for (gimple_stmt_iterator gsi = gsi_start_bb (bb);
7635 	     !gsi_end_p (gsi); gsi_next (&gsi))
7636 	  {
7637 	    gimple *stmt = gsi_stmt (gsi);
7638 	    walk_stmt_load_store_ops (stmt, &data,
7639 				      visit_loadstore, visit_loadstore);
7640 	  }
7641     }
7642 
7643   BITMAP_FREE (rvars);
7644 }
7645 
7646 /* Compute points-to information for every SSA_NAME pointer in the
7647    current function and compute the transitive closure of escaped
7648    variables to re-initialize the call-clobber states of local variables.  */
7649 
7650 unsigned int
compute_may_aliases(void)7651 compute_may_aliases (void)
7652 {
7653   if (cfun->gimple_df->ipa_pta)
7654     {
7655       if (dump_file)
7656 	{
7657 	  fprintf (dump_file, "\nNot re-computing points-to information "
7658 		   "because IPA points-to information is available.\n\n");
7659 
7660 	  /* But still dump what we have remaining it.  */
7661 	  dump_alias_info (dump_file);
7662 	}
7663 
7664       return 0;
7665     }
7666 
7667   /* For each pointer P_i, determine the sets of variables that P_i may
7668      point-to.  Compute the reachability set of escaped and call-used
7669      variables.  */
7670   compute_points_to_sets ();
7671 
7672   /* Debugging dumps.  */
7673   if (dump_file)
7674     dump_alias_info (dump_file);
7675 
7676   /* Compute restrict-based memory disambiguations.  */
7677   compute_dependence_clique ();
7678 
7679   /* Deallocate memory used by aliasing data structures and the internal
7680      points-to solution.  */
7681   delete_points_to_sets ();
7682 
7683   gcc_assert (!need_ssa_update_p (cfun));
7684 
7685   return 0;
7686 }
7687 
7688 /* A dummy pass to cause points-to information to be computed via
7689    TODO_rebuild_alias.  */
7690 
7691 namespace {
7692 
7693 const pass_data pass_data_build_alias =
7694 {
7695   GIMPLE_PASS, /* type */
7696   "alias", /* name */
7697   OPTGROUP_NONE, /* optinfo_flags */
7698   TV_NONE, /* tv_id */
7699   ( PROP_cfg | PROP_ssa ), /* properties_required */
7700   0, /* properties_provided */
7701   0, /* properties_destroyed */
7702   0, /* todo_flags_start */
7703   TODO_rebuild_alias, /* todo_flags_finish */
7704 };
7705 
7706 class pass_build_alias : public gimple_opt_pass
7707 {
7708 public:
pass_build_alias(gcc::context * ctxt)7709   pass_build_alias (gcc::context *ctxt)
7710     : gimple_opt_pass (pass_data_build_alias, ctxt)
7711   {}
7712 
7713   /* opt_pass methods: */
gate(function *)7714   virtual bool gate (function *) { return flag_tree_pta; }
7715 
7716 }; // class pass_build_alias
7717 
7718 } // anon namespace
7719 
7720 gimple_opt_pass *
make_pass_build_alias(gcc::context * ctxt)7721 make_pass_build_alias (gcc::context *ctxt)
7722 {
7723   return new pass_build_alias (ctxt);
7724 }
7725 
7726 /* A dummy pass to cause points-to information to be computed via
7727    TODO_rebuild_alias.  */
7728 
7729 namespace {
7730 
7731 const pass_data pass_data_build_ealias =
7732 {
7733   GIMPLE_PASS, /* type */
7734   "ealias", /* name */
7735   OPTGROUP_NONE, /* optinfo_flags */
7736   TV_NONE, /* tv_id */
7737   ( PROP_cfg | PROP_ssa ), /* properties_required */
7738   0, /* properties_provided */
7739   0, /* properties_destroyed */
7740   0, /* todo_flags_start */
7741   TODO_rebuild_alias, /* todo_flags_finish */
7742 };
7743 
7744 class pass_build_ealias : public gimple_opt_pass
7745 {
7746 public:
pass_build_ealias(gcc::context * ctxt)7747   pass_build_ealias (gcc::context *ctxt)
7748     : gimple_opt_pass (pass_data_build_ealias, ctxt)
7749   {}
7750 
7751   /* opt_pass methods: */
gate(function *)7752   virtual bool gate (function *) { return flag_tree_pta; }
7753 
7754 }; // class pass_build_ealias
7755 
7756 } // anon namespace
7757 
7758 gimple_opt_pass *
make_pass_build_ealias(gcc::context * ctxt)7759 make_pass_build_ealias (gcc::context *ctxt)
7760 {
7761   return new pass_build_ealias (ctxt);
7762 }
7763 
7764 
7765 /* IPA PTA solutions for ESCAPED.  */
7766 struct pt_solution ipa_escaped_pt
7767   = { true, false, false, false, false,
7768       false, false, false, false, false, NULL };
7769 
7770 /* Associate node with varinfo DATA. Worker for
7771    cgraph_for_symbol_thunks_and_aliases.  */
7772 static bool
associate_varinfo_to_alias(struct cgraph_node * node,void * data)7773 associate_varinfo_to_alias (struct cgraph_node *node, void *data)
7774 {
7775   if ((node->alias
7776        || (node->thunk.thunk_p
7777 	   && ! node->global.inlined_to))
7778       && node->analyzed)
7779     insert_vi_for_tree (node->decl, (varinfo_t)data);
7780   return false;
7781 }
7782 
7783 /* Dump varinfo VI to FILE.  */
7784 
7785 static void
dump_varinfo(FILE * file,varinfo_t vi)7786 dump_varinfo (FILE *file, varinfo_t vi)
7787 {
7788   if (vi == NULL)
7789     return;
7790 
7791   fprintf (file, "%u: %s\n", vi->id, vi->name);
7792 
7793   const char *sep = " ";
7794   if (vi->is_artificial_var)
7795     fprintf (file, "%sartificial", sep);
7796   if (vi->is_special_var)
7797     fprintf (file, "%sspecial", sep);
7798   if (vi->is_unknown_size_var)
7799     fprintf (file, "%sunknown-size", sep);
7800   if (vi->is_full_var)
7801     fprintf (file, "%sfull", sep);
7802   if (vi->is_heap_var)
7803     fprintf (file, "%sheap", sep);
7804   if (vi->may_have_pointers)
7805     fprintf (file, "%smay-have-pointers", sep);
7806   if (vi->only_restrict_pointers)
7807     fprintf (file, "%sonly-restrict-pointers", sep);
7808   if (vi->is_restrict_var)
7809     fprintf (file, "%sis-restrict-var", sep);
7810   if (vi->is_global_var)
7811     fprintf (file, "%sglobal", sep);
7812   if (vi->is_ipa_escape_point)
7813     fprintf (file, "%sipa-escape-point", sep);
7814   if (vi->is_fn_info)
7815     fprintf (file, "%sfn-info", sep);
7816   if (vi->ruid)
7817     fprintf (file, "%srestrict-uid:%u", sep, vi->ruid);
7818   if (vi->next)
7819     fprintf (file, "%snext:%u", sep, vi->next);
7820   if (vi->head != vi->id)
7821     fprintf (file, "%shead:%u", sep, vi->head);
7822   if (vi->offset)
7823     fprintf (file, "%soffset:" HOST_WIDE_INT_PRINT_DEC, sep, vi->offset);
7824   if (vi->size != ~(unsigned HOST_WIDE_INT)0)
7825     fprintf (file, "%ssize:" HOST_WIDE_INT_PRINT_DEC, sep, vi->size);
7826   if (vi->fullsize != ~(unsigned HOST_WIDE_INT)0
7827       && vi->fullsize != vi->size)
7828     fprintf (file, "%sfullsize:" HOST_WIDE_INT_PRINT_DEC, sep,
7829 	     vi->fullsize);
7830   fprintf (file, "\n");
7831 
7832   if (vi->solution && !bitmap_empty_p (vi->solution))
7833     {
7834       bitmap_iterator bi;
7835       unsigned i;
7836       fprintf (file, " solution: {");
7837       EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, i, bi)
7838 	fprintf (file, " %u", i);
7839       fprintf (file, " }\n");
7840     }
7841 
7842   if (vi->oldsolution && !bitmap_empty_p (vi->oldsolution)
7843       && !bitmap_equal_p (vi->solution, vi->oldsolution))
7844     {
7845       bitmap_iterator bi;
7846       unsigned i;
7847       fprintf (file, " oldsolution: {");
7848       EXECUTE_IF_SET_IN_BITMAP (vi->oldsolution, 0, i, bi)
7849 	fprintf (file, " %u", i);
7850       fprintf (file, " }\n");
7851     }
7852 }
7853 
7854 /* Dump varinfo VI to stderr.  */
7855 
7856 DEBUG_FUNCTION void
debug_varinfo(varinfo_t vi)7857 debug_varinfo (varinfo_t vi)
7858 {
7859   dump_varinfo (stderr, vi);
7860 }
7861 
7862 /* Dump varmap to FILE.  */
7863 
7864 static void
dump_varmap(FILE * file)7865 dump_varmap (FILE *file)
7866 {
7867   if (varmap.length () == 0)
7868     return;
7869 
7870   fprintf (file, "variables:\n");
7871 
7872   for (unsigned int i = 0; i < varmap.length (); ++i)
7873     {
7874       varinfo_t vi = get_varinfo (i);
7875       dump_varinfo (file, vi);
7876     }
7877 
7878   fprintf (file, "\n");
7879 }
7880 
7881 /* Dump varmap to stderr.  */
7882 
7883 DEBUG_FUNCTION void
debug_varmap(void)7884 debug_varmap (void)
7885 {
7886   dump_varmap (stderr);
7887 }
7888 
7889 /* Compute whether node is refered to non-locally.  Worker for
7890    cgraph_for_symbol_thunks_and_aliases.  */
7891 static bool
refered_from_nonlocal_fn(struct cgraph_node * node,void * data)7892 refered_from_nonlocal_fn (struct cgraph_node *node, void *data)
7893 {
7894   bool *nonlocal_p = (bool *)data;
7895   *nonlocal_p |= (node->used_from_other_partition
7896 		  || DECL_EXTERNAL (node->decl)
7897 		  || TREE_PUBLIC (node->decl)
7898 		  || node->force_output
7899 		  || lookup_attribute ("noipa", DECL_ATTRIBUTES (node->decl)));
7900   return false;
7901 }
7902 
7903 /* Same for varpool nodes.  */
7904 static bool
refered_from_nonlocal_var(struct varpool_node * node,void * data)7905 refered_from_nonlocal_var (struct varpool_node *node, void *data)
7906 {
7907   bool *nonlocal_p = (bool *)data;
7908   *nonlocal_p |= (node->used_from_other_partition
7909 		  || DECL_EXTERNAL (node->decl)
7910 		  || TREE_PUBLIC (node->decl)
7911 		  || node->force_output);
7912   return false;
7913 }
7914 
7915 /* Execute the driver for IPA PTA.  */
7916 static unsigned int
ipa_pta_execute(void)7917 ipa_pta_execute (void)
7918 {
7919   struct cgraph_node *node;
7920   varpool_node *var;
7921   unsigned int from = 0;
7922 
7923   in_ipa_mode = 1;
7924 
7925   init_alias_vars ();
7926 
7927   if (dump_file && (dump_flags & TDF_DETAILS))
7928     {
7929       symtab->dump (dump_file);
7930       fprintf (dump_file, "\n");
7931     }
7932 
7933   if (dump_file)
7934     {
7935       fprintf (dump_file, "Generating generic constraints\n\n");
7936       dump_constraints (dump_file, from);
7937       fprintf (dump_file, "\n");
7938       from = constraints.length ();
7939     }
7940 
7941   /* Build the constraints.  */
7942   FOR_EACH_DEFINED_FUNCTION (node)
7943     {
7944       varinfo_t vi;
7945       /* Nodes without a body are not interesting.  Especially do not
7946          visit clones at this point for now - we get duplicate decls
7947 	 there for inline clones at least.  */
7948       if (!node->has_gimple_body_p () || node->global.inlined_to)
7949 	continue;
7950       node->get_body ();
7951 
7952       gcc_assert (!node->clone_of);
7953 
7954       /* For externally visible or attribute used annotated functions use
7955 	 local constraints for their arguments.
7956 	 For local functions we see all callers and thus do not need initial
7957 	 constraints for parameters.  */
7958       bool nonlocal_p = (node->used_from_other_partition
7959 			 || DECL_EXTERNAL (node->decl)
7960 			 || TREE_PUBLIC (node->decl)
7961 			 || node->force_output
7962 			 || lookup_attribute ("noipa",
7963 					      DECL_ATTRIBUTES (node->decl)));
7964       node->call_for_symbol_thunks_and_aliases (refered_from_nonlocal_fn,
7965 						&nonlocal_p, true);
7966 
7967       vi = create_function_info_for (node->decl,
7968 				     alias_get_name (node->decl), false,
7969 				     nonlocal_p);
7970       if (dump_file
7971 	  && from != constraints.length ())
7972 	{
7973 	  fprintf (dump_file,
7974 		   "Generating intial constraints for %s", node->name ());
7975 	  if (DECL_ASSEMBLER_NAME_SET_P (node->decl))
7976 	    fprintf (dump_file, " (%s)",
7977 		     IDENTIFIER_POINTER
7978 		       (DECL_ASSEMBLER_NAME (node->decl)));
7979 	  fprintf (dump_file, "\n\n");
7980 	  dump_constraints (dump_file, from);
7981 	  fprintf (dump_file, "\n");
7982 
7983 	  from = constraints.length ();
7984 	}
7985 
7986       node->call_for_symbol_thunks_and_aliases
7987 	(associate_varinfo_to_alias, vi, true);
7988     }
7989 
7990   /* Create constraints for global variables and their initializers.  */
7991   FOR_EACH_VARIABLE (var)
7992     {
7993       if (var->alias && var->analyzed)
7994 	continue;
7995 
7996       varinfo_t vi = get_vi_for_tree (var->decl);
7997 
7998       /* For the purpose of IPA PTA unit-local globals are not
7999          escape points.  */
8000       bool nonlocal_p = (DECL_EXTERNAL (var->decl)
8001 			 || TREE_PUBLIC (var->decl)
8002 			 || var->used_from_other_partition
8003 			 || var->force_output);
8004       var->call_for_symbol_and_aliases (refered_from_nonlocal_var,
8005 					&nonlocal_p, true);
8006       if (nonlocal_p)
8007 	vi->is_ipa_escape_point = true;
8008     }
8009 
8010   if (dump_file
8011       && from != constraints.length ())
8012     {
8013       fprintf (dump_file,
8014 	       "Generating constraints for global initializers\n\n");
8015       dump_constraints (dump_file, from);
8016       fprintf (dump_file, "\n");
8017       from = constraints.length ();
8018     }
8019 
8020   FOR_EACH_DEFINED_FUNCTION (node)
8021     {
8022       struct function *func;
8023       basic_block bb;
8024 
8025       /* Nodes without a body are not interesting.  */
8026       if (!node->has_gimple_body_p () || node->clone_of)
8027 	continue;
8028 
8029       if (dump_file)
8030 	{
8031 	  fprintf (dump_file,
8032 		   "Generating constraints for %s", node->name ());
8033 	  if (DECL_ASSEMBLER_NAME_SET_P (node->decl))
8034 	    fprintf (dump_file, " (%s)",
8035 		     IDENTIFIER_POINTER
8036 		       (DECL_ASSEMBLER_NAME (node->decl)));
8037 	  fprintf (dump_file, "\n");
8038 	}
8039 
8040       func = DECL_STRUCT_FUNCTION (node->decl);
8041       gcc_assert (cfun == NULL);
8042 
8043       /* Build constriants for the function body.  */
8044       FOR_EACH_BB_FN (bb, func)
8045 	{
8046 	  for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
8047 	       gsi_next (&gsi))
8048 	    {
8049 	      gphi *phi = gsi.phi ();
8050 
8051 	      if (! virtual_operand_p (gimple_phi_result (phi)))
8052 		find_func_aliases (func, phi);
8053 	    }
8054 
8055 	  for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
8056 	       gsi_next (&gsi))
8057 	    {
8058 	      gimple *stmt = gsi_stmt (gsi);
8059 
8060 	      find_func_aliases (func, stmt);
8061 	      find_func_clobbers (func, stmt);
8062 	    }
8063 	}
8064 
8065       if (dump_file)
8066 	{
8067 	  fprintf (dump_file, "\n");
8068 	  dump_constraints (dump_file, from);
8069 	  fprintf (dump_file, "\n");
8070 	  from = constraints.length ();
8071 	}
8072     }
8073 
8074   /* From the constraints compute the points-to sets.  */
8075   solve_constraints ();
8076 
8077   /* Compute the global points-to sets for ESCAPED.
8078      ???  Note that the computed escape set is not correct
8079      for the whole unit as we fail to consider graph edges to
8080      externally visible functions.  */
8081   ipa_escaped_pt = find_what_var_points_to (NULL, get_varinfo (escaped_id));
8082 
8083   /* Make sure the ESCAPED solution (which is used as placeholder in
8084      other solutions) does not reference itself.  This simplifies
8085      points-to solution queries.  */
8086   ipa_escaped_pt.ipa_escaped = 0;
8087 
8088   /* Assign the points-to sets to the SSA names in the unit.  */
8089   FOR_EACH_DEFINED_FUNCTION (node)
8090     {
8091       tree ptr;
8092       struct function *fn;
8093       unsigned i;
8094       basic_block bb;
8095 
8096       /* Nodes without a body are not interesting.  */
8097       if (!node->has_gimple_body_p () || node->clone_of)
8098 	continue;
8099 
8100       fn = DECL_STRUCT_FUNCTION (node->decl);
8101 
8102       /* Compute the points-to sets for pointer SSA_NAMEs.  */
8103       FOR_EACH_VEC_ELT (*fn->gimple_df->ssa_names, i, ptr)
8104 	{
8105 	  if (ptr
8106 	      && POINTER_TYPE_P (TREE_TYPE (ptr)))
8107 	    find_what_p_points_to (node->decl, ptr);
8108 	}
8109 
8110       /* Compute the call-use and call-clobber sets for indirect calls
8111 	 and calls to external functions.  */
8112       FOR_EACH_BB_FN (bb, fn)
8113 	{
8114 	  gimple_stmt_iterator gsi;
8115 
8116 	  for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
8117 	    {
8118 	      gcall *stmt;
8119 	      struct pt_solution *pt;
8120 	      varinfo_t vi, fi;
8121 	      tree decl;
8122 
8123 	      stmt = dyn_cast <gcall *> (gsi_stmt (gsi));
8124 	      if (!stmt)
8125 		continue;
8126 
8127 	      /* Handle direct calls to functions with body.  */
8128 	      decl = gimple_call_fndecl (stmt);
8129 
8130 	      {
8131 		tree called_decl = NULL_TREE;
8132 		if (gimple_call_builtin_p (stmt, BUILT_IN_GOMP_PARALLEL))
8133 		  called_decl = TREE_OPERAND (gimple_call_arg (stmt, 0), 0);
8134 		else if (gimple_call_builtin_p (stmt, BUILT_IN_GOACC_PARALLEL))
8135 		  called_decl = TREE_OPERAND (gimple_call_arg (stmt, 1), 0);
8136 
8137 		if (called_decl != NULL_TREE
8138 		    && !fndecl_maybe_in_other_partition (called_decl))
8139 		  decl = called_decl;
8140 	      }
8141 
8142 	      if (decl
8143 		  && (fi = lookup_vi_for_tree (decl))
8144 		  && fi->is_fn_info)
8145 		{
8146 		  *gimple_call_clobber_set (stmt)
8147 		     = find_what_var_points_to
8148 		         (node->decl, first_vi_for_offset (fi, fi_clobbers));
8149 		  *gimple_call_use_set (stmt)
8150 		     = find_what_var_points_to
8151 		         (node->decl, first_vi_for_offset (fi, fi_uses));
8152 		}
8153 	      /* Handle direct calls to external functions.  */
8154 	      else if (decl)
8155 		{
8156 		  pt = gimple_call_use_set (stmt);
8157 		  if (gimple_call_flags (stmt) & ECF_CONST)
8158 		    memset (pt, 0, sizeof (struct pt_solution));
8159 		  else if ((vi = lookup_call_use_vi (stmt)) != NULL)
8160 		    {
8161 		      *pt = find_what_var_points_to (node->decl, vi);
8162 		      /* Escaped (and thus nonlocal) variables are always
8163 			 implicitly used by calls.  */
8164 		      /* ???  ESCAPED can be empty even though NONLOCAL
8165 			 always escaped.  */
8166 		      pt->nonlocal = 1;
8167 		      pt->ipa_escaped = 1;
8168 		    }
8169 		  else
8170 		    {
8171 		      /* If there is nothing special about this call then
8172 			 we have made everything that is used also escape.  */
8173 		      *pt = ipa_escaped_pt;
8174 		      pt->nonlocal = 1;
8175 		    }
8176 
8177 		  pt = gimple_call_clobber_set (stmt);
8178 		  if (gimple_call_flags (stmt) & (ECF_CONST|ECF_PURE|ECF_NOVOPS))
8179 		    memset (pt, 0, sizeof (struct pt_solution));
8180 		  else if ((vi = lookup_call_clobber_vi (stmt)) != NULL)
8181 		    {
8182 		      *pt = find_what_var_points_to (node->decl, vi);
8183 		      /* Escaped (and thus nonlocal) variables are always
8184 			 implicitly clobbered by calls.  */
8185 		      /* ???  ESCAPED can be empty even though NONLOCAL
8186 			 always escaped.  */
8187 		      pt->nonlocal = 1;
8188 		      pt->ipa_escaped = 1;
8189 		    }
8190 		  else
8191 		    {
8192 		      /* If there is nothing special about this call then
8193 			 we have made everything that is used also escape.  */
8194 		      *pt = ipa_escaped_pt;
8195 		      pt->nonlocal = 1;
8196 		    }
8197 		}
8198 	      /* Handle indirect calls.  */
8199 	      else if (!decl
8200 		       && (fi = get_fi_for_callee (stmt)))
8201 		{
8202 		  /* We need to accumulate all clobbers/uses of all possible
8203 		     callees.  */
8204 		  fi = get_varinfo (find (fi->id));
8205 		  /* If we cannot constrain the set of functions we'll end up
8206 		     calling we end up using/clobbering everything.  */
8207 		  if (bitmap_bit_p (fi->solution, anything_id)
8208 		      || bitmap_bit_p (fi->solution, nonlocal_id)
8209 		      || bitmap_bit_p (fi->solution, escaped_id))
8210 		    {
8211 		      pt_solution_reset (gimple_call_clobber_set (stmt));
8212 		      pt_solution_reset (gimple_call_use_set (stmt));
8213 		    }
8214 		  else
8215 		    {
8216 		      bitmap_iterator bi;
8217 		      unsigned i;
8218 		      struct pt_solution *uses, *clobbers;
8219 
8220 		      uses = gimple_call_use_set (stmt);
8221 		      clobbers = gimple_call_clobber_set (stmt);
8222 		      memset (uses, 0, sizeof (struct pt_solution));
8223 		      memset (clobbers, 0, sizeof (struct pt_solution));
8224 		      EXECUTE_IF_SET_IN_BITMAP (fi->solution, 0, i, bi)
8225 			{
8226 			  struct pt_solution sol;
8227 
8228 			  vi = get_varinfo (i);
8229 			  if (!vi->is_fn_info)
8230 			    {
8231 			      /* ???  We could be more precise here?  */
8232 			      uses->nonlocal = 1;
8233 			      uses->ipa_escaped = 1;
8234 			      clobbers->nonlocal = 1;
8235 			      clobbers->ipa_escaped = 1;
8236 			      continue;
8237 			    }
8238 
8239 			  if (!uses->anything)
8240 			    {
8241 			      sol = find_what_var_points_to
8242 				      (node->decl,
8243 				       first_vi_for_offset (vi, fi_uses));
8244 			      pt_solution_ior_into (uses, &sol);
8245 			    }
8246 			  if (!clobbers->anything)
8247 			    {
8248 			      sol = find_what_var_points_to
8249 				      (node->decl,
8250 				       first_vi_for_offset (vi, fi_clobbers));
8251 			      pt_solution_ior_into (clobbers, &sol);
8252 			    }
8253 			}
8254 		    }
8255 		}
8256 	    }
8257 	}
8258 
8259       fn->gimple_df->ipa_pta = true;
8260 
8261       /* We have to re-set the final-solution cache after each function
8262          because what is a "global" is dependent on function context.  */
8263       final_solutions->empty ();
8264       obstack_free (&final_solutions_obstack, NULL);
8265       gcc_obstack_init (&final_solutions_obstack);
8266     }
8267 
8268   delete_points_to_sets ();
8269 
8270   in_ipa_mode = 0;
8271 
8272   return 0;
8273 }
8274 
8275 namespace {
8276 
8277 const pass_data pass_data_ipa_pta =
8278 {
8279   SIMPLE_IPA_PASS, /* type */
8280   "pta", /* name */
8281   OPTGROUP_NONE, /* optinfo_flags */
8282   TV_IPA_PTA, /* tv_id */
8283   0, /* properties_required */
8284   0, /* properties_provided */
8285   0, /* properties_destroyed */
8286   0, /* todo_flags_start */
8287   0, /* todo_flags_finish */
8288 };
8289 
8290 class pass_ipa_pta : public simple_ipa_opt_pass
8291 {
8292 public:
pass_ipa_pta(gcc::context * ctxt)8293   pass_ipa_pta (gcc::context *ctxt)
8294     : simple_ipa_opt_pass (pass_data_ipa_pta, ctxt)
8295   {}
8296 
8297   /* opt_pass methods: */
gate(function *)8298   virtual bool gate (function *)
8299     {
8300       return (optimize
8301 	      && flag_ipa_pta
8302 	      /* Don't bother doing anything if the program has errors.  */
8303 	      && !seen_error ());
8304     }
8305 
clone()8306   opt_pass * clone () { return new pass_ipa_pta (m_ctxt); }
8307 
execute(function *)8308   virtual unsigned int execute (function *) { return ipa_pta_execute (); }
8309 
8310 }; // class pass_ipa_pta
8311 
8312 } // anon namespace
8313 
8314 simple_ipa_opt_pass *
make_pass_ipa_pta(gcc::context * ctxt)8315 make_pass_ipa_pta (gcc::context *ctxt)
8316 {
8317   return new pass_ipa_pta (ctxt);
8318 }
8319