Branch data Line data Source code
1 : : /* Constraint builder for tree based points-to analysis
2 : : Copyright (C) 2005-2025 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 "gimple-walk.h"
41 : : #include "varasm.h"
42 : : #include "stringpool.h"
43 : : #include "attribs.h"
44 : : #include "tree-ssa.h"
45 : : #include "tree-cfg.h"
46 : : #include "gimple-range.h"
47 : : #include "ipa-modref-tree.h"
48 : : #include "ipa-modref.h"
49 : : #include "attr-fnspec.h"
50 : :
51 : : #include "tree-ssa-structalias.h"
52 : : #include "gimple-ssa-pta-constraints.h"
53 : :
54 : : using namespace pointer_analysis;
55 : :
56 : : /* Map from trees to variable infos. */
57 : : static hash_map<tree, varinfo_t> *vi_for_tree;
58 : :
59 : : /* A map mapping call statements to per-stmt variables for uses
60 : : and clobbers specific to the call. */
61 : : static hash_map<gimple *, varinfo_t> *call_stmt_vars;
62 : :
63 : : static unsigned int create_variable_info_for (tree, const char *, bool);
64 : : static inline bool type_can_have_subvars (const_tree);
65 : : static void make_param_constraints (varinfo_t);
66 : :
67 : : /* Lookup or create the variable for the call statement CALL. */
68 : :
69 : : static varinfo_t
70 : 67854352 : get_call_vi (gcall *call)
71 : : {
72 : 67854352 : varinfo_t vi, vi2;
73 : :
74 : 67854352 : bool existed;
75 : 67854352 : varinfo_t *slot_p = &call_stmt_vars->get_or_insert (call, &existed);
76 : 67854352 : if (existed)
77 : 52078252 : return *slot_p;
78 : :
79 : 15776100 : vi = new_var_info (NULL_TREE, "CALLUSED", true);
80 : 15776100 : vi->offset = 0;
81 : 15776100 : vi->size = 1;
82 : 15776100 : vi->fullsize = 2;
83 : 15776100 : vi->is_full_var = true;
84 : 15776100 : vi->is_reg_var = true;
85 : :
86 : 15776100 : vi2 = new_var_info (NULL_TREE, "CALLCLOBBERED", true);
87 : 15776100 : vi2->offset = 1;
88 : 15776100 : vi2->size = 1;
89 : 15776100 : vi2->fullsize = 2;
90 : 15776100 : vi2->is_full_var = true;
91 : 15776100 : vi2->is_reg_var = true;
92 : :
93 : 15776100 : vi->next = vi2->id;
94 : :
95 : 15776100 : *slot_p = vi;
96 : 15776100 : return vi;
97 : : }
98 : :
99 : : /* Lookup or create the variable for the call statement CALL representing
100 : : the uses. */
101 : :
102 : : static varinfo_t
103 : 42491226 : get_call_use_vi (gcall *call)
104 : : {
105 : 0 : return get_call_vi (call);
106 : : }
107 : :
108 : : /* Lookup or create the variable for the call statement CALL representing
109 : : the clobbers. */
110 : :
111 : : static varinfo_t ATTRIBUTE_UNUSED
112 : 25363126 : get_call_clobber_vi (gcall *call)
113 : : {
114 : 25363126 : return vi_next (get_call_vi (call));
115 : : }
116 : :
117 : :
118 : : static void get_constraint_for_1 (tree, vec<ce_s> *, bool, bool);
119 : : static void get_constraint_for (tree, vec<ce_s> *);
120 : : static void get_constraint_for_rhs (tree, vec<ce_s> *);
121 : : static void do_deref (vec<ce_s> *);
122 : :
123 : : /* Allocator for 'constraints' vector. */
124 : :
125 : : static object_allocator<constraint> constraint_pool ("Constraint pool");
126 : :
127 : : /* Create a new constraint consisting of LHS and RHS expressions. */
128 : :
129 : : static constraint_t
130 : 442675270 : new_constraint (const struct constraint_expr lhs,
131 : : const struct constraint_expr rhs)
132 : : {
133 : 0 : constraint_t ret = constraint_pool.allocate ();
134 : 442675270 : ret->lhs = lhs;
135 : 442675270 : ret->rhs = rhs;
136 : 442675270 : return ret;
137 : : }
138 : :
139 : : /* Insert ID as the variable id for tree T in the vi_for_tree map. */
140 : :
141 : : static void
142 : 92020310 : insert_vi_for_tree (tree t, varinfo_t vi)
143 : : {
144 : 92020310 : gcc_assert (vi);
145 : 92020310 : bool existed = vi_for_tree->put (t, vi);
146 : 92020310 : gcc_assert (!existed);
147 : 92020310 : }
148 : :
149 : : /* Return a printable name for DECL. */
150 : :
151 : : static const char *
152 : 91036928 : alias_get_name (tree decl)
153 : : {
154 : 91036928 : const char *res = "NULL";
155 : 91036928 : if (dump_file)
156 : : {
157 : 3981 : char *temp = NULL;
158 : 3981 : if (TREE_CODE (decl) == SSA_NAME)
159 : : {
160 : 2257 : res = get_name (decl);
161 : 3701 : temp = xasprintf ("%s_%u", res ? res : "", SSA_NAME_VERSION (decl));
162 : : }
163 : 1724 : else if (HAS_DECL_ASSEMBLER_NAME_P (decl)
164 : 1724 : && DECL_ASSEMBLER_NAME_SET_P (decl))
165 : 756 : res = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME_RAW (decl));
166 : 968 : else if (DECL_P (decl))
167 : : {
168 : 968 : res = get_name (decl);
169 : 968 : if (!res)
170 : 4 : temp = xasprintf ("D.%u", DECL_UID (decl));
171 : : }
172 : :
173 : 3017 : if (temp)
174 : : {
175 : 2261 : res = ggc_strdup (temp);
176 : 2261 : free (temp);
177 : : }
178 : : }
179 : :
180 : 91036928 : return res;
181 : : }
182 : :
183 : : /* Find the variable id for tree T in the map.
184 : : If T doesn't exist in the map, create an entry for it and return it. */
185 : :
186 : : static varinfo_t
187 : 241726193 : get_vi_for_tree (tree t)
188 : : {
189 : 241726193 : varinfo_t *slot = vi_for_tree->get (t);
190 : 241726193 : if (slot == NULL)
191 : : {
192 : 81649745 : unsigned int id = create_variable_info_for (t, alias_get_name (t), false);
193 : 81649745 : return get_varinfo (id);
194 : : }
195 : :
196 : 160076448 : return *slot;
197 : : }
198 : :
199 : : /* Get a scalar constraint expression for a new temporary variable. */
200 : :
201 : : static struct constraint_expr
202 : 3109208 : new_scalar_tmp_constraint_exp (const char *name, bool add_id)
203 : : {
204 : 3109208 : struct constraint_expr tmp;
205 : 3109208 : varinfo_t vi;
206 : :
207 : 3109208 : vi = new_var_info (NULL_TREE, name, add_id);
208 : 3109208 : vi->offset = 0;
209 : 3109208 : vi->size = -1;
210 : 3109208 : vi->fullsize = -1;
211 : 3109208 : vi->is_full_var = 1;
212 : 3109208 : vi->is_reg_var = 1;
213 : :
214 : 3109208 : tmp.var = vi->id;
215 : 3109208 : tmp.type = SCALAR;
216 : 3109208 : tmp.offset = 0;
217 : :
218 : 3109208 : return tmp;
219 : : }
220 : :
221 : : /* Get a constraint expression vector from an SSA_VAR_P node.
222 : : If address_p is true, the result will be taken its address of. */
223 : :
224 : : static void
225 : 221723235 : get_constraint_for_ssa_var (tree t, vec<ce_s> *results, bool address_p)
226 : : {
227 : 221723235 : struct constraint_expr cexpr;
228 : 221723235 : varinfo_t vi;
229 : :
230 : : /* We allow FUNCTION_DECLs here even though it doesn't make much sense. */
231 : 221723235 : gcc_assert (TREE_CODE (t) == SSA_NAME || DECL_P (t));
232 : :
233 : 221723235 : if (TREE_CODE (t) == SSA_NAME
234 : 221723235 : && SSA_NAME_IS_DEFAULT_DEF (t))
235 : : {
236 : : /* For parameters, get at the points-to set for the actual parm
237 : : decl. */
238 : 18091283 : if (TREE_CODE (SSA_NAME_VAR (t)) == PARM_DECL
239 : 18091283 : || TREE_CODE (SSA_NAME_VAR (t)) == RESULT_DECL)
240 : : {
241 : 17837767 : get_constraint_for_ssa_var (SSA_NAME_VAR (t), results, address_p);
242 : 41945360 : return;
243 : : }
244 : : /* For undefined SSA names return nothing. */
245 : 253516 : else if (!ssa_defined_default_def_p (t))
246 : : {
247 : 253516 : cexpr.var = nothing_id;
248 : 253516 : cexpr.type = SCALAR;
249 : 253516 : cexpr.offset = 0;
250 : 253516 : results->safe_push (cexpr);
251 : 253516 : return;
252 : : }
253 : : }
254 : :
255 : : /* For global variables resort to the alias target. */
256 : 203631952 : if (VAR_P (t) && (TREE_STATIC (t) || DECL_EXTERNAL (t)))
257 : : {
258 : 11202725 : varpool_node *node = varpool_node::get (t);
259 : 11202725 : if (node && node->alias && node->analyzed)
260 : : {
261 : 17238 : node = node->ultimate_alias_target ();
262 : : /* Canonicalize the PT uid of all aliases to the ultimate target.
263 : : ??? Hopefully the set of aliases can't change in a way that
264 : : changes the ultimate alias target. */
265 : 17238 : gcc_assert ((! DECL_PT_UID_SET_P (node->decl)
266 : : || DECL_PT_UID (node->decl) == DECL_UID (node->decl))
267 : : && (! DECL_PT_UID_SET_P (t)
268 : : || DECL_PT_UID (t) == DECL_UID (node->decl)));
269 : 17238 : DECL_PT_UID (t) = DECL_UID (node->decl);
270 : 17238 : t = node->decl;
271 : : }
272 : :
273 : : /* If this is decl may bind to NULL note that. */
274 : 11202725 : if (address_p
275 : 11202725 : && (! node || ! node->nonzero_address ()))
276 : : {
277 : 9024 : cexpr.var = nothing_id;
278 : 9024 : cexpr.type = SCALAR;
279 : 9024 : cexpr.offset = 0;
280 : 9024 : results->safe_push (cexpr);
281 : : }
282 : : }
283 : :
284 : 203631952 : vi = get_vi_for_tree (t);
285 : 203631952 : cexpr.var = vi->id;
286 : 203631952 : cexpr.type = SCALAR;
287 : 203631952 : cexpr.offset = 0;
288 : :
289 : : /* If we are not taking the address of the constraint expr, add all
290 : : sub-fiels of the variable as well. */
291 : 203631952 : if (!address_p
292 : 166251087 : && !vi->is_full_var)
293 : : {
294 : 20268929 : for (; vi; vi = vi_next (vi))
295 : : {
296 : 14252619 : cexpr.var = vi->id;
297 : 14252619 : results->safe_push (cexpr);
298 : : }
299 : : return;
300 : : }
301 : :
302 : 197615642 : results->safe_push (cexpr);
303 : : }
304 : :
305 : : /* Process constraint T, performing various simplifications and then
306 : : adding it to our list of overall constraints. */
307 : :
308 : : static void
309 : 438215450 : process_constraint (constraint_t t)
310 : : {
311 : 438215450 : struct constraint_expr rhs = t->rhs;
312 : 438215450 : struct constraint_expr lhs = t->lhs;
313 : :
314 : 438215450 : gcc_assert (rhs.var < varmap.length ());
315 : 438215450 : gcc_assert (lhs.var < varmap.length ());
316 : :
317 : : /* If we didn't get any useful constraint from the lhs we get
318 : : &ANYTHING as fallback from get_constraint_for. Deal with
319 : : it here by turning it into *ANYTHING. */
320 : 438215450 : if (lhs.type == ADDRESSOF
321 : 0 : && lhs.var == anything_id)
322 : 0 : t->lhs.type = lhs.type = DEREF;
323 : :
324 : : /* ADDRESSOF on the lhs is invalid. */
325 : 438215450 : gcc_assert (lhs.type != ADDRESSOF);
326 : :
327 : : /* We shouldn't add constraints from things that cannot have pointers.
328 : : It's not completely trivial to avoid in the callers, so do it here. */
329 : 438215450 : if (rhs.type != ADDRESSOF
330 : 438215450 : && !get_varinfo (rhs.var)->may_have_pointers)
331 : 438215450 : return;
332 : :
333 : : /* Likewise adding to the solution of a non-pointer var isn't useful. */
334 : 437836572 : if (!get_varinfo (lhs.var)->may_have_pointers)
335 : : return;
336 : :
337 : : /* This can happen in our IR with things like n->a = *p. */
338 : 437834841 : if (rhs.type == DEREF && lhs.type == DEREF && rhs.var != anything_id)
339 : : {
340 : : /* Split into tmp = *rhs, *lhs = tmp. */
341 : 285496 : struct constraint_expr tmplhs;
342 : 285496 : tmplhs = new_scalar_tmp_constraint_exp ("doubledereftmp", true);
343 : 285496 : process_constraint (new_constraint (tmplhs, rhs));
344 : 285496 : process_constraint (new_constraint (lhs, tmplhs));
345 : 285496 : }
346 : 437549345 : else if ((rhs.type != SCALAR || rhs.offset != 0) && lhs.type == DEREF)
347 : : {
348 : : /* Split into tmp = &rhs, *lhs = tmp. */
349 : 2001252 : struct constraint_expr tmplhs;
350 : 2001252 : tmplhs = new_scalar_tmp_constraint_exp ("derefaddrtmp", true);
351 : 2001252 : process_constraint (new_constraint (tmplhs, rhs));
352 : 2001252 : process_constraint (new_constraint (lhs, tmplhs));
353 : 2001252 : }
354 : : else
355 : : {
356 : 435548093 : gcc_assert (rhs.type != ADDRESSOF || rhs.offset == 0);
357 : 435548093 : if (rhs.type == ADDRESSOF)
358 : 85457694 : get_varinfo (get_varinfo (rhs.var)->head)->address_taken = true;
359 : 435548093 : constraints.safe_push (t);
360 : : }
361 : : }
362 : :
363 : :
364 : : /* Return the position, in bits, of FIELD_DECL from the beginning of its
365 : : structure. */
366 : :
367 : : static unsigned HOST_WIDE_INT
368 : 39970044 : bitpos_of_field (const tree fdecl)
369 : : {
370 : 39970044 : if (!tree_fits_uhwi_p (DECL_FIELD_OFFSET (fdecl))
371 : 39970044 : || !tree_fits_uhwi_p (DECL_FIELD_BIT_OFFSET (fdecl)))
372 : : return -1;
373 : :
374 : 39970044 : return (tree_to_uhwi (DECL_FIELD_OFFSET (fdecl)) * BITS_PER_UNIT
375 : 39970044 : + tree_to_uhwi (DECL_FIELD_BIT_OFFSET (fdecl)));
376 : : }
377 : :
378 : :
379 : : /* Get constraint expressions for offsetting PTR by OFFSET. Stores the
380 : : resulting constraint expressions in *RESULTS. */
381 : :
382 : : static void
383 : 40550766 : get_constraint_for_ptr_offset (tree ptr, tree offset,
384 : : vec<ce_s> *results)
385 : : {
386 : 40550766 : struct constraint_expr c;
387 : 40550766 : unsigned int j, n;
388 : 40550766 : HOST_WIDE_INT rhsoffset;
389 : :
390 : : /* If we do not do field-sensitive PTA adding offsets to pointers
391 : : does not change the points-to solution. */
392 : 40550766 : if (!use_field_sensitive)
393 : : {
394 : 1981255 : get_constraint_for_rhs (ptr, results);
395 : 1981255 : return;
396 : : }
397 : :
398 : : /* If the offset is not a non-negative integer constant that fits
399 : : in a HOST_WIDE_INT, we have to fall back to a conservative
400 : : solution which includes all sub-fields of all pointed-to
401 : : variables of ptr. */
402 : 38569511 : if (offset == NULL_TREE
403 : 13860746 : || TREE_CODE (offset) != INTEGER_CST)
404 : : rhsoffset = UNKNOWN_OFFSET;
405 : : else
406 : : {
407 : : /* Sign-extend the offset. */
408 : 11929925 : offset_int soffset = offset_int::from (wi::to_wide (offset), SIGNED);
409 : 11929925 : if (!wi::fits_shwi_p (soffset))
410 : : rhsoffset = UNKNOWN_OFFSET;
411 : : else
412 : : {
413 : : /* Make sure the bit-offset also fits. */
414 : 11929925 : HOST_WIDE_INT rhsunitoffset = soffset.to_shwi ();
415 : 11929925 : rhsoffset = rhsunitoffset * (unsigned HOST_WIDE_INT) BITS_PER_UNIT;
416 : 11929925 : if (rhsunitoffset != rhsoffset / BITS_PER_UNIT)
417 : 358 : rhsoffset = UNKNOWN_OFFSET;
418 : : }
419 : : }
420 : :
421 : 38569511 : get_constraint_for_rhs (ptr, results);
422 : 38569511 : if (rhsoffset == 0)
423 : : return;
424 : :
425 : : /* As we are eventually appending to the solution do not use
426 : : vec::iterate here. */
427 : 32360390 : n = results->length ();
428 : 64720966 : for (j = 0; j < n; j++)
429 : : {
430 : 32360576 : varinfo_t curr;
431 : 32360576 : c = (*results)[j];
432 : 32360576 : curr = get_varinfo (c.var);
433 : :
434 : 32360576 : if (c.type == ADDRESSOF
435 : : /* If this varinfo represents a full variable just use it. */
436 : 10681234 : && curr->is_full_var)
437 : : ;
438 : 24172501 : else if (c.type == ADDRESSOF
439 : : /* If we do not know the offset add all subfields. */
440 : 2493159 : && rhsoffset == UNKNOWN_OFFSET)
441 : : {
442 : 27650 : varinfo_t temp = get_varinfo (curr->head);
443 : 151495 : do
444 : : {
445 : 151495 : struct constraint_expr c2;
446 : 151495 : c2.var = temp->id;
447 : 151495 : c2.type = ADDRESSOF;
448 : 151495 : c2.offset = 0;
449 : 151495 : if (c2.var != c.var)
450 : 123845 : results->safe_push (c2);
451 : 151495 : temp = vi_next (temp);
452 : : }
453 : 151495 : while (temp);
454 : : }
455 : 24144851 : else if (c.type == ADDRESSOF)
456 : : {
457 : 2465509 : varinfo_t temp;
458 : 2465509 : unsigned HOST_WIDE_INT offset = curr->offset + rhsoffset;
459 : :
460 : : /* If curr->offset + rhsoffset is less than zero adjust it. */
461 : 2465509 : if (rhsoffset < 0
462 : 0 : && curr->offset < offset)
463 : 2465509 : offset = 0;
464 : :
465 : : /* We have to include all fields that overlap the current
466 : : field shifted by rhsoffset. And we include at least
467 : : the last or the first field of the variable to represent
468 : : reachability of off-bound addresses, in particular &object + 1,
469 : : conservatively correct. */
470 : 2465509 : temp = first_or_preceding_vi_for_offset (curr, offset);
471 : 2465509 : c.var = temp->id;
472 : 2465509 : c.offset = 0;
473 : 2465509 : temp = vi_next (temp);
474 : 2465509 : while (temp
475 : 2592710 : && temp->offset < offset + curr->size)
476 : : {
477 : 127201 : struct constraint_expr c2;
478 : 127201 : c2.var = temp->id;
479 : 127201 : c2.type = ADDRESSOF;
480 : 127201 : c2.offset = 0;
481 : 127201 : results->safe_push (c2);
482 : 127201 : temp = vi_next (temp);
483 : : }
484 : : }
485 : 21679342 : else if (c.type == SCALAR)
486 : : {
487 : 21679342 : gcc_assert (c.offset == 0);
488 : : c.offset = rhsoffset;
489 : : }
490 : : else
491 : : /* We shouldn't get any DEREFs here. */
492 : 0 : gcc_unreachable ();
493 : :
494 : 32360576 : (*results)[j] = c;
495 : : }
496 : : }
497 : :
498 : :
499 : : /* Given a COMPONENT_REF T, return the constraint_expr vector for it.
500 : : If address_p is true the result will be taken its address of.
501 : : If lhs_p is true then the constraint expression is assumed to be used
502 : : as the lhs. */
503 : :
504 : : static void
505 : 32063044 : get_constraint_for_component_ref (tree t, vec<ce_s> *results,
506 : : bool address_p, bool lhs_p)
507 : : {
508 : 32063044 : tree orig_t = t;
509 : 32063044 : poly_int64 bitsize = -1;
510 : 32063044 : poly_int64 bitmaxsize = -1;
511 : 32063044 : poly_int64 bitpos;
512 : 32063044 : bool reverse;
513 : 32063044 : tree forzero;
514 : :
515 : : /* Some people like to do cute things like take the address of
516 : : &0->a.b. */
517 : 32063044 : forzero = t;
518 : 32063044 : while (handled_component_p (forzero)
519 : 47178243 : || INDIRECT_REF_P (forzero)
520 : 140706102 : || TREE_CODE (forzero) == MEM_REF)
521 : 61464815 : forzero = TREE_OPERAND (forzero, 0);
522 : :
523 : 32063044 : if (CONSTANT_CLASS_P (forzero) && integer_zerop (forzero))
524 : : {
525 : 1717 : struct constraint_expr temp;
526 : :
527 : 1717 : temp.offset = 0;
528 : 1717 : temp.var = integer_id;
529 : 1717 : temp.type = SCALAR;
530 : 1717 : results->safe_push (temp);
531 : 1717 : return;
532 : : }
533 : :
534 : 32061327 : t = get_ref_base_and_extent (t, &bitpos, &bitsize, &bitmaxsize, &reverse);
535 : :
536 : : /* We can end up here for component references on a
537 : : VIEW_CONVERT_EXPR <>(&foobar) or things like a
538 : : BIT_FIELD_REF <&MEM[(void *)&b + 4B], ...>. So for
539 : : symbolic constants simply give up. */
540 : 32061327 : if (TREE_CODE (t) == ADDR_EXPR)
541 : : {
542 : 10 : constraint_expr result;
543 : 10 : result.type = SCALAR;
544 : 10 : result.var = anything_id;
545 : 10 : result.offset = 0;
546 : 10 : results->safe_push (result);
547 : 10 : return;
548 : : }
549 : :
550 : : /* Avoid creating pointer-offset constraints, so handle MEM_REF
551 : : offsets directly. Pretend to take the address of the base,
552 : : we'll take care of adding the required subset of sub-fields below. */
553 : 32061317 : if (TREE_CODE (t) == MEM_REF
554 : 32061317 : && !integer_zerop (TREE_OPERAND (t, 0)))
555 : : {
556 : 11855479 : poly_offset_int off = mem_ref_offset (t);
557 : 11855479 : off <<= LOG2_BITS_PER_UNIT;
558 : 11855479 : off += bitpos;
559 : 11855479 : poly_int64 off_hwi;
560 : 11855479 : if (off.to_shwi (&off_hwi))
561 : 11855477 : bitpos = off_hwi;
562 : : else
563 : : {
564 : 2 : bitpos = 0;
565 : 2 : bitmaxsize = -1;
566 : : }
567 : 11855479 : get_constraint_for_1 (TREE_OPERAND (t, 0), results, false, lhs_p);
568 : 11855479 : do_deref (results);
569 : : }
570 : : else
571 : 20205838 : get_constraint_for_1 (t, results, true, lhs_p);
572 : :
573 : : /* Strip off nothing_id. */
574 : 32061317 : if (results->length () == 2)
575 : : {
576 : 8074 : gcc_assert ((*results)[0].var == nothing_id);
577 : 8074 : results->unordered_remove (0);
578 : : }
579 : 32061317 : gcc_assert (results->length () == 1);
580 : 32061317 : struct constraint_expr &result = results->last ();
581 : :
582 : 32061317 : if (result.type == SCALAR
583 : 32061317 : && get_varinfo (result.var)->is_full_var)
584 : : /* For single-field vars do not bother about the offset. */
585 : 8327530 : result.offset = 0;
586 : 23733787 : else if (result.type == SCALAR)
587 : : {
588 : : /* In languages like C, you can access one past the end of an
589 : : array. You aren't allowed to dereference it, so we can
590 : : ignore this constraint. When we handle pointer subtraction,
591 : : we may have to do something cute here. */
592 : :
593 : 11878383 : if (maybe_lt (poly_uint64 (bitpos), get_varinfo (result.var)->fullsize)
594 : 11878383 : && maybe_ne (bitmaxsize, 0))
595 : : {
596 : : /* It's also not true that the constraint will actually start at the
597 : : right offset, it may start in some padding. We only care about
598 : : setting the constraint to the first actual field it touches, so
599 : : walk to find it. */
600 : 11868984 : struct constraint_expr cexpr = result;
601 : 11868984 : varinfo_t curr;
602 : 11868984 : results->pop ();
603 : 11868984 : cexpr.offset = 0;
604 : 62269801 : for (curr = get_varinfo (cexpr.var); curr; curr = vi_next (curr))
605 : : {
606 : 51263166 : if (ranges_maybe_overlap_p (poly_int64 (curr->offset),
607 : 51263166 : curr->size, bitpos, bitmaxsize))
608 : : {
609 : 12110945 : cexpr.var = curr->id;
610 : 12110945 : results->safe_push (cexpr);
611 : 12110945 : if (address_p)
612 : : break;
613 : : }
614 : : }
615 : : /* If we are going to take the address of this field then
616 : : to be able to compute reachability correctly add at least
617 : : the last field of the variable. */
618 : 12731357 : if (address_p && results->length () == 0)
619 : : {
620 : 24 : curr = get_varinfo (cexpr.var);
621 : 64 : while (curr->next != 0)
622 : 40 : curr = vi_next (curr);
623 : 24 : cexpr.var = curr->id;
624 : 24 : results->safe_push (cexpr);
625 : : }
626 : 11868960 : else if (results->length () == 0)
627 : : /* Assert that we found *some* field there. The user couldn't be
628 : : accessing *only* padding. */
629 : : /* Still the user could access one past the end of an array
630 : : embedded in a struct resulting in accessing *only* padding. */
631 : : /* Or accessing only padding via type-punning to a type
632 : : that has a filed just in padding space. */
633 : : {
634 : 18 : cexpr.type = SCALAR;
635 : 18 : cexpr.var = anything_id;
636 : 18 : cexpr.offset = 0;
637 : 18 : results->safe_push (cexpr);
638 : : }
639 : : }
640 : 9399 : else if (known_eq (bitmaxsize, 0))
641 : : {
642 : 9182 : if (dump_file && (dump_flags & TDF_DETAILS))
643 : 0 : fprintf (dump_file, "Access to zero-sized part of variable, "
644 : : "ignoring\n");
645 : : }
646 : : else
647 : 217 : if (dump_file && (dump_flags & TDF_DETAILS))
648 : 0 : fprintf (dump_file, "Access to past the end of variable, ignoring\n");
649 : : }
650 : 11855404 : else if (result.type == DEREF)
651 : : {
652 : : /* If we do not know exactly where the access goes say so. Note
653 : : that only for non-structure accesses we know that we access
654 : : at most one subfiled of any variable. */
655 : 11855353 : HOST_WIDE_INT const_bitpos;
656 : 11855353 : if (!bitpos.is_constant (&const_bitpos)
657 : 11855353 : || const_bitpos == -1
658 : 11855353 : || maybe_ne (bitsize, bitmaxsize)
659 : 11189519 : || AGGREGATE_TYPE_P (TREE_TYPE (orig_t))
660 : 9525370 : || result.offset == UNKNOWN_OFFSET)
661 : 2329983 : result.offset = UNKNOWN_OFFSET;
662 : : else
663 : 9525370 : result.offset += const_bitpos;
664 : : }
665 : 51 : else if (result.type == ADDRESSOF)
666 : : {
667 : : /* We can end up here for component references on constants like
668 : : VIEW_CONVERT_EXPR <>({ 0, 1, 2, 3 })[i]. */
669 : 51 : result.type = SCALAR;
670 : 51 : result.var = anything_id;
671 : 51 : result.offset = 0;
672 : : }
673 : : else
674 : 0 : gcc_unreachable ();
675 : : }
676 : :
677 : :
678 : : /* Dereference the constraint expression CONS, and return the result.
679 : : DEREF (ADDRESSOF) = SCALAR
680 : : DEREF (SCALAR) = DEREF
681 : : DEREF (DEREF) = (temp = DEREF1; result = DEREF (temp))
682 : : This is needed so that we can handle dereferencing DEREF constraints. */
683 : :
684 : : static void
685 : 24038470 : do_deref (vec<ce_s> *constraints)
686 : : {
687 : 24038470 : struct constraint_expr *c;
688 : 24038470 : unsigned int i = 0;
689 : :
690 : 48239893 : FOR_EACH_VEC_ELT (*constraints, i, c)
691 : : {
692 : 24201423 : if (c->type == SCALAR)
693 : 18180161 : c->type = DEREF;
694 : 6021262 : else if (c->type == ADDRESSOF)
695 : 6021256 : c->type = SCALAR;
696 : 6 : else if (c->type == DEREF)
697 : : {
698 : 6 : struct constraint_expr tmplhs;
699 : 6 : tmplhs = new_scalar_tmp_constraint_exp ("dereftmp", true);
700 : 6 : process_constraint (new_constraint (tmplhs, *c));
701 : 6 : c->var = tmplhs.var;
702 : : }
703 : : else
704 : 0 : gcc_unreachable ();
705 : : }
706 : 24038470 : }
707 : :
708 : : /* Given a tree T, return the constraint expression for taking the
709 : : address of it. */
710 : :
711 : : static void
712 : 28064441 : get_constraint_for_address_of (tree t, vec<ce_s> *results)
713 : : {
714 : 28064441 : struct constraint_expr *c;
715 : 28064441 : unsigned int i;
716 : :
717 : 28064441 : get_constraint_for_1 (t, results, true, true);
718 : :
719 : 84196543 : FOR_EACH_VEC_ELT (*results, i, c)
720 : : {
721 : 28067661 : if (c->type == DEREF)
722 : 1618820 : c->type = SCALAR;
723 : : else
724 : 26448841 : c->type = ADDRESSOF;
725 : : }
726 : 28064441 : }
727 : :
728 : : /* Given a tree T, return the constraint expression for it. */
729 : :
730 : : static void
731 : 318100043 : get_constraint_for_1 (tree t, vec<ce_s> *results, bool address_p,
732 : : bool lhs_p)
733 : : {
734 : 318100043 : struct constraint_expr temp;
735 : :
736 : : /* x = integer is all glommed to a single variable, which doesn't
737 : : point to anything by itself. That is, of course, unless it is an
738 : : integer constant being treated as a pointer, in which case, we
739 : : will return that this is really the addressof anything. This
740 : : happens below, since it will fall into the default case. The only
741 : : case we know something about an integer treated like a pointer is
742 : : when it is the NULL pointer, and then we just say it points to
743 : : NULL.
744 : :
745 : : Do not do that if -fno-delete-null-pointer-checks though, because
746 : : in that case *NULL does not fail, so it _should_ alias *anything.
747 : : It is not worth adding a new option or renaming the existing one,
748 : : since this case is relatively obscure. */
749 : 318100043 : if ((TREE_CODE (t) == INTEGER_CST
750 : 32401454 : && integer_zerop (t))
751 : : /* The only valid CONSTRUCTORs in gimple with pointer typed
752 : : elements are zero-initializer. But in IPA mode we also
753 : : process global initializers, so verify at least. */
754 : 339821375 : || (TREE_CODE (t) == CONSTRUCTOR
755 : 558859 : && CONSTRUCTOR_NELTS (t) == 0))
756 : : {
757 : 11191795 : if (flag_delete_null_pointer_checks)
758 : 11171774 : temp.var = nothing_id;
759 : : else
760 : 20021 : temp.var = nonlocal_id;
761 : 11191795 : temp.type = ADDRESSOF;
762 : 11191795 : temp.offset = 0;
763 : 11191795 : results->safe_push (temp);
764 : 328437180 : return;
765 : : }
766 : :
767 : : /* String constants are read-only, ideally we'd have a CONST_DECL
768 : : for those. */
769 : 306908248 : if (TREE_CODE (t) == STRING_CST)
770 : : {
771 : 6412186 : temp.var = string_id;
772 : 6412186 : temp.type = SCALAR;
773 : 6412186 : temp.offset = 0;
774 : 6412186 : results->safe_push (temp);
775 : 6412186 : return;
776 : : }
777 : :
778 : 300496062 : switch (TREE_CODE_CLASS (TREE_CODE (t)))
779 : : {
780 : 27884842 : case tcc_expression:
781 : 27884842 : {
782 : 27884842 : switch (TREE_CODE (t))
783 : : {
784 : 27824063 : case ADDR_EXPR:
785 : 27824063 : get_constraint_for_address_of (TREE_OPERAND (t, 0), results);
786 : 27824063 : return;
787 : : default:;
788 : : }
789 : : break;
790 : : }
791 : 44511761 : case tcc_reference:
792 : 44511761 : {
793 : 44511761 : if (!lhs_p && TREE_THIS_VOLATILE (t))
794 : : /* Fall back to anything. */
795 : : break;
796 : :
797 : 44405952 : switch (TREE_CODE (t))
798 : : {
799 : 11526079 : case MEM_REF:
800 : 11526079 : {
801 : 11526079 : struct constraint_expr cs;
802 : 11526079 : varinfo_t vi, curr;
803 : 11526079 : get_constraint_for_ptr_offset (TREE_OPERAND (t, 0),
804 : 11526079 : TREE_OPERAND (t, 1), results);
805 : 11526079 : do_deref (results);
806 : :
807 : : /* If we are not taking the address then make sure to process
808 : : all subvariables we might access. */
809 : 11526079 : if (address_p)
810 : : return;
811 : :
812 : 10834701 : cs = results->last ();
813 : 10834701 : if (cs.type == DEREF
814 : 10834701 : && type_can_have_subvars (TREE_TYPE (t)))
815 : : {
816 : : /* For dereferences this means we have to defer it
817 : : to solving time. */
818 : 571724 : results->last ().offset = UNKNOWN_OFFSET;
819 : 571724 : return;
820 : : }
821 : 10262977 : if (cs.type != SCALAR)
822 : : return;
823 : :
824 : 5011628 : vi = get_varinfo (cs.var);
825 : 5011628 : curr = vi_next (vi);
826 : 5011628 : if (!vi->is_full_var
827 : 3973281 : && curr)
828 : : {
829 : 2591156 : unsigned HOST_WIDE_INT size;
830 : 2591156 : if (tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (t))))
831 : 2591156 : size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (t)));
832 : : else
833 : 2591156 : size = -1;
834 : 5208212 : for (; curr; curr = vi_next (curr))
835 : : {
836 : : /* The start of the access might happen anywhere
837 : : within vi, so conservatively assume it was
838 : : at its end. */
839 : 3537808 : if (curr->offset - (vi->offset + vi->size - 1) < size)
840 : : {
841 : 2617056 : cs.var = curr->id;
842 : 2617056 : results->safe_push (cs);
843 : : }
844 : : else
845 : : break;
846 : : }
847 : : }
848 : : return;
849 : : }
850 : 32063044 : case ARRAY_REF:
851 : 32063044 : case ARRAY_RANGE_REF:
852 : 32063044 : case COMPONENT_REF:
853 : 32063044 : case IMAGPART_EXPR:
854 : 32063044 : case REALPART_EXPR:
855 : 32063044 : case BIT_FIELD_REF:
856 : 32063044 : get_constraint_for_component_ref (t, results, address_p, lhs_p);
857 : 32063044 : return;
858 : 816829 : case VIEW_CONVERT_EXPR:
859 : 816829 : get_constraint_for_1 (TREE_OPERAND (t, 0), results, address_p,
860 : : lhs_p);
861 : 816829 : return;
862 : : /* We are missing handling for TARGET_MEM_REF here. */
863 : : default:;
864 : : }
865 : : break;
866 : : }
867 : 155776271 : case tcc_exceptional:
868 : 155776271 : {
869 : 155776271 : switch (TREE_CODE (t))
870 : : {
871 : 155728885 : case SSA_NAME:
872 : 155728885 : {
873 : 155728885 : get_constraint_for_ssa_var (t, results, address_p);
874 : 155728885 : return;
875 : : }
876 : 47186 : case CONSTRUCTOR:
877 : 47186 : {
878 : 47186 : unsigned int i;
879 : 47186 : tree val;
880 : 47186 : auto_vec<ce_s> tmp;
881 : 272401 : FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (t), i, val)
882 : : {
883 : 225215 : struct constraint_expr *rhsp;
884 : 225215 : unsigned j;
885 : 225215 : get_constraint_for_1 (val, &tmp, address_p, lhs_p);
886 : 450647 : FOR_EACH_VEC_ELT (tmp, j, rhsp)
887 : 225432 : results->safe_push (*rhsp);
888 : 225215 : tmp.truncate (0);
889 : : }
890 : : /* We do not know whether the constructor was complete,
891 : : so technically we have to add &NOTHING or &ANYTHING
892 : : like we do for an empty constructor as well. */
893 : 47186 : return;
894 : 47186 : }
895 : : default:;
896 : : }
897 : : break;
898 : : }
899 : 48844418 : case tcc_declaration:
900 : 48844418 : {
901 : 48844418 : if (!lhs_p && VAR_P (t) && TREE_THIS_VOLATILE (t))
902 : : /* Fall back to anything. */
903 : : break;
904 : 48156583 : get_constraint_for_ssa_var (t, results, address_p);
905 : 48156583 : return;
906 : : }
907 : 23478735 : case tcc_constant:
908 : 23478735 : {
909 : : /* We cannot refer to automatic variables through constants. */
910 : 23478735 : temp.type = ADDRESSOF;
911 : 23478735 : temp.var = nonlocal_id;
912 : 23478735 : temp.offset = 0;
913 : 23478735 : results->safe_push (temp);
914 : 23478735 : return;
915 : : }
916 : 793644 : default:;
917 : : }
918 : :
919 : : /* The default fallback is a constraint from anything. */
920 : 854658 : temp.type = ADDRESSOF;
921 : 854658 : temp.var = anything_id;
922 : 854658 : temp.offset = 0;
923 : 854658 : results->safe_push (temp);
924 : : }
925 : :
926 : : /* Given a gimple tree T, return the constraint expression vector for it. */
927 : :
928 : : static void
929 : 87684200 : get_constraint_for (tree t, vec<ce_s> *results)
930 : : {
931 : 87684200 : gcc_assert (results->length () == 0);
932 : :
933 : 87684200 : get_constraint_for_1 (t, results, false, true);
934 : 87684200 : }
935 : :
936 : : /* Given a gimple tree T, return the constraint expression vector for it
937 : : to be used as the rhs of a constraint. */
938 : :
939 : : static void
940 : 169248041 : get_constraint_for_rhs (tree t, vec<ce_s> *results)
941 : : {
942 : 169248041 : gcc_assert (results->length () == 0);
943 : :
944 : 169248041 : get_constraint_for_1 (t, results, false, false);
945 : 169248041 : }
946 : :
947 : :
948 : : /* Efficiently generates constraints from all entries in *RHSC to all
949 : : entries in *LHSC. */
950 : :
951 : : static void
952 : 94366410 : process_all_all_constraints (const vec<ce_s> &lhsc,
953 : : const vec<ce_s> &rhsc)
954 : : {
955 : 94366410 : struct constraint_expr *lhsp, *rhsp;
956 : 94366410 : unsigned i, j;
957 : :
958 : 96611034 : if (lhsc.length () <= 1 || rhsc.length () <= 1)
959 : : {
960 : 283932926 : FOR_EACH_VEC_ELT (lhsc, i, lhsp)
961 : 306767595 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
962 : 116378625 : process_constraint (new_constraint (*lhsp, *rhsp));
963 : : }
964 : : else
965 : : {
966 : 822454 : struct constraint_expr tmp;
967 : 822454 : tmp = new_scalar_tmp_constraint_exp ("allalltmp", true);
968 : 4330960 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
969 : 2686052 : process_constraint (new_constraint (tmp, *rhsp));
970 : 3635538 : FOR_EACH_VEC_ELT (lhsc, i, lhsp)
971 : 1990630 : process_constraint (new_constraint (*lhsp, tmp));
972 : : }
973 : 94366410 : }
974 : :
975 : : /* Handle aggregate copies by expanding into copies of the respective
976 : : fields of the structures. */
977 : :
978 : : static void
979 : 2560205 : do_structure_copy (tree lhsop, tree rhsop)
980 : : {
981 : 2560205 : struct constraint_expr *lhsp, *rhsp;
982 : 2560205 : auto_vec<ce_s> lhsc;
983 : 2560205 : auto_vec<ce_s> rhsc;
984 : 2560205 : unsigned j;
985 : :
986 : 2560205 : get_constraint_for (lhsop, &lhsc);
987 : 2560205 : get_constraint_for_rhs (rhsop, &rhsc);
988 : 2560205 : lhsp = &lhsc[0];
989 : 2560205 : rhsp = &rhsc[0];
990 : 2560205 : if (lhsp->type == DEREF
991 : 1993420 : || (lhsp->type == ADDRESSOF && lhsp->var == anything_id)
992 : 1993420 : || rhsp->type == DEREF)
993 : : {
994 : 918955 : if (lhsp->type == DEREF)
995 : : {
996 : 566785 : gcc_assert (lhsc.length () == 1);
997 : 566785 : lhsp->offset = UNKNOWN_OFFSET;
998 : : }
999 : 918955 : if (rhsp->type == DEREF)
1000 : : {
1001 : 462723 : gcc_assert (rhsc.length () == 1);
1002 : 462723 : rhsp->offset = UNKNOWN_OFFSET;
1003 : : }
1004 : 918955 : process_all_all_constraints (lhsc, rhsc);
1005 : : }
1006 : 1641250 : else if (lhsp->type == SCALAR
1007 : 1641250 : && (rhsp->type == SCALAR
1008 : 461349 : || rhsp->type == ADDRESSOF))
1009 : : {
1010 : 1641250 : HOST_WIDE_INT lhssize, lhsoffset;
1011 : 1641250 : HOST_WIDE_INT rhssize, rhsoffset;
1012 : 1641250 : bool reverse;
1013 : 1641250 : unsigned k = 0;
1014 : 1641250 : if (!get_ref_base_and_extent_hwi (lhsop, &lhsoffset, &lhssize, &reverse)
1015 : 1641250 : || !get_ref_base_and_extent_hwi (rhsop, &rhsoffset, &rhssize,
1016 : : &reverse))
1017 : : {
1018 : 4186 : process_all_all_constraints (lhsc, rhsc);
1019 : 4186 : return;
1020 : : }
1021 : 6149669 : for (j = 0; lhsc.iterate (j, &lhsp);)
1022 : : {
1023 : 4586895 : varinfo_t lhsv, rhsv;
1024 : 4586895 : rhsp = &rhsc[k];
1025 : 4586895 : lhsv = get_varinfo (lhsp->var);
1026 : 4586895 : rhsv = get_varinfo (rhsp->var);
1027 : 4586895 : if (lhsv->may_have_pointers
1028 : 4586895 : && (lhsv->is_full_var
1029 : 4025956 : || rhsv->is_full_var
1030 : 3092864 : || ranges_overlap_p (lhsv->offset + rhsoffset, lhsv->size,
1031 : 3092864 : rhsv->offset + lhsoffset, rhsv->size)))
1032 : 3440081 : process_constraint (new_constraint (*lhsp, *rhsp));
1033 : 4586895 : if (!rhsv->is_full_var
1034 : 3229721 : && (lhsv->is_full_var
1035 : 3092864 : || (lhsv->offset + rhsoffset + lhsv->size
1036 : 3092864 : > rhsv->offset + lhsoffset + rhsv->size)))
1037 : : {
1038 : 1292181 : ++k;
1039 : 1292181 : if (k >= rhsc.length ())
1040 : : break;
1041 : : }
1042 : : else
1043 : 3294714 : ++j;
1044 : : }
1045 : 1637064 : }
1046 : : else
1047 : 0 : gcc_unreachable ();
1048 : 2560205 : }
1049 : :
1050 : : /* Create constraints ID = { rhsc }. */
1051 : :
1052 : : static void
1053 : 56341012 : make_constraints_to (unsigned id, const vec<ce_s> &rhsc)
1054 : : {
1055 : 56341012 : struct constraint_expr *c;
1056 : 56341012 : struct constraint_expr includes;
1057 : 56341012 : unsigned int j;
1058 : :
1059 : 56341012 : includes.var = id;
1060 : 56341012 : includes.offset = 0;
1061 : 56341012 : includes.type = SCALAR;
1062 : :
1063 : 116032226 : FOR_EACH_VEC_ELT (rhsc, j, c)
1064 : 59691214 : process_constraint (new_constraint (includes, *c));
1065 : 56341012 : }
1066 : :
1067 : : /* Create a constraint ID = OP. */
1068 : :
1069 : : static void
1070 : 56174056 : make_constraint_to (unsigned id, tree op)
1071 : : {
1072 : 56174056 : auto_vec<ce_s> rhsc;
1073 : 56174056 : get_constraint_for_rhs (op, &rhsc);
1074 : 56174056 : make_constraints_to (id, rhsc);
1075 : 56174056 : }
1076 : :
1077 : : /* Create a constraint ID = &FROM. */
1078 : :
1079 : : static void
1080 : 11437353 : make_constraint_from (varinfo_t vi, int from)
1081 : : {
1082 : 11437353 : struct constraint_expr lhs, rhs;
1083 : :
1084 : 11437353 : lhs.var = vi->id;
1085 : 11437353 : lhs.offset = 0;
1086 : 11437353 : lhs.type = SCALAR;
1087 : :
1088 : 11437353 : rhs.var = from;
1089 : 11437353 : rhs.offset = 0;
1090 : 11437353 : rhs.type = ADDRESSOF;
1091 : 11437353 : process_constraint (new_constraint (lhs, rhs));
1092 : 11437353 : }
1093 : :
1094 : : /* Create a constraint ID = FROM. */
1095 : :
1096 : : static void
1097 : 76785846 : make_copy_constraint (varinfo_t vi, int from)
1098 : : {
1099 : 76785846 : struct constraint_expr lhs, rhs;
1100 : :
1101 : 76785846 : lhs.var = vi->id;
1102 : 76785846 : lhs.offset = 0;
1103 : 76785846 : lhs.type = SCALAR;
1104 : :
1105 : 76785846 : rhs.var = from;
1106 : 76785846 : rhs.offset = 0;
1107 : 76785846 : rhs.type = SCALAR;
1108 : 76785846 : process_constraint (new_constraint (lhs, rhs));
1109 : 76785846 : }
1110 : :
1111 : : /* Make constraints necessary to make OP escape. */
1112 : :
1113 : : static void
1114 : 23506623 : make_escape_constraint (tree op)
1115 : : {
1116 : 0 : make_constraint_to (escaped_id, op);
1117 : 23506623 : }
1118 : :
1119 : : /* Make constraint necessary to make all indirect references
1120 : : from VI escape. */
1121 : :
1122 : : static void
1123 : 1159051 : make_indirect_escape_constraint (varinfo_t vi)
1124 : : {
1125 : 1159051 : struct constraint_expr lhs, rhs;
1126 : : /* escaped = *(VAR + UNKNOWN); */
1127 : 1159051 : lhs.type = SCALAR;
1128 : 1159051 : lhs.var = escaped_id;
1129 : 1159051 : lhs.offset = 0;
1130 : 1159051 : rhs.type = DEREF;
1131 : 1159051 : rhs.var = vi->id;
1132 : 1159051 : rhs.offset = UNKNOWN_OFFSET;
1133 : 1159051 : process_constraint (new_constraint (lhs, rhs));
1134 : 1159051 : }
1135 : :
1136 : : /* Add constraints to that the solution of VI is transitively closed. */
1137 : :
1138 : : static void
1139 : 25735106 : make_transitive_closure_constraints (varinfo_t vi)
1140 : : {
1141 : 25735106 : struct constraint_expr lhs, rhs;
1142 : :
1143 : : /* VAR = *(VAR + UNKNOWN); */
1144 : 25735106 : lhs.type = SCALAR;
1145 : 25735106 : lhs.var = vi->id;
1146 : 25735106 : lhs.offset = 0;
1147 : 25735106 : rhs.type = DEREF;
1148 : 25735106 : rhs.var = vi->id;
1149 : 25735106 : rhs.offset = UNKNOWN_OFFSET;
1150 : 25735106 : process_constraint (new_constraint (lhs, rhs));
1151 : 25735106 : }
1152 : :
1153 : : /* Add constraints to that the solution of VI has all subvariables added. */
1154 : :
1155 : : static void
1156 : 31185859 : make_any_offset_constraints (varinfo_t vi)
1157 : : {
1158 : 31185859 : struct constraint_expr lhs, rhs;
1159 : :
1160 : : /* VAR = VAR + UNKNOWN; */
1161 : 31185859 : lhs.type = SCALAR;
1162 : 31185859 : lhs.var = vi->id;
1163 : 31185859 : lhs.offset = 0;
1164 : 31185859 : rhs.type = SCALAR;
1165 : 31185859 : rhs.var = vi->id;
1166 : 31185859 : rhs.offset = UNKNOWN_OFFSET;
1167 : 31185859 : process_constraint (new_constraint (lhs, rhs));
1168 : 31185859 : }
1169 : :
1170 : : /* Temporary storage for fake var decls. */
1171 : : struct obstack fake_var_decl_obstack;
1172 : :
1173 : : /* Build a fake VAR_DECL acting as referrer to a DECL_UID. */
1174 : :
1175 : : static tree
1176 : 934698 : build_fake_var_decl (tree type)
1177 : : {
1178 : 934698 : tree decl = (tree) XOBNEW (&fake_var_decl_obstack, struct tree_var_decl);
1179 : 934698 : memset (decl, 0, sizeof (struct tree_var_decl));
1180 : 934698 : TREE_SET_CODE (decl, VAR_DECL);
1181 : 934698 : TREE_TYPE (decl) = type;
1182 : 934698 : DECL_UID (decl) = allocate_decl_uid ();
1183 : 934698 : SET_DECL_PT_UID (decl, -1);
1184 : 934698 : layout_decl (decl, 0);
1185 : 934698 : return decl;
1186 : : }
1187 : :
1188 : : /* Create a new artificial heap variable with NAME.
1189 : : Return the created variable. */
1190 : :
1191 : : static varinfo_t
1192 : 341278 : make_heapvar (const char *name, bool add_id)
1193 : : {
1194 : 341278 : varinfo_t vi;
1195 : 341278 : tree heapvar;
1196 : :
1197 : 341278 : heapvar = build_fake_var_decl (ptr_type_node);
1198 : 341278 : DECL_EXTERNAL (heapvar) = 1;
1199 : :
1200 : 341278 : vi = new_var_info (heapvar, name, add_id);
1201 : 341278 : vi->is_heap_var = true;
1202 : 341278 : vi->is_unknown_size_var = true;
1203 : 341278 : vi->offset = 0;
1204 : 341278 : vi->fullsize = ~0;
1205 : 341278 : vi->size = ~0;
1206 : 341278 : vi->is_full_var = true;
1207 : 341278 : insert_vi_for_tree (heapvar, vi);
1208 : :
1209 : 341278 : return vi;
1210 : : }
1211 : :
1212 : : /* Create a new artificial heap variable with NAME and make a
1213 : : constraint from it to LHS. Set flags according to a tag used
1214 : : for tracking restrict pointers. */
1215 : :
1216 : : static varinfo_t
1217 : 11232 : make_constraint_from_restrict (varinfo_t lhs, const char *name, bool add_id)
1218 : : {
1219 : 11232 : varinfo_t vi = make_heapvar (name, add_id);
1220 : 11232 : vi->is_restrict_var = 1;
1221 : 11232 : vi->is_global_var = 1;
1222 : 11232 : vi->may_have_pointers = 1;
1223 : 11232 : make_constraint_from (lhs, vi->id);
1224 : 11232 : return vi;
1225 : : }
1226 : :
1227 : : /* Create a new artificial heap variable with NAME and make a
1228 : : constraint from it to LHS. Set flags according to a tag used
1229 : : for tracking restrict pointers and make the artificial heap
1230 : : point to global memory. */
1231 : :
1232 : : static varinfo_t
1233 : 11232 : make_constraint_from_global_restrict (varinfo_t lhs, const char *name,
1234 : : bool add_id)
1235 : : {
1236 : 11232 : varinfo_t vi = make_constraint_from_restrict (lhs, name, add_id);
1237 : 11232 : make_copy_constraint (vi, nonlocal_id);
1238 : 11232 : return vi;
1239 : : }
1240 : :
1241 : : /* Get a constraint for the requested part of a function designator FI
1242 : : when operating in IPA mode. */
1243 : :
1244 : : static struct constraint_expr
1245 : 1434756 : get_function_part_constraint (varinfo_t fi, unsigned part)
1246 : : {
1247 : 1434756 : struct constraint_expr c;
1248 : :
1249 : 1434756 : gcc_assert (in_ipa_mode);
1250 : :
1251 : 1434756 : if (fi->id == anything_id)
1252 : : {
1253 : : /* ??? We probably should have a ANYFN special variable. */
1254 : : c.var = anything_id;
1255 : : c.offset = 0;
1256 : : c.type = SCALAR;
1257 : : }
1258 : 493458 : else if (fi->decl && TREE_CODE (fi->decl) == FUNCTION_DECL)
1259 : : {
1260 : 490075 : varinfo_t ai = first_vi_for_offset (fi, part);
1261 : 490075 : if (ai)
1262 : 490075 : c.var = ai->id;
1263 : : else
1264 : : c.var = anything_id;
1265 : : c.offset = 0;
1266 : : c.type = SCALAR;
1267 : : }
1268 : : else
1269 : : {
1270 : 3383 : c.var = fi->id;
1271 : 3383 : c.offset = part;
1272 : 3383 : c.type = DEREF;
1273 : : }
1274 : :
1275 : 1434756 : return c;
1276 : : }
1277 : :
1278 : : /* Produce constraints for argument ARG of call STMT with eaf flags
1279 : : FLAGS. RESULTS is array holding constraints for return value.
1280 : : CALLESCAPE_ID is variable where call loocal escapes are added.
1281 : : WRITES_GLOVEL_MEMORY is true if callee may write global memory. */
1282 : :
1283 : : static void
1284 : 30128951 : handle_call_arg (gcall *stmt, tree arg, vec<ce_s> *results, int flags,
1285 : : int callescape_id, bool writes_global_memory)
1286 : : {
1287 : 30128951 : int relevant_indirect_flags = EAF_NO_INDIRECT_CLOBBER | EAF_NO_INDIRECT_READ
1288 : : | EAF_NO_INDIRECT_ESCAPE;
1289 : 30128951 : int relevant_flags = relevant_indirect_flags
1290 : : | EAF_NO_DIRECT_CLOBBER
1291 : : | EAF_NO_DIRECT_READ
1292 : : | EAF_NO_DIRECT_ESCAPE;
1293 : 30128951 : if (gimple_call_lhs (stmt))
1294 : : {
1295 : 11379070 : relevant_flags |= EAF_NOT_RETURNED_DIRECTLY | EAF_NOT_RETURNED_INDIRECTLY;
1296 : 11379070 : relevant_indirect_flags |= EAF_NOT_RETURNED_INDIRECTLY;
1297 : :
1298 : : /* If value is never read from it can not be returned indirectly
1299 : : (except through the escape solution).
1300 : : For all flags we get these implications right except for
1301 : : not_returned because we miss return functions in ipa-prop. */
1302 : :
1303 : 11379070 : if (flags & EAF_NO_DIRECT_READ)
1304 : 1981822 : flags |= EAF_NOT_RETURNED_INDIRECTLY;
1305 : : }
1306 : :
1307 : : /* If the argument is not used we can ignore it.
1308 : : Similarly argument is invisile for us if it not clobbered, does not
1309 : : escape, is not read and can not be returned. */
1310 : 30128951 : if ((flags & EAF_UNUSED) || ((flags & relevant_flags) == relevant_flags))
1311 : : return;
1312 : :
1313 : : /* Produce varinfo for direct accesses to ARG. */
1314 : 28884166 : varinfo_t tem = new_var_info (NULL_TREE, "callarg", true);
1315 : 28884166 : tem->is_reg_var = true;
1316 : 28884166 : make_constraint_to (tem->id, arg);
1317 : 28884166 : make_any_offset_constraints (tem);
1318 : :
1319 : 28884166 : bool callarg_transitive = false;
1320 : :
1321 : : /* As an compile time optimization if we make no difference between
1322 : : direct and indirect accesses make arg transitively closed.
1323 : : This avoids the need to build indir arg and do everything twice. */
1324 : 28884166 : if (((flags & EAF_NO_INDIRECT_CLOBBER) != 0)
1325 : 28884166 : == ((flags & EAF_NO_DIRECT_CLOBBER) != 0)
1326 : 27546812 : && (((flags & EAF_NO_INDIRECT_READ) != 0)
1327 : 27546812 : == ((flags & EAF_NO_DIRECT_READ) != 0))
1328 : 26596368 : && (((flags & EAF_NO_INDIRECT_ESCAPE) != 0)
1329 : 26596368 : == ((flags & EAF_NO_DIRECT_ESCAPE) != 0))
1330 : 26063995 : && (((flags & EAF_NOT_RETURNED_INDIRECTLY) != 0)
1331 : 26063995 : == ((flags & EAF_NOT_RETURNED_DIRECTLY) != 0)))
1332 : : {
1333 : 24219605 : make_transitive_closure_constraints (tem);
1334 : 24219605 : callarg_transitive = true;
1335 : : }
1336 : :
1337 : : /* If necessary, produce varinfo for indirect accesses to ARG. */
1338 : 28884166 : varinfo_t indir_tem = NULL;
1339 : 24219605 : if (!callarg_transitive
1340 : 4664561 : && (flags & relevant_indirect_flags) != relevant_indirect_flags)
1341 : : {
1342 : 1631763 : struct constraint_expr lhs, rhs;
1343 : 1631763 : indir_tem = new_var_info (NULL_TREE, "indircallarg", true);
1344 : 1631763 : indir_tem->is_reg_var = true;
1345 : :
1346 : : /* indir_term = *tem. */
1347 : 1631763 : lhs.type = SCALAR;
1348 : 1631763 : lhs.var = indir_tem->id;
1349 : 1631763 : lhs.offset = 0;
1350 : :
1351 : 1631763 : rhs.type = DEREF;
1352 : 1631763 : rhs.var = tem->id;
1353 : 1631763 : rhs.offset = UNKNOWN_OFFSET;
1354 : 1631763 : process_constraint (new_constraint (lhs, rhs));
1355 : :
1356 : 1631763 : make_any_offset_constraints (indir_tem);
1357 : :
1358 : : /* If we do not read indirectly there is no need for transitive closure.
1359 : : We know there is only one level of indirection. */
1360 : 1631763 : if (!(flags & EAF_NO_INDIRECT_READ))
1361 : 1515501 : make_transitive_closure_constraints (indir_tem);
1362 : 1631763 : gcc_checking_assert (!(flags & EAF_NO_DIRECT_READ));
1363 : : }
1364 : :
1365 : 28884166 : if (gimple_call_lhs (stmt))
1366 : : {
1367 : 11149115 : if (!(flags & EAF_NOT_RETURNED_DIRECTLY))
1368 : : {
1369 : 10176367 : struct constraint_expr cexpr;
1370 : 10176367 : cexpr.var = tem->id;
1371 : 10176367 : cexpr.type = SCALAR;
1372 : 10176367 : cexpr.offset = 0;
1373 : 10176367 : results->safe_push (cexpr);
1374 : : }
1375 : 11149115 : if (!callarg_transitive & !(flags & EAF_NOT_RETURNED_INDIRECTLY))
1376 : : {
1377 : 638007 : struct constraint_expr cexpr;
1378 : 638007 : cexpr.var = indir_tem->id;
1379 : 638007 : cexpr.type = SCALAR;
1380 : 638007 : cexpr.offset = 0;
1381 : 638007 : results->safe_push (cexpr);
1382 : : }
1383 : : }
1384 : :
1385 : 28884166 : if (!(flags & EAF_NO_DIRECT_READ))
1386 : : {
1387 : 26735078 : varinfo_t uses = get_call_use_vi (stmt);
1388 : 26735078 : make_copy_constraint (uses, tem->id);
1389 : 26735078 : if (!callarg_transitive & !(flags & EAF_NO_INDIRECT_READ))
1390 : 1515501 : make_copy_constraint (uses, indir_tem->id);
1391 : : }
1392 : : else
1393 : : /* To read indirectly we need to read directly. */
1394 : 2149088 : gcc_checking_assert (flags & EAF_NO_INDIRECT_READ);
1395 : :
1396 : 28884166 : if (!(flags & EAF_NO_DIRECT_CLOBBER))
1397 : : {
1398 : 24004700 : struct constraint_expr lhs, rhs;
1399 : :
1400 : : /* *arg = callescape. */
1401 : 24004700 : lhs.type = DEREF;
1402 : 24004700 : lhs.var = tem->id;
1403 : 24004700 : lhs.offset = 0;
1404 : :
1405 : 24004700 : rhs.type = SCALAR;
1406 : 24004700 : rhs.var = callescape_id;
1407 : 24004700 : rhs.offset = 0;
1408 : 24004700 : process_constraint (new_constraint (lhs, rhs));
1409 : :
1410 : : /* callclobbered = arg. */
1411 : 24004700 : make_copy_constraint (get_call_clobber_vi (stmt), tem->id);
1412 : : }
1413 : 28884166 : if (!callarg_transitive & !(flags & EAF_NO_INDIRECT_CLOBBER))
1414 : : {
1415 : 1338474 : struct constraint_expr lhs, rhs;
1416 : :
1417 : : /* *indir_arg = callescape. */
1418 : 1338474 : lhs.type = DEREF;
1419 : 1338474 : lhs.var = indir_tem->id;
1420 : 1338474 : lhs.offset = 0;
1421 : :
1422 : 1338474 : rhs.type = SCALAR;
1423 : 1338474 : rhs.var = callescape_id;
1424 : 1338474 : rhs.offset = 0;
1425 : 1338474 : process_constraint (new_constraint (lhs, rhs));
1426 : :
1427 : : /* callclobbered = indir_arg. */
1428 : 1338474 : make_copy_constraint (get_call_clobber_vi (stmt), indir_tem->id);
1429 : : }
1430 : :
1431 : 28884166 : if (!(flags & (EAF_NO_DIRECT_ESCAPE | EAF_NO_INDIRECT_ESCAPE)))
1432 : : {
1433 : 22498670 : struct constraint_expr lhs, rhs;
1434 : :
1435 : : /* callescape = arg; */
1436 : 22498670 : lhs.var = callescape_id;
1437 : 22498670 : lhs.offset = 0;
1438 : 22498670 : lhs.type = SCALAR;
1439 : :
1440 : 22498670 : rhs.var = tem->id;
1441 : 22498670 : rhs.offset = 0;
1442 : 22498670 : rhs.type = SCALAR;
1443 : 22498670 : process_constraint (new_constraint (lhs, rhs));
1444 : :
1445 : 22498670 : if (writes_global_memory)
1446 : 21774312 : make_escape_constraint (arg);
1447 : : }
1448 : 6385496 : else if (!callarg_transitive & !(flags & EAF_NO_INDIRECT_ESCAPE))
1449 : : {
1450 : 1274165 : struct constraint_expr lhs, rhs;
1451 : :
1452 : : /* callescape = *(indir_arg + UNKNOWN); */
1453 : 1274165 : lhs.var = callescape_id;
1454 : 1274165 : lhs.offset = 0;
1455 : 1274165 : lhs.type = SCALAR;
1456 : :
1457 : 1274165 : rhs.var = indir_tem->id;
1458 : 1274165 : rhs.offset = 0;
1459 : 1274165 : rhs.type = SCALAR;
1460 : 1274165 : process_constraint (new_constraint (lhs, rhs));
1461 : :
1462 : 1274165 : if (writes_global_memory)
1463 : 1159051 : make_indirect_escape_constraint (tem);
1464 : : }
1465 : : }
1466 : :
1467 : : /* For non-IPA mode, generate constraints necessary for a call on the
1468 : : RHS and collect return value constraint to RESULTS to be used later in
1469 : : handle_lhs_call.
1470 : :
1471 : : IMPLICIT_EAF_FLAGS are added to each function argument. If
1472 : : WRITES_GLOBAL_MEMORY is true function is assumed to possibly write to global
1473 : : memory. Similar for READS_GLOBAL_MEMORY. */
1474 : :
1475 : : static void
1476 : 15086218 : handle_rhs_call (gcall *stmt, vec<ce_s> *results,
1477 : : int implicit_eaf_flags,
1478 : : bool writes_global_memory,
1479 : : bool reads_global_memory)
1480 : : {
1481 : 15086218 : determine_global_memory_access (stmt, &writes_global_memory,
1482 : : &reads_global_memory,
1483 : : NULL);
1484 : :
1485 : 15086218 : varinfo_t callescape = new_var_info (NULL_TREE, "callescape", true);
1486 : :
1487 : : /* If function can use global memory, add it to callescape
1488 : : and to possible return values. If not we can still use/return addresses
1489 : : of global symbols. */
1490 : 15086218 : struct constraint_expr lhs, rhs;
1491 : :
1492 : 15086218 : lhs.type = SCALAR;
1493 : 15086218 : lhs.var = callescape->id;
1494 : 15086218 : lhs.offset = 0;
1495 : :
1496 : 15086218 : rhs.type = reads_global_memory ? SCALAR : ADDRESSOF;
1497 : 15086218 : rhs.var = nonlocal_id;
1498 : 15086218 : rhs.offset = 0;
1499 : :
1500 : 15086218 : process_constraint (new_constraint (lhs, rhs));
1501 : 15086218 : results->safe_push (rhs);
1502 : :
1503 : 15086218 : varinfo_t uses = get_call_use_vi (stmt);
1504 : 15086218 : make_copy_constraint (uses, callescape->id);
1505 : :
1506 : 45131311 : for (unsigned i = 0; i < gimple_call_num_args (stmt); ++i)
1507 : : {
1508 : 30045093 : tree arg = gimple_call_arg (stmt, i);
1509 : 30045093 : int flags = gimple_call_arg_flags (stmt, i);
1510 : 30045093 : handle_call_arg (stmt, arg, results,
1511 : : flags | implicit_eaf_flags,
1512 : 30045093 : callescape->id, writes_global_memory);
1513 : : }
1514 : :
1515 : : /* The static chain escapes as well. */
1516 : 15086218 : if (gimple_call_chain (stmt))
1517 : 83858 : handle_call_arg (stmt, gimple_call_chain (stmt), results,
1518 : : implicit_eaf_flags
1519 : 83858 : | gimple_call_static_chain_flags (stmt),
1520 : 83858 : callescape->id, writes_global_memory);
1521 : :
1522 : : /* And if we applied NRV the address of the return slot escapes as well. */
1523 : 15086218 : if (gimple_call_return_slot_opt_p (stmt)
1524 : 640913 : && gimple_call_lhs (stmt) != NULL_TREE
1525 : 15698702 : && TREE_ADDRESSABLE (TREE_TYPE (gimple_call_lhs (stmt))))
1526 : : {
1527 : 87771 : int flags = gimple_call_retslot_flags (stmt);
1528 : 87771 : const int relevant_flags = EAF_NO_DIRECT_ESCAPE
1529 : : | EAF_NOT_RETURNED_DIRECTLY;
1530 : :
1531 : 87771 : if (!(flags & EAF_UNUSED) && (flags & relevant_flags) != relevant_flags)
1532 : : {
1533 : 70775 : auto_vec<ce_s> tmpc;
1534 : :
1535 : 70775 : get_constraint_for_address_of (gimple_call_lhs (stmt), &tmpc);
1536 : :
1537 : 70775 : if (!(flags & EAF_NO_DIRECT_ESCAPE))
1538 : : {
1539 : 70771 : make_constraints_to (callescape->id, tmpc);
1540 : 70771 : if (writes_global_memory)
1541 : 69582 : make_constraints_to (escaped_id, tmpc);
1542 : : }
1543 : 70775 : if (!(flags & EAF_NOT_RETURNED_DIRECTLY))
1544 : : {
1545 : : struct constraint_expr *c;
1546 : : unsigned i;
1547 : 210583 : FOR_EACH_VEC_ELT (tmpc, i, c)
1548 : 69904 : results->safe_push (*c);
1549 : : }
1550 : 70775 : }
1551 : : }
1552 : 15086218 : }
1553 : :
1554 : : /* For non-IPA mode, generate constraints necessary for a call
1555 : : that returns a pointer and assigns it to LHS. This simply makes
1556 : : the LHS point to global and escaped variables. */
1557 : :
1558 : : static void
1559 : 5783560 : handle_lhs_call (gcall *stmt, tree lhs, int flags, vec<ce_s> &rhsc,
1560 : : tree fndecl)
1561 : : {
1562 : 5783560 : auto_vec<ce_s> lhsc;
1563 : :
1564 : 5783560 : get_constraint_for (lhs, &lhsc);
1565 : : /* If the store is to a global decl make sure to
1566 : : add proper escape constraints. */
1567 : 5783560 : lhs = get_base_address (lhs);
1568 : 5783560 : if (lhs
1569 : 5783560 : && DECL_P (lhs)
1570 : 6822957 : && is_global_var (lhs))
1571 : : {
1572 : 3295 : struct constraint_expr tmpc;
1573 : 3295 : tmpc.var = escaped_id;
1574 : 3295 : tmpc.offset = 0;
1575 : 3295 : tmpc.type = SCALAR;
1576 : 3295 : lhsc.safe_push (tmpc);
1577 : : }
1578 : :
1579 : : /* If the call returns an argument unmodified override the rhs
1580 : : constraints. */
1581 : 5783560 : if (flags & ERF_RETURNS_ARG
1582 : 5783560 : && (flags & ERF_RETURN_ARG_MASK) < gimple_call_num_args (stmt))
1583 : : {
1584 : 77395 : tree arg;
1585 : 77395 : rhsc.truncate (0);
1586 : 77395 : arg = gimple_call_arg (stmt, flags & ERF_RETURN_ARG_MASK);
1587 : 77395 : get_constraint_for (arg, &rhsc);
1588 : 77395 : process_all_all_constraints (lhsc, rhsc);
1589 : 77395 : rhsc.truncate (0);
1590 : : }
1591 : 5706165 : else if (flags & ERF_NOALIAS)
1592 : : {
1593 : 296627 : varinfo_t vi;
1594 : 296627 : struct constraint_expr tmpc;
1595 : 296627 : rhsc.truncate (0);
1596 : 296627 : vi = make_heapvar ("HEAP", true);
1597 : : /* We are marking allocated storage local, we deal with it becoming
1598 : : global by escaping and setting of vars_contains_escaped_heap. */
1599 : 296627 : DECL_EXTERNAL (vi->decl) = 0;
1600 : 296627 : vi->is_global_var = 0;
1601 : : /* If this is not a real malloc call assume the memory was
1602 : : initialized and thus may point to global memory. All
1603 : : builtin functions with the malloc attribute behave in a sane way. */
1604 : 296627 : if (!fndecl
1605 : 296627 : || !fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
1606 : 154493 : make_constraint_from (vi, nonlocal_id);
1607 : 296627 : tmpc.var = vi->id;
1608 : 296627 : tmpc.offset = 0;
1609 : 296627 : tmpc.type = ADDRESSOF;
1610 : 296627 : rhsc.safe_push (tmpc);
1611 : 296627 : process_all_all_constraints (lhsc, rhsc);
1612 : 296627 : rhsc.truncate (0);
1613 : : }
1614 : : else
1615 : 5409538 : process_all_all_constraints (lhsc, rhsc);
1616 : 5783560 : }
1617 : :
1618 : :
1619 : : /* Create constraints for assigning call argument ARG to the incoming parameter
1620 : : INDEX of function FI. */
1621 : :
1622 : : static void
1623 : 803954 : find_func_aliases_for_call_arg (varinfo_t fi, unsigned index, tree arg)
1624 : : {
1625 : 803954 : struct constraint_expr lhs;
1626 : 803954 : lhs = get_function_part_constraint (fi, fi_parm_base + index);
1627 : :
1628 : 803954 : auto_vec<ce_s, 2> rhsc;
1629 : 803954 : get_constraint_for_rhs (arg, &rhsc);
1630 : :
1631 : 803954 : unsigned j;
1632 : 803954 : struct constraint_expr *rhsp;
1633 : 3215817 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
1634 : 803955 : process_constraint (new_constraint (lhs, *rhsp));
1635 : 803954 : }
1636 : :
1637 : : /* Create constraints for the builtin call T. Return true if the call
1638 : : was handled, otherwise false. */
1639 : :
1640 : : static bool
1641 : 5004687 : find_func_aliases_for_builtin_call (struct function *fn, gcall *t)
1642 : : {
1643 : 5004687 : tree fndecl = gimple_call_fndecl (t);
1644 : 5004687 : auto_vec<ce_s, 2> lhsc;
1645 : 5004687 : auto_vec<ce_s, 4> rhsc;
1646 : 5004687 : varinfo_t fi;
1647 : :
1648 : 5004687 : if (gimple_call_builtin_p (t, BUILT_IN_NORMAL))
1649 : : /* ??? All builtins that are handled here need to be handled
1650 : : in the alias-oracle query functions explicitly! */
1651 : 4546780 : switch (DECL_FUNCTION_CODE (fndecl))
1652 : : {
1653 : : /* All the following functions return a pointer to the same object
1654 : : as their first argument points to. The functions do not add
1655 : : to the ESCAPED solution. The functions make the first argument
1656 : : pointed to memory point to what the second argument pointed to
1657 : : memory points to. */
1658 : 265355 : case BUILT_IN_STRCPY:
1659 : 265355 : case BUILT_IN_STRNCPY:
1660 : 265355 : case BUILT_IN_BCOPY:
1661 : 265355 : case BUILT_IN_MEMCPY:
1662 : 265355 : case BUILT_IN_MEMMOVE:
1663 : 265355 : case BUILT_IN_MEMPCPY:
1664 : 265355 : case BUILT_IN_STPCPY:
1665 : 265355 : case BUILT_IN_STPNCPY:
1666 : 265355 : case BUILT_IN_STRCAT:
1667 : 265355 : case BUILT_IN_STRNCAT:
1668 : 265355 : case BUILT_IN_STRCPY_CHK:
1669 : 265355 : case BUILT_IN_STRNCPY_CHK:
1670 : 265355 : case BUILT_IN_MEMCPY_CHK:
1671 : 265355 : case BUILT_IN_MEMMOVE_CHK:
1672 : 265355 : case BUILT_IN_MEMPCPY_CHK:
1673 : 265355 : case BUILT_IN_STPCPY_CHK:
1674 : 265355 : case BUILT_IN_STPNCPY_CHK:
1675 : 265355 : case BUILT_IN_STRCAT_CHK:
1676 : 265355 : case BUILT_IN_STRNCAT_CHK:
1677 : 265355 : case BUILT_IN_TM_MEMCPY:
1678 : 265355 : case BUILT_IN_TM_MEMMOVE:
1679 : 265355 : {
1680 : 265355 : tree res = gimple_call_lhs (t);
1681 : 530710 : tree dest = gimple_call_arg (t, (DECL_FUNCTION_CODE (fndecl)
1682 : : == BUILT_IN_BCOPY ? 1 : 0));
1683 : 530710 : tree src = gimple_call_arg (t, (DECL_FUNCTION_CODE (fndecl)
1684 : 265355 : == BUILT_IN_BCOPY ? 0 : 1));
1685 : 265355 : if (res != NULL_TREE)
1686 : : {
1687 : 25611 : get_constraint_for (res, &lhsc);
1688 : 25611 : if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_MEMPCPY
1689 : 22474 : || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPCPY
1690 : 21299 : || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPNCPY
1691 : 19543 : || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_MEMPCPY_CHK
1692 : 19206 : || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPCPY_CHK
1693 : 44536 : || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPNCPY_CHK)
1694 : 6961 : get_constraint_for_ptr_offset (dest, NULL_TREE, &rhsc);
1695 : : else
1696 : 18650 : get_constraint_for (dest, &rhsc);
1697 : 25611 : process_all_all_constraints (lhsc, rhsc);
1698 : 25611 : lhsc.truncate (0);
1699 : 25611 : rhsc.truncate (0);
1700 : : }
1701 : 265355 : get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
1702 : 265355 : get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
1703 : 265355 : do_deref (&lhsc);
1704 : 265355 : do_deref (&rhsc);
1705 : 265355 : process_all_all_constraints (lhsc, rhsc);
1706 : 265355 : return true;
1707 : : }
1708 : 74748 : case BUILT_IN_MEMSET:
1709 : 74748 : case BUILT_IN_MEMSET_CHK:
1710 : 74748 : case BUILT_IN_TM_MEMSET:
1711 : 74748 : {
1712 : 74748 : tree res = gimple_call_lhs (t);
1713 : 74748 : tree dest = gimple_call_arg (t, 0);
1714 : 74748 : unsigned i;
1715 : 74748 : ce_s *lhsp;
1716 : 74748 : struct constraint_expr ac;
1717 : 74748 : if (res != NULL_TREE)
1718 : : {
1719 : 5559 : get_constraint_for (res, &lhsc);
1720 : 5559 : get_constraint_for (dest, &rhsc);
1721 : 5559 : process_all_all_constraints (lhsc, rhsc);
1722 : 5559 : lhsc.truncate (0);
1723 : : }
1724 : 74748 : get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
1725 : 74748 : do_deref (&lhsc);
1726 : 74748 : if (flag_delete_null_pointer_checks
1727 : 149355 : && integer_zerop (gimple_call_arg (t, 1)))
1728 : : {
1729 : : ac.type = ADDRESSOF;
1730 : : ac.var = nothing_id;
1731 : : }
1732 : : else
1733 : : {
1734 : : ac.type = SCALAR;
1735 : : ac.var = integer_id;
1736 : : }
1737 : 74748 : ac.offset = 0;
1738 : 1425188 : FOR_EACH_VEC_ELT (lhsc, i, lhsp)
1739 : 80833 : process_constraint (new_constraint (*lhsp, ac));
1740 : : return true;
1741 : : }
1742 : : case BUILT_IN_STACK_SAVE:
1743 : : case BUILT_IN_STACK_RESTORE:
1744 : : /* Nothing interesting happens. */
1745 : : return true;
1746 : 33288 : case BUILT_IN_ALLOCA:
1747 : 33288 : case BUILT_IN_ALLOCA_WITH_ALIGN:
1748 : 33288 : case BUILT_IN_ALLOCA_WITH_ALIGN_AND_MAX:
1749 : 33288 : {
1750 : 33288 : tree ptr = gimple_call_lhs (t);
1751 : 33288 : if (ptr == NULL_TREE)
1752 : : return true;
1753 : 33287 : get_constraint_for (ptr, &lhsc);
1754 : 33287 : varinfo_t vi = make_heapvar ("HEAP", true);
1755 : : /* Alloca storage is never global. To exempt it from escaped
1756 : : handling make it a non-heap var. */
1757 : 33287 : DECL_EXTERNAL (vi->decl) = 0;
1758 : 33287 : vi->is_global_var = 0;
1759 : 33287 : vi->is_heap_var = 0;
1760 : 33287 : struct constraint_expr tmpc;
1761 : 33287 : tmpc.var = vi->id;
1762 : 33287 : tmpc.offset = 0;
1763 : 33287 : tmpc.type = ADDRESSOF;
1764 : 33287 : rhsc.safe_push (tmpc);
1765 : 33287 : process_all_all_constraints (lhsc, rhsc);
1766 : 33287 : return true;
1767 : : }
1768 : 132 : case BUILT_IN_POSIX_MEMALIGN:
1769 : 132 : {
1770 : 132 : tree ptrptr = gimple_call_arg (t, 0);
1771 : 132 : get_constraint_for (ptrptr, &lhsc);
1772 : 132 : do_deref (&lhsc);
1773 : 132 : varinfo_t vi = make_heapvar ("HEAP", true);
1774 : : /* We are marking allocated storage local, we deal with it becoming
1775 : : global by escaping and setting of vars_contains_escaped_heap. */
1776 : 132 : DECL_EXTERNAL (vi->decl) = 0;
1777 : 132 : vi->is_global_var = 0;
1778 : 132 : struct constraint_expr tmpc;
1779 : 132 : tmpc.var = vi->id;
1780 : 132 : tmpc.offset = 0;
1781 : 132 : tmpc.type = ADDRESSOF;
1782 : 132 : rhsc.safe_push (tmpc);
1783 : 132 : process_all_all_constraints (lhsc, rhsc);
1784 : 132 : return true;
1785 : : }
1786 : 1673 : case BUILT_IN_ASSUME_ALIGNED:
1787 : 1673 : {
1788 : 1673 : tree res = gimple_call_lhs (t);
1789 : 1673 : tree dest = gimple_call_arg (t, 0);
1790 : 1673 : if (res != NULL_TREE)
1791 : : {
1792 : 1673 : get_constraint_for (res, &lhsc);
1793 : 1673 : get_constraint_for (dest, &rhsc);
1794 : 1673 : process_all_all_constraints (lhsc, rhsc);
1795 : : }
1796 : 1673 : return true;
1797 : : }
1798 : : /* All the following functions do not return pointers, do not
1799 : : modify the points-to sets of memory reachable from their
1800 : : arguments and do not add to the ESCAPED solution. */
1801 : : case BUILT_IN_SINCOS:
1802 : : case BUILT_IN_SINCOSF:
1803 : : case BUILT_IN_SINCOSL:
1804 : : case BUILT_IN_FREXP:
1805 : : case BUILT_IN_FREXPF:
1806 : : case BUILT_IN_FREXPL:
1807 : : case BUILT_IN_GAMMA_R:
1808 : : case BUILT_IN_GAMMAF_R:
1809 : : case BUILT_IN_GAMMAL_R:
1810 : : case BUILT_IN_LGAMMA_R:
1811 : : case BUILT_IN_LGAMMAF_R:
1812 : : case BUILT_IN_LGAMMAL_R:
1813 : : case BUILT_IN_MODF:
1814 : : case BUILT_IN_MODFF:
1815 : : case BUILT_IN_MODFL:
1816 : : case BUILT_IN_REMQUO:
1817 : : case BUILT_IN_REMQUOF:
1818 : : case BUILT_IN_REMQUOL:
1819 : : case BUILT_IN_FREE:
1820 : : return true;
1821 : 15702 : case BUILT_IN_STRDUP:
1822 : 15702 : case BUILT_IN_STRNDUP:
1823 : 15702 : case BUILT_IN_REALLOC:
1824 : 15702 : if (gimple_call_lhs (t))
1825 : : {
1826 : 15666 : auto_vec<ce_s> rhsc;
1827 : 15666 : handle_lhs_call (t, gimple_call_lhs (t),
1828 : 15666 : gimple_call_return_flags (t) | ERF_NOALIAS,
1829 : : rhsc, fndecl);
1830 : 15666 : get_constraint_for_ptr_offset (gimple_call_lhs (t),
1831 : : NULL_TREE, &lhsc);
1832 : 15666 : get_constraint_for_ptr_offset (gimple_call_arg (t, 0),
1833 : : NULL_TREE, &rhsc);
1834 : 15666 : do_deref (&lhsc);
1835 : 15666 : do_deref (&rhsc);
1836 : 15666 : process_all_all_constraints (lhsc, rhsc);
1837 : 15666 : lhsc.truncate (0);
1838 : 15666 : rhsc.truncate (0);
1839 : : /* For realloc the resulting pointer can be equal to the
1840 : : argument as well. But only doing this wouldn't be
1841 : : correct because with ptr == 0 realloc behaves like malloc. */
1842 : 15666 : if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_REALLOC)
1843 : : {
1844 : 14018 : get_constraint_for (gimple_call_lhs (t), &lhsc);
1845 : 14018 : get_constraint_for (gimple_call_arg (t, 0), &rhsc);
1846 : 14018 : process_all_all_constraints (lhsc, rhsc);
1847 : : }
1848 : 15666 : return true;
1849 : 15666 : }
1850 : : break;
1851 : : /* String / character search functions return a pointer into the
1852 : : source string or NULL. */
1853 : 11113 : case BUILT_IN_INDEX:
1854 : 11113 : case BUILT_IN_STRCHR:
1855 : 11113 : case BUILT_IN_STRRCHR:
1856 : 11113 : case BUILT_IN_MEMCHR:
1857 : 11113 : case BUILT_IN_STRSTR:
1858 : 11113 : case BUILT_IN_STRPBRK:
1859 : 11113 : if (gimple_call_lhs (t))
1860 : : {
1861 : 11113 : tree src = gimple_call_arg (t, 0);
1862 : 11113 : get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
1863 : 11113 : constraint_expr nul;
1864 : 11113 : nul.var = nothing_id;
1865 : 11113 : nul.offset = 0;
1866 : 11113 : nul.type = ADDRESSOF;
1867 : 11113 : rhsc.safe_push (nul);
1868 : 11113 : get_constraint_for (gimple_call_lhs (t), &lhsc);
1869 : 11113 : process_all_all_constraints (lhsc, rhsc);
1870 : : }
1871 : 11113 : return true;
1872 : : /* Pure functions that return something not based on any object and
1873 : : that use the memory pointed to by their arguments (but not
1874 : : transitively). */
1875 : 623651 : case BUILT_IN_STRCMP:
1876 : 623651 : case BUILT_IN_STRCMP_EQ:
1877 : 623651 : case BUILT_IN_STRNCMP:
1878 : 623651 : case BUILT_IN_STRNCMP_EQ:
1879 : 623651 : case BUILT_IN_STRCASECMP:
1880 : 623651 : case BUILT_IN_STRNCASECMP:
1881 : 623651 : case BUILT_IN_MEMCMP:
1882 : 623651 : case BUILT_IN_BCMP:
1883 : 623651 : case BUILT_IN_STRSPN:
1884 : 623651 : case BUILT_IN_STRCSPN:
1885 : 623651 : {
1886 : 623651 : varinfo_t uses = get_call_use_vi (t);
1887 : 623651 : make_any_offset_constraints (uses);
1888 : 623651 : make_constraint_to (uses->id, gimple_call_arg (t, 0));
1889 : 623651 : make_constraint_to (uses->id, gimple_call_arg (t, 1));
1890 : : /* No constraints are necessary for the return value. */
1891 : 623651 : return true;
1892 : : }
1893 : 46279 : case BUILT_IN_STRLEN:
1894 : 46279 : {
1895 : 46279 : varinfo_t uses = get_call_use_vi (t);
1896 : 46279 : make_any_offset_constraints (uses);
1897 : 46279 : make_constraint_to (uses->id, gimple_call_arg (t, 0));
1898 : : /* No constraints are necessary for the return value. */
1899 : 46279 : return true;
1900 : : }
1901 : : case BUILT_IN_OBJECT_SIZE:
1902 : : case BUILT_IN_CONSTANT_P:
1903 : : {
1904 : : /* No constraints are necessary for the return value or the
1905 : : arguments. */
1906 : : return true;
1907 : : }
1908 : : /* Trampolines are special - they set up passing the static
1909 : : frame. */
1910 : 480 : case BUILT_IN_INIT_TRAMPOLINE:
1911 : 480 : {
1912 : 480 : tree tramp = gimple_call_arg (t, 0);
1913 : 480 : tree nfunc = gimple_call_arg (t, 1);
1914 : 480 : tree frame = gimple_call_arg (t, 2);
1915 : 480 : unsigned i;
1916 : 480 : struct constraint_expr lhs, *rhsp;
1917 : 480 : if (in_ipa_mode)
1918 : : {
1919 : 7 : varinfo_t nfi = NULL;
1920 : 7 : gcc_assert (TREE_CODE (nfunc) == ADDR_EXPR);
1921 : 7 : nfi = lookup_vi_for_tree (TREE_OPERAND (nfunc, 0));
1922 : 7 : if (nfi)
1923 : : {
1924 : 7 : lhs = get_function_part_constraint (nfi, fi_static_chain);
1925 : 7 : get_constraint_for (frame, &rhsc);
1926 : 21 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
1927 : 7 : process_constraint (new_constraint (lhs, *rhsp));
1928 : 7 : rhsc.truncate (0);
1929 : :
1930 : : /* Make the frame point to the function for
1931 : : the trampoline adjustment call. */
1932 : 7 : get_constraint_for (tramp, &lhsc);
1933 : 7 : do_deref (&lhsc);
1934 : 7 : get_constraint_for (nfunc, &rhsc);
1935 : 7 : process_all_all_constraints (lhsc, rhsc);
1936 : :
1937 : 7 : return true;
1938 : : }
1939 : : }
1940 : : /* Else fallthru to generic handling which will let
1941 : : the frame escape. */
1942 : 473 : break;
1943 : : }
1944 : 517 : case BUILT_IN_ADJUST_TRAMPOLINE:
1945 : 517 : {
1946 : 517 : tree tramp = gimple_call_arg (t, 0);
1947 : 517 : tree res = gimple_call_lhs (t);
1948 : 517 : if (in_ipa_mode && res)
1949 : : {
1950 : 7 : get_constraint_for (res, &lhsc);
1951 : 7 : get_constraint_for (tramp, &rhsc);
1952 : 7 : do_deref (&rhsc);
1953 : 7 : process_all_all_constraints (lhsc, rhsc);
1954 : : }
1955 : 517 : return true;
1956 : : }
1957 : 4 : CASE_BUILT_IN_TM_STORE (1):
1958 : 4 : CASE_BUILT_IN_TM_STORE (2):
1959 : 4 : CASE_BUILT_IN_TM_STORE (4):
1960 : 4 : CASE_BUILT_IN_TM_STORE (8):
1961 : 4 : CASE_BUILT_IN_TM_STORE (FLOAT):
1962 : 4 : CASE_BUILT_IN_TM_STORE (DOUBLE):
1963 : 4 : CASE_BUILT_IN_TM_STORE (LDOUBLE):
1964 : 4 : CASE_BUILT_IN_TM_STORE (M64):
1965 : 4 : CASE_BUILT_IN_TM_STORE (M128):
1966 : 4 : CASE_BUILT_IN_TM_STORE (M256):
1967 : 4 : {
1968 : 4 : tree addr = gimple_call_arg (t, 0);
1969 : 4 : tree src = gimple_call_arg (t, 1);
1970 : :
1971 : 4 : get_constraint_for (addr, &lhsc);
1972 : 4 : do_deref (&lhsc);
1973 : 4 : get_constraint_for (src, &rhsc);
1974 : 4 : process_all_all_constraints (lhsc, rhsc);
1975 : 4 : return true;
1976 : : }
1977 : 10 : CASE_BUILT_IN_TM_LOAD (1):
1978 : 10 : CASE_BUILT_IN_TM_LOAD (2):
1979 : 10 : CASE_BUILT_IN_TM_LOAD (4):
1980 : 10 : CASE_BUILT_IN_TM_LOAD (8):
1981 : 10 : CASE_BUILT_IN_TM_LOAD (FLOAT):
1982 : 10 : CASE_BUILT_IN_TM_LOAD (DOUBLE):
1983 : 10 : CASE_BUILT_IN_TM_LOAD (LDOUBLE):
1984 : 10 : CASE_BUILT_IN_TM_LOAD (M64):
1985 : 10 : CASE_BUILT_IN_TM_LOAD (M128):
1986 : 10 : CASE_BUILT_IN_TM_LOAD (M256):
1987 : 10 : {
1988 : 10 : tree dest = gimple_call_lhs (t);
1989 : 10 : tree addr = gimple_call_arg (t, 0);
1990 : :
1991 : 10 : get_constraint_for (dest, &lhsc);
1992 : 10 : get_constraint_for (addr, &rhsc);
1993 : 10 : do_deref (&rhsc);
1994 : 10 : process_all_all_constraints (lhsc, rhsc);
1995 : 10 : return true;
1996 : : }
1997 : : /* Variadic argument handling needs to be handled in IPA
1998 : : mode as well. */
1999 : 19952 : case BUILT_IN_VA_START:
2000 : 19952 : {
2001 : 19952 : tree valist = gimple_call_arg (t, 0);
2002 : 19952 : struct constraint_expr rhs, *lhsp;
2003 : 19952 : unsigned i;
2004 : 19952 : get_constraint_for_ptr_offset (valist, NULL_TREE, &lhsc);
2005 : 19952 : do_deref (&lhsc);
2006 : : /* The va_list gets access to pointers in variadic
2007 : : arguments. Which we know in the case of IPA analysis
2008 : : and otherwise are just all nonlocal variables. */
2009 : 19952 : if (in_ipa_mode)
2010 : : {
2011 : 7 : fi = lookup_vi_for_tree (fn->decl);
2012 : 7 : rhs = get_function_part_constraint (fi, ~0);
2013 : 7 : rhs.type = ADDRESSOF;
2014 : : }
2015 : : else
2016 : : {
2017 : : rhs.var = nonlocal_id;
2018 : : rhs.type = ADDRESSOF;
2019 : : rhs.offset = 0;
2020 : : }
2021 : 40071 : FOR_EACH_VEC_ELT (lhsc, i, lhsp)
2022 : 20119 : process_constraint (new_constraint (*lhsp, rhs));
2023 : : /* va_list is clobbered. */
2024 : 19952 : make_constraint_to (get_call_clobber_vi (t)->id, valist);
2025 : 19952 : return true;
2026 : : }
2027 : : /* va_end doesn't have any effect that matters. */
2028 : : case BUILT_IN_VA_END:
2029 : : return true;
2030 : : /* Alternate return. Simply give up for now. */
2031 : 940 : case BUILT_IN_RETURN:
2032 : 940 : {
2033 : 940 : fi = NULL;
2034 : 940 : if (!in_ipa_mode
2035 : 940 : || !(fi = get_vi_for_tree (fn->decl)))
2036 : 940 : make_constraint_from (get_varinfo (escaped_id), anything_id);
2037 : 0 : else if (in_ipa_mode
2038 : : && fi != NULL)
2039 : : {
2040 : 0 : struct constraint_expr lhs, rhs;
2041 : 0 : lhs = get_function_part_constraint (fi, fi_result);
2042 : 0 : rhs.var = anything_id;
2043 : 0 : rhs.offset = 0;
2044 : 0 : rhs.type = SCALAR;
2045 : 0 : process_constraint (new_constraint (lhs, rhs));
2046 : : }
2047 : 940 : return true;
2048 : : }
2049 : 54689 : case BUILT_IN_GOMP_PARALLEL:
2050 : 54689 : case BUILT_IN_GOACC_PARALLEL:
2051 : 54689 : {
2052 : 54689 : if (in_ipa_mode)
2053 : : {
2054 : 13740 : unsigned int fnpos, argpos;
2055 : 13740 : switch (DECL_FUNCTION_CODE (fndecl))
2056 : : {
2057 : : case BUILT_IN_GOMP_PARALLEL:
2058 : : /* __builtin_GOMP_parallel (fn, data, num_threads, flags). */
2059 : : fnpos = 0;
2060 : : argpos = 1;
2061 : : break;
2062 : 13727 : case BUILT_IN_GOACC_PARALLEL:
2063 : : /* __builtin_GOACC_parallel (flags_m, fn, mapnum, hostaddrs,
2064 : : sizes, kinds, ...). */
2065 : 13727 : fnpos = 1;
2066 : 13727 : argpos = 3;
2067 : 13727 : break;
2068 : 0 : default:
2069 : 0 : gcc_unreachable ();
2070 : : }
2071 : :
2072 : 13740 : tree fnarg = gimple_call_arg (t, fnpos);
2073 : 13740 : gcc_assert (TREE_CODE (fnarg) == ADDR_EXPR);
2074 : 13740 : tree fndecl = TREE_OPERAND (fnarg, 0);
2075 : 13740 : if (fndecl_maybe_in_other_partition (fndecl))
2076 : : /* Fallthru to general call handling. */
2077 : : break;
2078 : :
2079 : 13697 : tree arg = gimple_call_arg (t, argpos);
2080 : :
2081 : 13697 : varinfo_t fi = get_vi_for_tree (fndecl);
2082 : 13697 : find_func_aliases_for_call_arg (fi, 0, arg);
2083 : 13697 : return true;
2084 : : }
2085 : : /* Else fallthru to generic call handling. */
2086 : : break;
2087 : : }
2088 : : /* printf-style functions may have hooks to set pointers to
2089 : : point to somewhere into the generated string. Leave them
2090 : : for a later exercise... */
2091 : 43 : default:
2092 : : /* Fallthru to general call handling. */;
2093 : : }
2094 : :
2095 : : return false;
2096 : 5004687 : }
2097 : :
2098 : : /* Create constraints for the call T. */
2099 : :
2100 : : static void
2101 : 17735058 : find_func_aliases_for_call (struct function *fn, gcall *t)
2102 : : {
2103 : 17735058 : tree fndecl = gimple_call_fndecl (t);
2104 : 17735058 : varinfo_t fi;
2105 : :
2106 : 17735058 : if (fndecl != NULL_TREE
2107 : 16400102 : && fndecl_built_in_p (fndecl)
2108 : 22739745 : && find_func_aliases_for_builtin_call (fn, t))
2109 : : return;
2110 : :
2111 : 16465451 : if (gimple_call_internal_p (t, IFN_DEFERRED_INIT))
2112 : : return;
2113 : :
2114 : 16201259 : fi = get_fi_for_callee (t);
2115 : 16201259 : if (!in_ipa_mode
2116 : 236077 : || (fi->decl && fndecl && !fi->is_fn_info))
2117 : : {
2118 : 16019077 : auto_vec<ce_s, 16> rhsc;
2119 : 16019077 : int flags = gimple_call_flags (t);
2120 : :
2121 : : /* Const functions can return their arguments and addresses
2122 : : of global memory but not of escaped memory. */
2123 : 16019077 : if (flags & (ECF_CONST|ECF_NOVOPS))
2124 : : {
2125 : 1529379 : if (gimple_call_lhs (t))
2126 : 920715 : handle_rhs_call (t, &rhsc, implicit_const_eaf_flags, false, false);
2127 : : }
2128 : : /* Pure functions can return addresses in and of memory
2129 : : reachable from their arguments, but they are not an escape
2130 : : point for reachable memory of their arguments. */
2131 : 14489698 : else if (flags & (ECF_PURE|ECF_LOOPING_CONST_OR_PURE))
2132 : 536953 : handle_rhs_call (t, &rhsc, implicit_pure_eaf_flags, false, true);
2133 : : /* If the call is to a replaceable operator delete and results
2134 : : from a delete expression as opposed to a direct call to
2135 : : such operator, then the effects for PTA (in particular
2136 : : the escaping of the pointer) can be ignored. */
2137 : 13952745 : else if (fndecl
2138 : 13322324 : && DECL_IS_OPERATOR_DELETE_P (fndecl)
2139 : 14282077 : && gimple_call_from_new_or_delete (t))
2140 : : ;
2141 : : else
2142 : 13628550 : handle_rhs_call (t, &rhsc, 0, true, true);
2143 : 16019077 : if (gimple_call_lhs (t))
2144 : 5767894 : handle_lhs_call (t, gimple_call_lhs (t),
2145 : : gimple_call_return_flags (t), rhsc, fndecl);
2146 : 16019077 : }
2147 : : else
2148 : : {
2149 : 182182 : auto_vec<ce_s, 2> rhsc;
2150 : 182182 : tree lhsop;
2151 : 182182 : unsigned j;
2152 : :
2153 : : /* Assign all the passed arguments to the appropriate incoming
2154 : : parameters of the function. */
2155 : 972439 : for (j = 0; j < gimple_call_num_args (t); j++)
2156 : : {
2157 : 790257 : tree arg = gimple_call_arg (t, j);
2158 : 790257 : find_func_aliases_for_call_arg (fi, j, arg);
2159 : : }
2160 : :
2161 : : /* If we are returning a value, assign it to the result. */
2162 : 182182 : lhsop = gimple_call_lhs (t);
2163 : 182182 : if (lhsop)
2164 : : {
2165 : 162141 : auto_vec<ce_s, 2> lhsc;
2166 : 162141 : struct constraint_expr rhs;
2167 : 162141 : struct constraint_expr *lhsp;
2168 : 162993 : bool aggr_p = aggregate_value_p (lhsop, gimple_call_fntype (t));
2169 : :
2170 : 162141 : get_constraint_for (lhsop, &lhsc);
2171 : 162141 : rhs = get_function_part_constraint (fi, fi_result);
2172 : 162141 : if (aggr_p)
2173 : : {
2174 : 10 : auto_vec<ce_s, 2> tem;
2175 : 10 : tem.quick_push (rhs);
2176 : 10 : do_deref (&tem);
2177 : 10 : gcc_checking_assert (tem.length () == 1);
2178 : 10 : rhs = tem[0];
2179 : 10 : }
2180 : 324285 : FOR_EACH_VEC_ELT (lhsc, j, lhsp)
2181 : 162144 : process_constraint (new_constraint (*lhsp, rhs));
2182 : :
2183 : : /* If we pass the result decl by reference, honor that. */
2184 : 162141 : if (aggr_p)
2185 : : {
2186 : 10 : struct constraint_expr lhs;
2187 : 10 : struct constraint_expr *rhsp;
2188 : :
2189 : 10 : get_constraint_for_address_of (lhsop, &rhsc);
2190 : 10 : lhs = get_function_part_constraint (fi, fi_result);
2191 : 30 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
2192 : 10 : process_constraint (new_constraint (lhs, *rhsp));
2193 : 10 : rhsc.truncate (0);
2194 : : }
2195 : 162141 : }
2196 : :
2197 : : /* If we use a static chain, pass it along. */
2198 : 182182 : if (gimple_call_chain (t))
2199 : : {
2200 : 278 : struct constraint_expr lhs;
2201 : 278 : struct constraint_expr *rhsp;
2202 : :
2203 : 278 : get_constraint_for (gimple_call_chain (t), &rhsc);
2204 : 278 : lhs = get_function_part_constraint (fi, fi_static_chain);
2205 : 1112 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
2206 : 278 : process_constraint (new_constraint (lhs, *rhsp));
2207 : : }
2208 : 182182 : }
2209 : : }
2210 : :
2211 : : /* Walk statement T setting up aliasing constraints according to the
2212 : : references found in T. This function is the main part of the
2213 : : constraint builder. AI points to auxiliary alias information used
2214 : : when building alias sets and computing alias grouping heuristics. */
2215 : :
2216 : : static void
2217 : 256191379 : find_func_aliases (struct function *fn, gimple *origt)
2218 : : {
2219 : 256191379 : gimple *t = origt;
2220 : 256191379 : auto_vec<ce_s, 16> lhsc;
2221 : 256191379 : auto_vec<ce_s, 16> rhsc;
2222 : 256191379 : varinfo_t fi;
2223 : :
2224 : : /* Now build constraints expressions. */
2225 : 256191379 : if (gimple_code (t) == GIMPLE_PHI)
2226 : : {
2227 : : /* For a phi node, assign all the arguments to
2228 : : the result. */
2229 : 6440104 : get_constraint_for (gimple_phi_result (t), &lhsc);
2230 : 21504837 : for (unsigned i = 0; i < gimple_phi_num_args (t); i++)
2231 : : {
2232 : 15064733 : get_constraint_for_rhs (gimple_phi_arg_def (t, i), &rhsc);
2233 : 15064733 : process_all_all_constraints (lhsc, rhsc);
2234 : 15064733 : rhsc.truncate (0);
2235 : : }
2236 : : }
2237 : : /* In IPA mode, we need to generate constraints to pass call
2238 : : arguments through their calls. There are two cases,
2239 : : either a GIMPLE_CALL returning a value, or just a plain
2240 : : GIMPLE_CALL when we are not.
2241 : :
2242 : : In non-ipa mode, we need to generate constraints for each
2243 : : pointer passed by address. */
2244 : 249751275 : else if (is_gimple_call (t))
2245 : 17735058 : find_func_aliases_for_call (fn, as_a <gcall *> (t));
2246 : :
2247 : : /* Otherwise, just a regular assignment statement. Only care about
2248 : : operations with pointer result, others are dealt with as escape
2249 : : points if they have pointer operands. */
2250 : 232016217 : else if (is_gimple_assign (t))
2251 : : {
2252 : : /* Otherwise, just a regular assignment statement. */
2253 : 79934634 : tree lhsop = gimple_assign_lhs (t);
2254 : 79934634 : tree rhsop = (gimple_num_ops (t) == 2) ? gimple_assign_rhs1 (t) : NULL;
2255 : :
2256 : 62480452 : if (rhsop && TREE_CLOBBER_P (rhsop))
2257 : : /* Ignore clobbers, they don't actually store anything into
2258 : : the LHS. */
2259 : : ;
2260 : 57328557 : else if (rhsop && AGGREGATE_TYPE_P (TREE_TYPE (lhsop)))
2261 : 2560205 : do_structure_copy (lhsop, rhsop);
2262 : : else
2263 : : {
2264 : 72222534 : enum tree_code code = gimple_assign_rhs_code (t);
2265 : :
2266 : 72222534 : get_constraint_for (lhsop, &lhsc);
2267 : :
2268 : 72222534 : if (code == POINTER_PLUS_EXPR)
2269 : 2661071 : get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
2270 : : gimple_assign_rhs2 (t), &rhsc);
2271 : 69561463 : else if (code == POINTER_DIFF_EXPR)
2272 : : /* The result is not a pointer (part). */
2273 : : ;
2274 : 69214553 : else if (code == BIT_AND_EXPR
2275 : 69214553 : && TREE_CODE (gimple_assign_rhs2 (t)) == INTEGER_CST)
2276 : : {
2277 : : /* Aligning a pointer via a BIT_AND_EXPR is offsetting
2278 : : the pointer. Handle it by offsetting it by UNKNOWN. */
2279 : 645089 : get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
2280 : : NULL_TREE, &rhsc);
2281 : : }
2282 : 68569464 : else if (code == TRUNC_DIV_EXPR
2283 : : || code == CEIL_DIV_EXPR
2284 : : || code == FLOOR_DIV_EXPR
2285 : 68569464 : || code == ROUND_DIV_EXPR
2286 : 68569464 : || code == EXACT_DIV_EXPR
2287 : : || code == TRUNC_MOD_EXPR
2288 : 68193728 : || code == CEIL_MOD_EXPR
2289 : : || code == FLOOR_MOD_EXPR
2290 : 68023660 : || code == ROUND_MOD_EXPR)
2291 : : /* Division and modulo transfer the pointer from the LHS. */
2292 : 547351 : get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
2293 : : NULL_TREE, &rhsc);
2294 : 68022113 : else if (CONVERT_EXPR_CODE_P (code)
2295 : 68022113 : || gimple_assign_single_p (t))
2296 : : /* See through conversions, single RHS are handled by
2297 : : get_constraint_for_rhs. */
2298 : 54070229 : get_constraint_for_rhs (rhsop, &rhsc);
2299 : 13951884 : else if (code == COND_EXPR)
2300 : : {
2301 : : /* The result is a merge of both COND_EXPR arms. */
2302 : 9920 : auto_vec<ce_s, 2> tmp;
2303 : 9920 : struct constraint_expr *rhsp;
2304 : 9920 : unsigned i;
2305 : 9920 : get_constraint_for_rhs (gimple_assign_rhs2 (t), &rhsc);
2306 : 9920 : get_constraint_for_rhs (gimple_assign_rhs3 (t), &tmp);
2307 : 39680 : FOR_EACH_VEC_ELT (tmp, i, rhsp)
2308 : 9920 : rhsc.safe_push (*rhsp);
2309 : 9920 : }
2310 : 13941964 : else if (truth_value_p (code))
2311 : : /* Truth value results are not pointer (parts). Or at least
2312 : : very unreasonable obfuscation of a part. */
2313 : : ;
2314 : : else
2315 : : {
2316 : : /* All other operations are possibly offsetting merges. */
2317 : 12552684 : auto_vec<ce_s, 4> tmp;
2318 : 12552684 : struct constraint_expr *rhsp;
2319 : 12552684 : unsigned i, j;
2320 : 12552684 : get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
2321 : : NULL_TREE, &rhsc);
2322 : 37047738 : for (i = 2; i < gimple_num_ops (t); ++i)
2323 : : {
2324 : 11942370 : get_constraint_for_ptr_offset (gimple_op (t, i),
2325 : : NULL_TREE, &tmp);
2326 : 35827110 : FOR_EACH_VEC_ELT (tmp, j, rhsp)
2327 : 11942370 : rhsc.safe_push (*rhsp);
2328 : 11942370 : tmp.truncate (0);
2329 : : }
2330 : 12552684 : }
2331 : 72222534 : process_all_all_constraints (lhsc, rhsc);
2332 : : }
2333 : : /* If there is a store to a global variable the rhs escapes. */
2334 : 79934634 : if ((lhsop = get_base_address (lhsop)) != NULL_TREE
2335 : 79934634 : && DECL_P (lhsop))
2336 : : {
2337 : 22243944 : varinfo_t vi = get_vi_for_tree (lhsop);
2338 : 22243944 : if ((! in_ipa_mode && vi->is_global_var)
2339 : 20644319 : || vi->is_ipa_escape_point)
2340 : 1602191 : make_escape_constraint (rhsop);
2341 : : }
2342 : : }
2343 : : /* Handle escapes through return. */
2344 : 152081583 : else if (gimple_code (t) == GIMPLE_RETURN
2345 : 152081583 : && gimple_return_retval (as_a <greturn *> (t)) != NULL_TREE)
2346 : : {
2347 : 2473992 : greturn *return_stmt = as_a <greturn *> (t);
2348 : 2473992 : tree retval = gimple_return_retval (return_stmt);
2349 : 2473992 : if (!in_ipa_mode)
2350 : 2469734 : make_constraint_to (escaped_return_id, retval);
2351 : : else
2352 : : {
2353 : 4258 : struct constraint_expr lhs ;
2354 : 4258 : struct constraint_expr *rhsp;
2355 : 4258 : unsigned i;
2356 : :
2357 : 4258 : fi = lookup_vi_for_tree (fn->decl);
2358 : 4258 : lhs = get_function_part_constraint (fi, fi_result);
2359 : 4258 : get_constraint_for_rhs (retval, &rhsc);
2360 : 17032 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
2361 : 4258 : process_constraint (new_constraint (lhs, *rhsp));
2362 : : }
2363 : : }
2364 : : /* Handle asms conservatively by adding escape constraints to everything. */
2365 : 256429293 : else if (gasm *asm_stmt = dyn_cast <gasm *> (t))
2366 : : {
2367 : 237914 : unsigned i, noutputs;
2368 : 237914 : const char **oconstraints;
2369 : 237914 : const char *constraint;
2370 : 237914 : bool allows_mem, allows_reg, is_inout;
2371 : :
2372 : 237914 : noutputs = gimple_asm_noutputs (asm_stmt);
2373 : 237914 : oconstraints = XALLOCAVEC (const char *, noutputs);
2374 : :
2375 : 468008 : for (i = 0; i < noutputs; ++i)
2376 : : {
2377 : 230094 : tree link = gimple_asm_output_op (asm_stmt, i);
2378 : 230094 : tree op = TREE_VALUE (link);
2379 : :
2380 : 230094 : constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
2381 : 230094 : oconstraints[i] = constraint;
2382 : 230094 : parse_output_constraint (&constraint, i, 0, 0, &allows_mem,
2383 : : &allows_reg, &is_inout, nullptr);
2384 : :
2385 : : /* A memory constraint makes the address of the operand escape. */
2386 : 230094 : if (!allows_reg && allows_mem)
2387 : : {
2388 : 12740 : auto_vec<ce_s> tmpc;
2389 : 12740 : get_constraint_for_address_of (op, &tmpc);
2390 : 12740 : make_constraints_to (escaped_id, tmpc);
2391 : 12740 : }
2392 : :
2393 : : /* The asm may read global memory, so outputs may point to
2394 : : any global memory. */
2395 : 230094 : if (op)
2396 : : {
2397 : 230094 : auto_vec<ce_s, 2> lhsc;
2398 : 230094 : struct constraint_expr rhsc, *lhsp;
2399 : 230094 : unsigned j;
2400 : 230094 : get_constraint_for (op, &lhsc);
2401 : 230094 : rhsc.var = nonlocal_id;
2402 : 230094 : rhsc.offset = 0;
2403 : 230094 : rhsc.type = SCALAR;
2404 : 920379 : FOR_EACH_VEC_ELT (lhsc, j, lhsp)
2405 : 230097 : process_constraint (new_constraint (*lhsp, rhsc));
2406 : 230094 : }
2407 : : }
2408 : 381897 : for (i = 0; i < gimple_asm_ninputs (asm_stmt); ++i)
2409 : : {
2410 : 143983 : tree link = gimple_asm_input_op (asm_stmt, i);
2411 : 143983 : tree op = TREE_VALUE (link);
2412 : :
2413 : 143983 : constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
2414 : :
2415 : 143983 : parse_input_constraint (&constraint, 0, 0, noutputs, 0, oconstraints,
2416 : : &allows_mem, &allows_reg, nullptr);
2417 : :
2418 : : /* A memory constraint makes the address of the operand escape. */
2419 : 143983 : if (!allows_reg && allows_mem)
2420 : : {
2421 : 13863 : auto_vec<ce_s> tmpc;
2422 : 13863 : get_constraint_for_address_of (op, &tmpc);
2423 : 13863 : make_constraints_to (escaped_id, tmpc);
2424 : 13863 : }
2425 : : /* Strictly we'd only need the constraint to ESCAPED if
2426 : : the asm clobbers memory, otherwise using something
2427 : : along the lines of per-call clobbers/uses would be enough. */
2428 : 130120 : else if (op)
2429 : 130120 : make_escape_constraint (op);
2430 : : }
2431 : : }
2432 : 256191379 : }
2433 : :
2434 : :
2435 : : /* Create a constraint adding to the clobber set of FI the memory
2436 : : pointed to by PTR. */
2437 : :
2438 : : static void
2439 : 0 : process_ipa_clobber (varinfo_t fi, tree ptr)
2440 : : {
2441 : 0 : vec<ce_s> ptrc = vNULL;
2442 : 0 : struct constraint_expr *c, lhs;
2443 : 0 : unsigned i;
2444 : 0 : get_constraint_for_rhs (ptr, &ptrc);
2445 : 0 : lhs = get_function_part_constraint (fi, fi_clobbers);
2446 : 0 : FOR_EACH_VEC_ELT (ptrc, i, c)
2447 : 0 : process_constraint (new_constraint (lhs, *c));
2448 : 0 : ptrc.release ();
2449 : 0 : }
2450 : :
2451 : : /* Walk statement T setting up clobber and use constraints according to the
2452 : : references found in T. This function is a main part of the
2453 : : IPA constraint builder. */
2454 : :
2455 : : static void
2456 : 955006 : find_func_clobbers (struct function *fn, gimple *origt)
2457 : : {
2458 : 955006 : gimple *t = origt;
2459 : 955006 : auto_vec<ce_s, 16> lhsc;
2460 : 955006 : auto_vec<ce_s, 16> rhsc;
2461 : 955006 : varinfo_t fi;
2462 : :
2463 : : /* Add constraints for clobbered/used in IPA mode.
2464 : : We are not interested in what automatic variables are clobbered
2465 : : or used as we only use the information in the caller to which
2466 : : they do not escape. */
2467 : 955006 : gcc_assert (in_ipa_mode);
2468 : :
2469 : : /* If the stmt refers to memory in any way it better had a VUSE. */
2470 : 2037552 : if (gimple_vuse (t) == NULL_TREE)
2471 : : return;
2472 : :
2473 : : /* We'd better have function information for the current function. */
2474 : 625076 : fi = lookup_vi_for_tree (fn->decl);
2475 : 625076 : gcc_assert (fi != NULL);
2476 : :
2477 : : /* Account for stores in assignments and calls. */
2478 : 625076 : if (gimple_vdef (t) != NULL_TREE
2479 : 1150333 : && gimple_has_lhs (t))
2480 : : {
2481 : 328661 : tree lhs = gimple_get_lhs (t);
2482 : 328661 : tree tem = lhs;
2483 : 830930 : while (handled_component_p (tem))
2484 : 173608 : tem = TREE_OPERAND (tem, 0);
2485 : 328661 : if ((DECL_P (tem)
2486 : 186866 : && !auto_var_in_fn_p (tem, fn->decl))
2487 : 323492 : || INDIRECT_REF_P (tem)
2488 : 652153 : || (TREE_CODE (tem) == MEM_REF
2489 : 29689 : && !(TREE_CODE (TREE_OPERAND (tem, 0)) == ADDR_EXPR
2490 : : && auto_var_in_fn_p
2491 : 4170 : (TREE_OPERAND (TREE_OPERAND (tem, 0), 0), fn->decl))))
2492 : : {
2493 : 27412 : struct constraint_expr lhsc, *rhsp;
2494 : 27412 : unsigned i;
2495 : 27412 : lhsc = get_function_part_constraint (fi, fi_clobbers);
2496 : 27412 : get_constraint_for_address_of (lhs, &rhsc);
2497 : 82236 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
2498 : 27412 : process_constraint (new_constraint (lhsc, *rhsp));
2499 : 27412 : rhsc.truncate (0);
2500 : : }
2501 : : }
2502 : :
2503 : : /* Account for uses in assigments and returns. */
2504 : 625076 : if (gimple_assign_single_p (t)
2505 : 625076 : || (gimple_code (t) == GIMPLE_RETURN
2506 : 22976 : && gimple_return_retval (as_a <greturn *> (t)) != NULL_TREE))
2507 : : {
2508 : 356823 : tree rhs = (gimple_assign_single_p (t)
2509 : 356823 : ? gimple_assign_rhs1 (t)
2510 : 4258 : : gimple_return_retval (as_a <greturn *> (t)));
2511 : 356823 : tree tem = rhs;
2512 : 511688 : while (handled_component_p (tem))
2513 : 154865 : tem = TREE_OPERAND (tem, 0);
2514 : 356823 : if ((DECL_P (tem)
2515 : 53291 : && !auto_var_in_fn_p (tem, fn->decl))
2516 : 348080 : || INDIRECT_REF_P (tem)
2517 : 704903 : || (TREE_CODE (tem) == MEM_REF
2518 : 88699 : && !(TREE_CODE (TREE_OPERAND (tem, 0)) == ADDR_EXPR
2519 : : && auto_var_in_fn_p
2520 : 1224 : (TREE_OPERAND (TREE_OPERAND (tem, 0), 0), fn->decl))))
2521 : : {
2522 : 95586 : struct constraint_expr lhs, *rhsp;
2523 : 95586 : unsigned i;
2524 : 95586 : lhs = get_function_part_constraint (fi, fi_uses);
2525 : 95586 : get_constraint_for_address_of (rhs, &rhsc);
2526 : 286758 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
2527 : 95586 : process_constraint (new_constraint (lhs, *rhsp));
2528 : 95586 : rhsc.truncate (0);
2529 : : }
2530 : : }
2531 : :
2532 : 625076 : if (gcall *call_stmt = dyn_cast <gcall *> (t))
2533 : : {
2534 : 249493 : varinfo_t cfi = NULL;
2535 : 249493 : tree decl = gimple_call_fndecl (t);
2536 : 249493 : struct constraint_expr lhs, rhs;
2537 : 249493 : unsigned i, j;
2538 : :
2539 : : /* For builtins we do not have separate function info. For those
2540 : : we do not generate escapes for we have to generate clobbers/uses. */
2541 : 249493 : if (gimple_call_builtin_p (t, BUILT_IN_NORMAL))
2542 : 36018 : switch (DECL_FUNCTION_CODE (decl))
2543 : : {
2544 : : /* The following functions use and clobber memory pointed to
2545 : : by their arguments. */
2546 : 162 : case BUILT_IN_STRCPY:
2547 : 162 : case BUILT_IN_STRNCPY:
2548 : 162 : case BUILT_IN_BCOPY:
2549 : 162 : case BUILT_IN_MEMCPY:
2550 : 162 : case BUILT_IN_MEMMOVE:
2551 : 162 : case BUILT_IN_MEMPCPY:
2552 : 162 : case BUILT_IN_STPCPY:
2553 : 162 : case BUILT_IN_STPNCPY:
2554 : 162 : case BUILT_IN_STRCAT:
2555 : 162 : case BUILT_IN_STRNCAT:
2556 : 162 : case BUILT_IN_STRCPY_CHK:
2557 : 162 : case BUILT_IN_STRNCPY_CHK:
2558 : 162 : case BUILT_IN_MEMCPY_CHK:
2559 : 162 : case BUILT_IN_MEMMOVE_CHK:
2560 : 162 : case BUILT_IN_MEMPCPY_CHK:
2561 : 162 : case BUILT_IN_STPCPY_CHK:
2562 : 162 : case BUILT_IN_STPNCPY_CHK:
2563 : 162 : case BUILT_IN_STRCAT_CHK:
2564 : 162 : case BUILT_IN_STRNCAT_CHK:
2565 : 162 : {
2566 : 324 : tree dest = gimple_call_arg (t, (DECL_FUNCTION_CODE (decl)
2567 : : == BUILT_IN_BCOPY ? 1 : 0));
2568 : 324 : tree src = gimple_call_arg (t, (DECL_FUNCTION_CODE (decl)
2569 : 162 : == BUILT_IN_BCOPY ? 0 : 1));
2570 : 162 : unsigned i;
2571 : 162 : struct constraint_expr *rhsp, *lhsp;
2572 : 162 : get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
2573 : 162 : lhs = get_function_part_constraint (fi, fi_clobbers);
2574 : 486 : FOR_EACH_VEC_ELT (lhsc, i, lhsp)
2575 : 162 : process_constraint (new_constraint (lhs, *lhsp));
2576 : 162 : get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
2577 : 162 : lhs = get_function_part_constraint (fi, fi_uses);
2578 : 486 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
2579 : 162 : process_constraint (new_constraint (lhs, *rhsp));
2580 : : return;
2581 : : }
2582 : : /* The following function clobbers memory pointed to by
2583 : : its argument. */
2584 : 890 : case BUILT_IN_MEMSET:
2585 : 890 : case BUILT_IN_MEMSET_CHK:
2586 : 890 : case BUILT_IN_POSIX_MEMALIGN:
2587 : 890 : {
2588 : 890 : tree dest = gimple_call_arg (t, 0);
2589 : 890 : unsigned i;
2590 : 890 : ce_s *lhsp;
2591 : 890 : get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
2592 : 890 : lhs = get_function_part_constraint (fi, fi_clobbers);
2593 : 2670 : FOR_EACH_VEC_ELT (lhsc, i, lhsp)
2594 : 890 : process_constraint (new_constraint (lhs, *lhsp));
2595 : : return;
2596 : : }
2597 : : /* The following functions clobber their second and third
2598 : : arguments. */
2599 : 0 : case BUILT_IN_SINCOS:
2600 : 0 : case BUILT_IN_SINCOSF:
2601 : 0 : case BUILT_IN_SINCOSL:
2602 : 0 : {
2603 : 0 : process_ipa_clobber (fi, gimple_call_arg (t, 1));
2604 : 0 : process_ipa_clobber (fi, gimple_call_arg (t, 2));
2605 : 0 : return;
2606 : : }
2607 : : /* The following functions clobber their second argument. */
2608 : 0 : case BUILT_IN_FREXP:
2609 : 0 : case BUILT_IN_FREXPF:
2610 : 0 : case BUILT_IN_FREXPL:
2611 : 0 : case BUILT_IN_LGAMMA_R:
2612 : 0 : case BUILT_IN_LGAMMAF_R:
2613 : 0 : case BUILT_IN_LGAMMAL_R:
2614 : 0 : case BUILT_IN_GAMMA_R:
2615 : 0 : case BUILT_IN_GAMMAF_R:
2616 : 0 : case BUILT_IN_GAMMAL_R:
2617 : 0 : case BUILT_IN_MODF:
2618 : 0 : case BUILT_IN_MODFF:
2619 : 0 : case BUILT_IN_MODFL:
2620 : 0 : {
2621 : 0 : process_ipa_clobber (fi, gimple_call_arg (t, 1));
2622 : 0 : return;
2623 : : }
2624 : : /* The following functions clobber their third argument. */
2625 : 0 : case BUILT_IN_REMQUO:
2626 : 0 : case BUILT_IN_REMQUOF:
2627 : 0 : case BUILT_IN_REMQUOL:
2628 : 0 : {
2629 : 0 : process_ipa_clobber (fi, gimple_call_arg (t, 2));
2630 : 0 : return;
2631 : : }
2632 : : /* The following functions use what their first argument
2633 : : points to. */
2634 : 60 : case BUILT_IN_STRDUP:
2635 : 60 : case BUILT_IN_STRNDUP:
2636 : 60 : case BUILT_IN_REALLOC:
2637 : 60 : case BUILT_IN_INDEX:
2638 : 60 : case BUILT_IN_STRCHR:
2639 : 60 : case BUILT_IN_STRRCHR:
2640 : 60 : case BUILT_IN_MEMCHR:
2641 : 60 : {
2642 : 60 : tree src = gimple_call_arg (t, 0);
2643 : 60 : get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
2644 : 60 : lhs = get_function_part_constraint (fi, fi_uses);
2645 : 60 : struct constraint_expr *rhsp;
2646 : 180 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
2647 : 60 : process_constraint (new_constraint (lhs, *rhsp));
2648 : : return;
2649 : : }
2650 : : /* The following functions use what their first and second argument
2651 : : point to. */
2652 : 16 : case BUILT_IN_STRSTR:
2653 : 16 : case BUILT_IN_STRPBRK:
2654 : 16 : {
2655 : 16 : tree src = gimple_call_arg (t, 0);
2656 : 16 : get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
2657 : 16 : lhs = get_function_part_constraint (fi, fi_uses);
2658 : 16 : struct constraint_expr *rhsp;
2659 : 48 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
2660 : 16 : process_constraint (new_constraint (lhs, *rhsp));
2661 : 16 : rhsc.truncate (0);
2662 : 16 : src = gimple_call_arg (t, 1);
2663 : 16 : get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
2664 : 242811 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
2665 : 16 : process_constraint (new_constraint (lhs, *rhsp));
2666 : : return;
2667 : : }
2668 : : /* The following functions neither read nor clobber memory. */
2669 : : case BUILT_IN_ASSUME_ALIGNED:
2670 : : case BUILT_IN_FREE:
2671 : : return;
2672 : : /* Trampolines are of no interest to us. */
2673 : : case BUILT_IN_INIT_TRAMPOLINE:
2674 : : case BUILT_IN_ADJUST_TRAMPOLINE:
2675 : : return;
2676 : : case BUILT_IN_VA_START:
2677 : : case BUILT_IN_VA_END:
2678 : : return;
2679 : 13740 : case BUILT_IN_GOMP_PARALLEL:
2680 : 13740 : case BUILT_IN_GOACC_PARALLEL:
2681 : 13740 : {
2682 : 13740 : unsigned int fnpos, argpos;
2683 : 13740 : unsigned int implicit_use_args[2];
2684 : 13740 : unsigned int num_implicit_use_args = 0;
2685 : 13740 : switch (DECL_FUNCTION_CODE (decl))
2686 : : {
2687 : : case BUILT_IN_GOMP_PARALLEL:
2688 : : /* __builtin_GOMP_parallel (fn, data, num_threads, flags). */
2689 : : fnpos = 0;
2690 : : argpos = 1;
2691 : : break;
2692 : 13727 : case BUILT_IN_GOACC_PARALLEL:
2693 : : /* __builtin_GOACC_parallel (flags_m, fn, mapnum, hostaddrs,
2694 : : sizes, kinds, ...). */
2695 : 13727 : fnpos = 1;
2696 : 13727 : argpos = 3;
2697 : 13727 : implicit_use_args[num_implicit_use_args++] = 4;
2698 : 13727 : implicit_use_args[num_implicit_use_args++] = 5;
2699 : 13727 : break;
2700 : 0 : default:
2701 : 0 : gcc_unreachable ();
2702 : : }
2703 : :
2704 : 13740 : tree fnarg = gimple_call_arg (t, fnpos);
2705 : 13740 : gcc_assert (TREE_CODE (fnarg) == ADDR_EXPR);
2706 : 13740 : tree fndecl = TREE_OPERAND (fnarg, 0);
2707 : 13740 : if (fndecl_maybe_in_other_partition (fndecl))
2708 : : /* Fallthru to general call handling. */
2709 : : break;
2710 : :
2711 : 13697 : varinfo_t cfi = get_vi_for_tree (fndecl);
2712 : :
2713 : 13697 : tree arg = gimple_call_arg (t, argpos);
2714 : :
2715 : : /* Parameter passed by value is used. */
2716 : 13697 : lhs = get_function_part_constraint (fi, fi_uses);
2717 : 13697 : struct constraint_expr *rhsp;
2718 : 13697 : get_constraint_for (arg, &rhsc);
2719 : 41091 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
2720 : 13697 : process_constraint (new_constraint (lhs, *rhsp));
2721 : 13697 : rhsc.truncate (0);
2722 : :
2723 : : /* Handle parameters used by the call, but not used in cfi, as
2724 : : implicitly used by cfi. */
2725 : 13697 : lhs = get_function_part_constraint (cfi, fi_uses);
2726 : 41071 : for (unsigned i = 0; i < num_implicit_use_args; ++i)
2727 : : {
2728 : 27374 : tree arg = gimple_call_arg (t, implicit_use_args[i]);
2729 : 27374 : get_constraint_for (arg, &rhsc);
2730 : 82122 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
2731 : 27374 : process_constraint (new_constraint (lhs, *rhsp));
2732 : 27374 : rhsc.truncate (0);
2733 : : }
2734 : :
2735 : : /* The caller clobbers what the callee does. */
2736 : 13697 : lhs = get_function_part_constraint (fi, fi_clobbers);
2737 : 13697 : rhs = get_function_part_constraint (cfi, fi_clobbers);
2738 : 13697 : process_constraint (new_constraint (lhs, rhs));
2739 : :
2740 : : /* The caller uses what the callee does. */
2741 : 13697 : lhs = get_function_part_constraint (fi, fi_uses);
2742 : 13697 : rhs = get_function_part_constraint (cfi, fi_uses);
2743 : 13697 : process_constraint (new_constraint (lhs, rhs));
2744 : :
2745 : 13697 : return;
2746 : : }
2747 : : /* printf-style functions may have hooks to set pointers to
2748 : : point to somewhere into the generated string. Leave them
2749 : : for a later exercise... */
2750 : : default:
2751 : : /* Fallthru to general call handling. */;
2752 : : }
2753 : :
2754 : : /* Parameters passed by value are used. */
2755 : 232738 : lhs = get_function_part_constraint (fi, fi_uses);
2756 : 1142973 : for (i = 0; i < gimple_call_num_args (t); i++)
2757 : : {
2758 : 910235 : struct constraint_expr *rhsp;
2759 : 910235 : tree arg = gimple_call_arg (t, i);
2760 : :
2761 : 1800478 : if (TREE_CODE (arg) == SSA_NAME
2762 : 910235 : || is_gimple_min_invariant (arg))
2763 : 890243 : continue;
2764 : :
2765 : 19992 : get_constraint_for_address_of (arg, &rhsc);
2766 : 59977 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
2767 : 19993 : process_constraint (new_constraint (lhs, *rhsp));
2768 : 19992 : rhsc.truncate (0);
2769 : : }
2770 : :
2771 : : /* Build constraints for propagating clobbers/uses along the
2772 : : callgraph edges. */
2773 : 232738 : cfi = get_fi_for_callee (call_stmt);
2774 : 232738 : if (cfi->id == anything_id)
2775 : : {
2776 : 346552 : if (gimple_vdef (t))
2777 : 121552 : make_constraint_from (first_vi_for_offset (fi, fi_clobbers),
2778 : : anything_id);
2779 : 173276 : make_constraint_from (first_vi_for_offset (fi, fi_uses),
2780 : : anything_id);
2781 : 173276 : return;
2782 : : }
2783 : :
2784 : : /* For callees without function info (that's external functions),
2785 : : ESCAPED is clobbered and used. */
2786 : 59462 : if (cfi->decl
2787 : 59461 : && TREE_CODE (cfi->decl) == FUNCTION_DECL
2788 : 58783 : && !cfi->is_fn_info)
2789 : : {
2790 : 52732 : varinfo_t vi;
2791 : :
2792 : 105464 : if (gimple_vdef (t))
2793 : 52547 : make_copy_constraint (first_vi_for_offset (fi, fi_clobbers),
2794 : : escaped_id);
2795 : 52732 : make_copy_constraint (first_vi_for_offset (fi, fi_uses), escaped_id);
2796 : :
2797 : : /* Also honor the call statement use/clobber info. */
2798 : 52732 : if ((vi = lookup_call_clobber_vi (call_stmt)) != NULL)
2799 : 52456 : make_copy_constraint (first_vi_for_offset (fi, fi_clobbers),
2800 : 52456 : vi->id);
2801 : 52732 : if ((vi = lookup_call_use_vi (call_stmt)) != NULL)
2802 : 52456 : make_copy_constraint (first_vi_for_offset (fi, fi_uses),
2803 : 52456 : vi->id);
2804 : 52732 : return;
2805 : : }
2806 : :
2807 : : /* Otherwise the caller clobbers and uses what the callee does.
2808 : : ??? This should use a new complex constraint that filters
2809 : : local variables of the callee. */
2810 : 13460 : if (gimple_vdef (t))
2811 : : {
2812 : 5716 : lhs = get_function_part_constraint (fi, fi_clobbers);
2813 : 5716 : rhs = get_function_part_constraint (cfi, fi_clobbers);
2814 : 5716 : process_constraint (new_constraint (lhs, rhs));
2815 : : }
2816 : 6730 : lhs = get_function_part_constraint (fi, fi_uses);
2817 : 6730 : rhs = get_function_part_constraint (cfi, fi_uses);
2818 : 6730 : process_constraint (new_constraint (lhs, rhs));
2819 : : }
2820 : 375583 : else if (gimple_code (t) == GIMPLE_ASM)
2821 : : {
2822 : : /* ??? Ick. We can do better. */
2823 : 42 : if (gimple_vdef (t))
2824 : 42 : make_constraint_from (first_vi_for_offset (fi, fi_clobbers),
2825 : : anything_id);
2826 : 42 : make_constraint_from (first_vi_for_offset (fi, fi_uses),
2827 : : anything_id);
2828 : : }
2829 : 955006 : }
2830 : :
2831 : :
2832 : : /* This structure is used during pushing fields onto the fieldstack
2833 : : to track the offset of the field, since bitpos_of_field gives it
2834 : : relative to its immediate containing type, and we want it relative
2835 : : to the ultimate containing object. */
2836 : :
2837 : : struct fieldoff
2838 : : {
2839 : : /* Offset from the base of the base containing object to this field. */
2840 : : HOST_WIDE_INT offset;
2841 : :
2842 : : /* Size, in bits, of the field. */
2843 : : unsigned HOST_WIDE_INT size;
2844 : :
2845 : : unsigned has_unknown_size : 1;
2846 : :
2847 : : unsigned must_have_pointers : 1;
2848 : :
2849 : : unsigned may_have_pointers : 1;
2850 : :
2851 : : unsigned only_restrict_pointers : 1;
2852 : :
2853 : : tree restrict_pointed_type;
2854 : : };
2855 : : typedef struct fieldoff fieldoff_s;
2856 : :
2857 : :
2858 : : /* qsort comparison function for two fieldoff's PA and PB. */
2859 : :
2860 : : static int
2861 : 188330794 : fieldoff_compare (const void *pa, const void *pb)
2862 : : {
2863 : 188330794 : const fieldoff_s *foa = (const fieldoff_s *)pa;
2864 : 188330794 : const fieldoff_s *fob = (const fieldoff_s *)pb;
2865 : 188330794 : unsigned HOST_WIDE_INT foasize, fobsize;
2866 : :
2867 : 188330794 : if (foa->offset < fob->offset)
2868 : : return -1;
2869 : 98204626 : else if (foa->offset > fob->offset)
2870 : : return 1;
2871 : :
2872 : 1346622 : foasize = foa->size;
2873 : 1346622 : fobsize = fob->size;
2874 : 1346622 : if (foasize < fobsize)
2875 : : return -1;
2876 : 1122537 : else if (foasize > fobsize)
2877 : 128954 : return 1;
2878 : : return 0;
2879 : : }
2880 : :
2881 : : /* Sort a fieldstack according to the field offset and sizes. */
2882 : : static void
2883 : 7564200 : sort_fieldstack (vec<fieldoff_s> &fieldstack)
2884 : : {
2885 : 7564200 : fieldstack.qsort (fieldoff_compare);
2886 : 7564200 : }
2887 : :
2888 : : /* Return true if T is a type that can have subvars. */
2889 : :
2890 : : static inline bool
2891 : 65721842 : type_can_have_subvars (const_tree t)
2892 : : {
2893 : : /* Aggregates without overlapping fields can have subvars. */
2894 : 5823073 : return TREE_CODE (t) == RECORD_TYPE;
2895 : : }
2896 : :
2897 : : /* Return true if V is a tree that we can have subvars for.
2898 : : Normally, this is any aggregate type. Also complex
2899 : : types which are not gimple registers can have subvars. */
2900 : :
2901 : : static inline bool
2902 : 120559862 : var_can_have_subvars (const_tree v)
2903 : : {
2904 : : /* Volatile variables should never have subvars. */
2905 : 120559862 : if (TREE_THIS_VOLATILE (v))
2906 : : return false;
2907 : :
2908 : : /* Non decls or memory tags can never have subvars. */
2909 : 120268113 : if (!DECL_P (v))
2910 : : return false;
2911 : :
2912 : 59898769 : return type_can_have_subvars (TREE_TYPE (v));
2913 : : }
2914 : :
2915 : : /* Return true if T is a type that does contain pointers. */
2916 : :
2917 : : static bool
2918 : 33702059 : type_must_have_pointers (tree type)
2919 : : {
2920 : 34443436 : if (POINTER_TYPE_P (type))
2921 : : return true;
2922 : :
2923 : 19334125 : if (TREE_CODE (type) == ARRAY_TYPE)
2924 : 741377 : return type_must_have_pointers (TREE_TYPE (type));
2925 : :
2926 : : /* A function or method can have pointers as arguments, so track
2927 : : those separately. */
2928 : 18592748 : if (FUNC_OR_METHOD_TYPE_P (type))
2929 : 0 : return true;
2930 : :
2931 : : return false;
2932 : : }
2933 : :
2934 : : static bool
2935 : 33702059 : field_must_have_pointers (tree t)
2936 : : {
2937 : 33702059 : return type_must_have_pointers (TREE_TYPE (t));
2938 : : }
2939 : :
2940 : : /* Given a TYPE, and a vector of field offsets FIELDSTACK, push all
2941 : : the fields of TYPE onto fieldstack, recording their offsets along
2942 : : the way.
2943 : :
2944 : : OFFSET is used to keep track of the offset in this entire
2945 : : structure, rather than just the immediately containing structure.
2946 : : Returns false if the caller is supposed to handle the field we
2947 : : recursed for. */
2948 : :
2949 : : static bool
2950 : 14070932 : push_fields_onto_fieldstack (tree type, vec<fieldoff_s> *fieldstack,
2951 : : unsigned HOST_WIDE_INT offset)
2952 : : {
2953 : 14070932 : tree field;
2954 : 14070932 : bool empty_p = true;
2955 : :
2956 : 14070932 : if (TREE_CODE (type) != RECORD_TYPE)
2957 : : return false;
2958 : :
2959 : : /* If the vector of fields is growing too big, bail out early.
2960 : : Callers check for vec::length <= param_max_fields_for_field_sensitive, make
2961 : : sure this fails. */
2962 : 14070932 : if (fieldstack->length () > (unsigned)param_max_fields_for_field_sensitive)
2963 : : return false;
2964 : :
2965 : 320855505 : for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
2966 : 306972526 : if (TREE_CODE (field) == FIELD_DECL)
2967 : : {
2968 : 39970044 : bool push = false;
2969 : 39970044 : unsigned HOST_WIDE_INT foff = bitpos_of_field (field);
2970 : 39970044 : tree field_type = TREE_TYPE (field);
2971 : :
2972 : 39970044 : if (!var_can_have_subvars (field)
2973 : 6475845 : || TREE_CODE (field_type) == QUAL_UNION_TYPE
2974 : 46445889 : || TREE_CODE (field_type) == UNION_TYPE)
2975 : : push = true;
2976 : 6475845 : else if (!push_fields_onto_fieldstack
2977 : 6475845 : (field_type, fieldstack, offset + foff)
2978 : 6475845 : && (DECL_SIZE (field)
2979 : 1106663 : && !integer_zerop (DECL_SIZE (field))))
2980 : : /* Empty structures may have actual size, like in C++. So
2981 : : see if we didn't push any subfields and the size is
2982 : : nonzero, push the field onto the stack. */
2983 : : push = true;
2984 : :
2985 : : if (push)
2986 : : {
2987 : 33702059 : fieldoff_s *pair = NULL;
2988 : 33702059 : bool has_unknown_size = false;
2989 : 33702059 : bool must_have_pointers_p;
2990 : :
2991 : 33702059 : if (!fieldstack->is_empty ())
2992 : 26371441 : pair = &fieldstack->last ();
2993 : :
2994 : : /* If there isn't anything at offset zero, create sth. */
2995 : 26371441 : if (!pair
2996 : 7330618 : && offset + foff != 0)
2997 : : {
2998 : 8905 : fieldoff_s e
2999 : 8905 : = {0, offset + foff, false, false, true, false, NULL_TREE};
3000 : 8905 : pair = fieldstack->safe_push (e);
3001 : : }
3002 : :
3003 : 33702059 : if (!DECL_SIZE (field)
3004 : 33702059 : || !tree_fits_uhwi_p (DECL_SIZE (field)))
3005 : : has_unknown_size = true;
3006 : :
3007 : : /* If adjacent fields do not contain pointers merge them. */
3008 : 33702059 : must_have_pointers_p = field_must_have_pointers (field);
3009 : 33702059 : if (pair
3010 : 33702059 : && !has_unknown_size
3011 : 26349486 : && !must_have_pointers_p
3012 : 16397087 : && !pair->must_have_pointers
3013 : 11729503 : && !pair->has_unknown_size
3014 : 11729500 : && pair->offset + pair->size == offset + foff)
3015 : : {
3016 : 11150779 : pair->size += tree_to_uhwi (DECL_SIZE (field));
3017 : : }
3018 : : else
3019 : : {
3020 : 22551280 : fieldoff_s e;
3021 : 22551280 : e.offset = offset + foff;
3022 : 22551280 : e.has_unknown_size = has_unknown_size;
3023 : 22551280 : if (!has_unknown_size)
3024 : 22520393 : e.size = tree_to_uhwi (DECL_SIZE (field));
3025 : : else
3026 : 30887 : e.size = -1;
3027 : 22551280 : e.must_have_pointers = must_have_pointers_p;
3028 : 22551280 : e.may_have_pointers = true;
3029 : 22551280 : e.only_restrict_pointers
3030 : 22551280 : = (!has_unknown_size
3031 : 22520393 : && POINTER_TYPE_P (field_type)
3032 : 37652211 : && TYPE_RESTRICT (field_type));
3033 : 22551280 : if (e.only_restrict_pointers)
3034 : 106835 : e.restrict_pointed_type = TREE_TYPE (field_type);
3035 : 22551280 : fieldstack->safe_push (e);
3036 : : }
3037 : : }
3038 : :
3039 : : empty_p = false;
3040 : : }
3041 : :
3042 : 13882979 : return !empty_p;
3043 : : }
3044 : :
3045 : : /* Count the number of arguments DECL has, and set IS_VARARGS to true
3046 : : if it is a varargs function. */
3047 : :
3048 : : static unsigned int
3049 : 23378 : count_num_arguments (tree decl, bool *is_varargs)
3050 : : {
3051 : 23378 : unsigned int num = 0;
3052 : 23378 : tree t;
3053 : :
3054 : : /* Capture named arguments for K&R functions. They do not
3055 : : have a prototype and thus no TYPE_ARG_TYPES. */
3056 : 48500 : for (t = DECL_ARGUMENTS (decl); t; t = DECL_CHAIN (t))
3057 : 25122 : ++num;
3058 : :
3059 : : /* Check if the function has variadic arguments. */
3060 : 48500 : for (t = TYPE_ARG_TYPES (TREE_TYPE (decl)); t; t = TREE_CHAIN (t))
3061 : 48493 : if (TREE_VALUE (t) == void_type_node)
3062 : : break;
3063 : 23378 : if (!t)
3064 : 7 : *is_varargs = true;
3065 : :
3066 : 23378 : return num;
3067 : : }
3068 : :
3069 : : /* Creation function node for DECL, using NAME, and return the index
3070 : : of the variable we've created for the function. If NONLOCAL_p, create
3071 : : initial constraints. */
3072 : :
3073 : : static varinfo_t
3074 : 23378 : create_function_info_for (tree decl, const char *name, bool add_id,
3075 : : bool nonlocal_p)
3076 : : {
3077 : 23378 : struct function *fn = DECL_STRUCT_FUNCTION (decl);
3078 : 23378 : varinfo_t vi, prev_vi;
3079 : 23378 : tree arg;
3080 : 23378 : unsigned int i;
3081 : 23378 : bool is_varargs = false;
3082 : 23378 : unsigned int num_args = count_num_arguments (decl, &is_varargs);
3083 : :
3084 : : /* Create the variable info. */
3085 : :
3086 : 23378 : vi = new_var_info (decl, name, add_id);
3087 : 23378 : vi->offset = 0;
3088 : 23378 : vi->size = 1;
3089 : 23378 : vi->fullsize = fi_parm_base + num_args;
3090 : 23378 : vi->is_fn_info = 1;
3091 : 23378 : vi->may_have_pointers = false;
3092 : 23378 : if (is_varargs)
3093 : 7 : vi->fullsize = ~0;
3094 : 23378 : insert_vi_for_tree (vi->decl, vi);
3095 : :
3096 : 23378 : prev_vi = vi;
3097 : :
3098 : : /* Create a variable for things the function clobbers and one for
3099 : : things the function uses. */
3100 : 23378 : {
3101 : 23378 : varinfo_t clobbervi, usevi;
3102 : 23378 : const char *newname;
3103 : 23378 : char *tempname;
3104 : :
3105 : 23378 : tempname = xasprintf ("%s.clobber", name);
3106 : 23378 : newname = ggc_strdup (tempname);
3107 : 23378 : free (tempname);
3108 : :
3109 : 23378 : clobbervi = new_var_info (NULL, newname, false);
3110 : 23378 : clobbervi->offset = fi_clobbers;
3111 : 23378 : clobbervi->size = 1;
3112 : 23378 : clobbervi->fullsize = vi->fullsize;
3113 : 23378 : clobbervi->is_full_var = true;
3114 : 23378 : clobbervi->is_global_var = false;
3115 : 23378 : clobbervi->is_reg_var = true;
3116 : :
3117 : 23378 : gcc_assert (prev_vi->offset < clobbervi->offset);
3118 : 23378 : prev_vi->next = clobbervi->id;
3119 : 23378 : prev_vi = clobbervi;
3120 : :
3121 : 23378 : tempname = xasprintf ("%s.use", name);
3122 : 23378 : newname = ggc_strdup (tempname);
3123 : 23378 : free (tempname);
3124 : :
3125 : 23378 : usevi = new_var_info (NULL, newname, false);
3126 : 23378 : usevi->offset = fi_uses;
3127 : 23378 : usevi->size = 1;
3128 : 23378 : usevi->fullsize = vi->fullsize;
3129 : 23378 : usevi->is_full_var = true;
3130 : 23378 : usevi->is_global_var = false;
3131 : 23378 : usevi->is_reg_var = true;
3132 : :
3133 : 23378 : gcc_assert (prev_vi->offset < usevi->offset);
3134 : 23378 : prev_vi->next = usevi->id;
3135 : 23378 : prev_vi = usevi;
3136 : : }
3137 : :
3138 : : /* And one for the static chain. */
3139 : 23378 : if (fn->static_chain_decl != NULL_TREE)
3140 : : {
3141 : 139 : varinfo_t chainvi;
3142 : 139 : const char *newname;
3143 : 139 : char *tempname;
3144 : :
3145 : 139 : tempname = xasprintf ("%s.chain", name);
3146 : 139 : newname = ggc_strdup (tempname);
3147 : 139 : free (tempname);
3148 : :
3149 : 139 : chainvi = new_var_info (fn->static_chain_decl, newname, false);
3150 : 139 : chainvi->offset = fi_static_chain;
3151 : 139 : chainvi->size = 1;
3152 : 139 : chainvi->fullsize = vi->fullsize;
3153 : 139 : chainvi->is_full_var = true;
3154 : 139 : chainvi->is_global_var = false;
3155 : :
3156 : 139 : insert_vi_for_tree (fn->static_chain_decl, chainvi);
3157 : :
3158 : 139 : if (nonlocal_p
3159 : 0 : && chainvi->may_have_pointers)
3160 : 0 : make_constraint_from (chainvi, nonlocal_id);
3161 : :
3162 : 139 : gcc_assert (prev_vi->offset < chainvi->offset);
3163 : 139 : prev_vi->next = chainvi->id;
3164 : 139 : prev_vi = chainvi;
3165 : : }
3166 : :
3167 : : /* Create a variable for the return var. */
3168 : 23378 : if (DECL_RESULT (decl) != NULL
3169 : 23378 : || !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
3170 : : {
3171 : 23378 : varinfo_t resultvi;
3172 : 23378 : const char *newname;
3173 : 23378 : char *tempname;
3174 : 23378 : tree resultdecl = decl;
3175 : :
3176 : 23378 : if (DECL_RESULT (decl))
3177 : 23378 : resultdecl = DECL_RESULT (decl);
3178 : :
3179 : 23378 : tempname = xasprintf ("%s.result", name);
3180 : 23378 : newname = ggc_strdup (tempname);
3181 : 23378 : free (tempname);
3182 : :
3183 : 23378 : resultvi = new_var_info (resultdecl, newname, false);
3184 : 23378 : resultvi->offset = fi_result;
3185 : 23378 : resultvi->size = 1;
3186 : 23378 : resultvi->fullsize = vi->fullsize;
3187 : 23378 : resultvi->is_full_var = true;
3188 : 23378 : if (DECL_RESULT (decl))
3189 : 23378 : resultvi->may_have_pointers = true;
3190 : :
3191 : 23378 : if (DECL_RESULT (decl))
3192 : 23378 : insert_vi_for_tree (DECL_RESULT (decl), resultvi);
3193 : :
3194 : 23378 : if (nonlocal_p
3195 : 6977 : && DECL_RESULT (decl)
3196 : 30355 : && DECL_BY_REFERENCE (DECL_RESULT (decl)))
3197 : 6 : make_constraint_from (resultvi, nonlocal_id);
3198 : :
3199 : 23378 : gcc_assert (prev_vi->offset < resultvi->offset);
3200 : 23378 : prev_vi->next = resultvi->id;
3201 : 23378 : prev_vi = resultvi;
3202 : : }
3203 : :
3204 : : /* We also need to make function return values escape. Nothing
3205 : : escapes by returning from main though. */
3206 : 23378 : if (nonlocal_p
3207 : 23378 : && !MAIN_NAME_P (DECL_NAME (decl)))
3208 : : {
3209 : 3466 : varinfo_t fi, rvi;
3210 : 3466 : fi = lookup_vi_for_tree (decl);
3211 : 3466 : rvi = first_vi_for_offset (fi, fi_result);
3212 : 3466 : if (rvi && rvi->offset == fi_result)
3213 : 3466 : make_copy_constraint (get_varinfo (escaped_id), rvi->id);
3214 : : }
3215 : :
3216 : : /* Set up variables for each argument. */
3217 : 23378 : arg = DECL_ARGUMENTS (decl);
3218 : 48500 : for (i = 0; i < num_args; i++)
3219 : : {
3220 : 25122 : varinfo_t argvi;
3221 : 25122 : const char *newname;
3222 : 25122 : char *tempname;
3223 : 25122 : tree argdecl = decl;
3224 : :
3225 : 25122 : if (arg)
3226 : 25122 : argdecl = arg;
3227 : :
3228 : 25122 : tempname = xasprintf ("%s.arg%d", name, i);
3229 : 25122 : newname = ggc_strdup (tempname);
3230 : 25122 : free (tempname);
3231 : :
3232 : 25122 : argvi = new_var_info (argdecl, newname, false);
3233 : 25122 : argvi->offset = fi_parm_base + i;
3234 : 25122 : argvi->size = 1;
3235 : 25122 : argvi->is_full_var = true;
3236 : 25122 : argvi->fullsize = vi->fullsize;
3237 : 25122 : if (arg)
3238 : 25122 : argvi->may_have_pointers = true;
3239 : :
3240 : 25122 : if (arg)
3241 : 25122 : insert_vi_for_tree (arg, argvi);
3242 : :
3243 : 25122 : if (nonlocal_p
3244 : 9142 : && argvi->may_have_pointers)
3245 : 9142 : make_constraint_from (argvi, nonlocal_id);
3246 : :
3247 : 25122 : gcc_assert (prev_vi->offset < argvi->offset);
3248 : 25122 : prev_vi->next = argvi->id;
3249 : 25122 : prev_vi = argvi;
3250 : 25122 : if (arg)
3251 : 25122 : arg = DECL_CHAIN (arg);
3252 : : }
3253 : :
3254 : : /* Add one representative for all further args. */
3255 : 23378 : if (is_varargs)
3256 : : {
3257 : 7 : varinfo_t argvi;
3258 : 7 : const char *newname;
3259 : 7 : char *tempname;
3260 : 7 : tree decl;
3261 : :
3262 : 7 : tempname = xasprintf ("%s.varargs", name);
3263 : 7 : newname = ggc_strdup (tempname);
3264 : 7 : free (tempname);
3265 : :
3266 : : /* We need sth that can be pointed to for va_start. */
3267 : 7 : decl = build_fake_var_decl (ptr_type_node);
3268 : :
3269 : 7 : argvi = new_var_info (decl, newname, false);
3270 : 7 : argvi->offset = fi_parm_base + num_args;
3271 : 7 : argvi->size = ~0;
3272 : 7 : argvi->is_full_var = true;
3273 : 7 : argvi->is_heap_var = true;
3274 : 7 : argvi->fullsize = vi->fullsize;
3275 : :
3276 : 7 : if (nonlocal_p
3277 : 6 : && argvi->may_have_pointers)
3278 : 6 : make_constraint_from (argvi, nonlocal_id);
3279 : :
3280 : 7 : gcc_assert (prev_vi->offset < argvi->offset);
3281 : 7 : prev_vi->next = argvi->id;
3282 : : }
3283 : :
3284 : 23378 : return vi;
3285 : : }
3286 : :
3287 : :
3288 : : /* Return true if FIELDSTACK contains fields that overlap.
3289 : : FIELDSTACK is assumed to be sorted by offset. */
3290 : :
3291 : : static bool
3292 : 7564200 : check_for_overlaps (const vec<fieldoff_s> &fieldstack)
3293 : : {
3294 : 7564200 : fieldoff_s *fo = NULL;
3295 : 7564200 : unsigned int i;
3296 : 7564200 : HOST_WIDE_INT lastoffset = -1;
3297 : :
3298 : 29324266 : FOR_EACH_VEC_ELT (fieldstack, i, fo)
3299 : : {
3300 : 21778252 : if (fo->offset == lastoffset)
3301 : : return true;
3302 : 21760066 : lastoffset = fo->offset;
3303 : : }
3304 : : return false;
3305 : : }
3306 : :
3307 : : /* Create a varinfo structure for NAME and DECL, and add it to VARMAP.
3308 : : This will also create any varinfo structures necessary for fields
3309 : : of DECL. DECL is a function parameter if HANDLE_PARAM is set.
3310 : : HANDLED_STRUCT_TYPE is used to register struct types reached by following
3311 : : restrict pointers. This is needed to prevent infinite recursion.
3312 : : If ADD_RESTRICT, pretend that the pointer NAME is restrict even if DECL
3313 : : does not advertise it. */
3314 : :
3315 : : static varinfo_t
3316 : 91606962 : create_variable_info_for_1 (tree decl, const char *name, bool add_id,
3317 : : bool handle_param, bitmap handled_struct_type,
3318 : : bool add_restrict = false)
3319 : : {
3320 : 91606962 : varinfo_t vi, newvi;
3321 : 91606962 : tree decl_type = TREE_TYPE (decl);
3322 : 91606962 : tree declsize = DECL_P (decl) ? DECL_SIZE (decl) : TYPE_SIZE (decl_type);
3323 : 91606962 : auto_vec<fieldoff_s> fieldstack;
3324 : 91606962 : fieldoff_s *fo;
3325 : 91606962 : unsigned int i;
3326 : :
3327 : 91606962 : if (!declsize
3328 : 83351706 : || !tree_fits_uhwi_p (declsize))
3329 : : {
3330 : 8268821 : vi = new_var_info (decl, name, add_id);
3331 : 8268821 : vi->offset = 0;
3332 : 8268821 : vi->size = ~0;
3333 : 8268821 : vi->fullsize = ~0;
3334 : 8268821 : vi->is_unknown_size_var = true;
3335 : 8268821 : vi->is_full_var = true;
3336 : 8268821 : vi->may_have_pointers = true;
3337 : 8268821 : return vi;
3338 : : }
3339 : :
3340 : : /* Collect field information. */
3341 : 83338141 : if (use_field_sensitive
3342 : 79402992 : && var_can_have_subvars (decl)
3343 : : /* ??? Force us to not use subfields for globals in IPA mode.
3344 : : Else we'd have to parse arbitrary initializers. */
3345 : 90953295 : && !(in_ipa_mode
3346 : 19604 : && is_global_var (decl)))
3347 : : {
3348 : 7595087 : fieldoff_s *fo = NULL;
3349 : 7595087 : bool notokay = false;
3350 : 7595087 : unsigned int i;
3351 : :
3352 : 7595087 : push_fields_onto_fieldstack (decl_type, &fieldstack, 0);
3353 : :
3354 : 37719469 : for (i = 0; !notokay && fieldstack.iterate (i, &fo); i++)
3355 : 22560182 : if (fo->has_unknown_size
3356 : 22529295 : || fo->offset < 0)
3357 : : {
3358 : : notokay = true;
3359 : : break;
3360 : : }
3361 : :
3362 : : /* We can't sort them if we have a field with a variable sized type,
3363 : : which will make notokay = true. In that case, we are going to return
3364 : : without creating varinfos for the fields anyway, so sorting them is a
3365 : : waste to boot. */
3366 : 7595087 : if (!notokay)
3367 : : {
3368 : 7564200 : sort_fieldstack (fieldstack);
3369 : : /* Due to some C++ FE issues, like PR 22488, we might end up
3370 : : what appear to be overlapping fields even though they,
3371 : : in reality, do not overlap. Until the C++ FE is fixed,
3372 : : we will simply disable field-sensitivity for these cases. */
3373 : 7564200 : notokay = check_for_overlaps (fieldstack);
3374 : : }
3375 : :
3376 : 7564200 : if (notokay)
3377 : 49073 : fieldstack.release ();
3378 : : }
3379 : :
3380 : : /* If we didn't end up collecting sub-variables create a full
3381 : : variable for the decl. */
3382 : 83338141 : if (fieldstack.length () == 0
3383 : 7281545 : || fieldstack.length () > (unsigned)param_max_fields_for_field_sensitive)
3384 : : {
3385 : 76057014 : vi = new_var_info (decl, name, add_id);
3386 : 76057014 : vi->offset = 0;
3387 : 76057014 : vi->may_have_pointers = true;
3388 : 76057014 : vi->fullsize = tree_to_uhwi (declsize);
3389 : 76057014 : vi->size = vi->fullsize;
3390 : 76057014 : vi->is_full_var = true;
3391 : 76057014 : if (POINTER_TYPE_P (decl_type)
3392 : 76057014 : && (TYPE_RESTRICT (decl_type) || add_restrict))
3393 : 846547 : vi->only_restrict_pointers = 1;
3394 : 76057014 : if (vi->only_restrict_pointers
3395 : 846547 : && !type_contains_placeholder_p (TREE_TYPE (decl_type))
3396 : 846547 : && handle_param
3397 : 76625139 : && !bitmap_bit_p (handled_struct_type,
3398 : 568125 : TYPE_UID (TREE_TYPE (decl_type))))
3399 : : {
3400 : 568125 : varinfo_t rvi;
3401 : 568125 : tree heapvar = build_fake_var_decl (TREE_TYPE (decl_type));
3402 : 568125 : DECL_EXTERNAL (heapvar) = 1;
3403 : 568125 : if (var_can_have_subvars (heapvar))
3404 : 887580 : bitmap_set_bit (handled_struct_type,
3405 : 443790 : TYPE_UID (TREE_TYPE (decl_type)));
3406 : 568125 : rvi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS", true,
3407 : : true, handled_struct_type);
3408 : 568125 : if (var_can_have_subvars (heapvar))
3409 : 887580 : bitmap_clear_bit (handled_struct_type,
3410 : 443790 : TYPE_UID (TREE_TYPE (decl_type)));
3411 : 568125 : rvi->is_restrict_var = 1;
3412 : 568125 : insert_vi_for_tree (heapvar, rvi);
3413 : 568125 : make_constraint_from (vi, rvi->id);
3414 : 568125 : make_param_constraints (rvi);
3415 : : }
3416 : 76057014 : fieldstack.release ();
3417 : 76057014 : return vi;
3418 : : }
3419 : :
3420 : 7281127 : vi = new_var_info (decl, name, add_id);
3421 : 7281127 : vi->fullsize = tree_to_uhwi (declsize);
3422 : 7281127 : if (fieldstack.length () == 1)
3423 : 1577626 : vi->is_full_var = true;
3424 : : for (i = 0, newvi = vi;
3425 : 120559160 : fieldstack.iterate (i, &fo);
3426 : 21671071 : ++i, newvi = vi_next (newvi))
3427 : : {
3428 : 21671071 : const char *newname = NULL;
3429 : 21671071 : char *tempname;
3430 : :
3431 : 21671071 : if (dump_file)
3432 : : {
3433 : 331 : if (fieldstack.length () != 1)
3434 : : {
3435 : 301 : tempname
3436 : 301 : = xasprintf ("%s." HOST_WIDE_INT_PRINT_DEC
3437 : : "+" HOST_WIDE_INT_PRINT_DEC, name,
3438 : : fo->offset, fo->size);
3439 : 301 : newname = ggc_strdup (tempname);
3440 : 301 : free (tempname);
3441 : : }
3442 : : }
3443 : : else
3444 : : newname = "NULL";
3445 : :
3446 : 301 : if (newname)
3447 : 21671041 : newvi->name = newname;
3448 : 21671071 : newvi->offset = fo->offset;
3449 : 21671071 : newvi->size = fo->size;
3450 : 21671071 : newvi->fullsize = vi->fullsize;
3451 : 21671071 : newvi->may_have_pointers = fo->may_have_pointers;
3452 : 21671071 : newvi->only_restrict_pointers = fo->only_restrict_pointers;
3453 : 21671071 : if (handle_param
3454 : 1689464 : && newvi->only_restrict_pointers
3455 : 25291 : && !type_contains_placeholder_p (fo->restrict_pointed_type)
3456 : 21696362 : && !bitmap_bit_p (handled_struct_type,
3457 : 25291 : TYPE_UID (fo->restrict_pointed_type)))
3458 : : {
3459 : 25288 : varinfo_t rvi;
3460 : 25288 : tree heapvar = build_fake_var_decl (fo->restrict_pointed_type);
3461 : 25288 : DECL_EXTERNAL (heapvar) = 1;
3462 : 25288 : if (var_can_have_subvars (heapvar))
3463 : 80 : bitmap_set_bit (handled_struct_type,
3464 : 40 : TYPE_UID (fo->restrict_pointed_type));
3465 : 25288 : rvi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS", true,
3466 : : true, handled_struct_type);
3467 : 25288 : if (var_can_have_subvars (heapvar))
3468 : 80 : bitmap_clear_bit (handled_struct_type,
3469 : 40 : TYPE_UID (fo->restrict_pointed_type));
3470 : 25288 : rvi->is_restrict_var = 1;
3471 : 25288 : insert_vi_for_tree (heapvar, rvi);
3472 : 25288 : make_constraint_from (newvi, rvi->id);
3473 : 25288 : make_param_constraints (rvi);
3474 : : }
3475 : 36061015 : if (i + 1 < fieldstack.length ())
3476 : : {
3477 : 14389944 : varinfo_t tem = new_var_info (decl, name, false);
3478 : 14389944 : newvi->next = tem->id;
3479 : 14389944 : tem->head = vi->id;
3480 : : }
3481 : : }
3482 : :
3483 : : return vi;
3484 : 91606962 : }
3485 : :
3486 : : static unsigned int
3487 : 81649745 : create_variable_info_for (tree decl, const char *name, bool add_id)
3488 : : {
3489 : : /* First see if we are dealing with an ifunc resolver call and
3490 : : assiociate that with a call to the resolver function result. */
3491 : 81649745 : cgraph_node *node;
3492 : 81649745 : if (in_ipa_mode
3493 : 691933 : && TREE_CODE (decl) == FUNCTION_DECL
3494 : 17649 : && (node = cgraph_node::get (decl))
3495 : 81667393 : && node->ifunc_resolver)
3496 : : {
3497 : 1 : varinfo_t fi = get_vi_for_tree (node->get_alias_target ()->decl);
3498 : 1 : constraint_expr rhs
3499 : 1 : = get_function_part_constraint (fi, fi_result);
3500 : 1 : fi = new_var_info (NULL_TREE, "ifuncres", true);
3501 : 1 : fi->is_reg_var = true;
3502 : 1 : constraint_expr lhs;
3503 : 1 : lhs.type = SCALAR;
3504 : 1 : lhs.var = fi->id;
3505 : 1 : lhs.offset = 0;
3506 : 1 : process_constraint (new_constraint (lhs, rhs));
3507 : 1 : insert_vi_for_tree (decl, fi);
3508 : 1 : return fi->id;
3509 : : }
3510 : :
3511 : 81649744 : varinfo_t vi = create_variable_info_for_1 (decl, name, add_id, false, NULL);
3512 : 81649744 : unsigned int id = vi->id;
3513 : :
3514 : 81649744 : insert_vi_for_tree (decl, vi);
3515 : :
3516 : 81649744 : if (!VAR_P (decl))
3517 : : return id;
3518 : :
3519 : : /* Create initial constraints for globals. */
3520 : 32620107 : for (; vi; vi = vi_next (vi))
3521 : : {
3522 : 22929784 : if (!vi->may_have_pointers
3523 : 22929784 : || !vi->is_global_var)
3524 : 15002464 : continue;
3525 : :
3526 : : /* Mark global restrict qualified pointers. */
3527 : 15500237 : if ((POINTER_TYPE_P (TREE_TYPE (decl))
3528 : 354565 : && TYPE_RESTRICT (TREE_TYPE (decl)))
3529 : 15848111 : || vi->only_restrict_pointers)
3530 : : {
3531 : 11232 : varinfo_t rvi
3532 : 11232 : = make_constraint_from_global_restrict (vi, "GLOBAL_RESTRICT",
3533 : : true);
3534 : : /* ??? For now exclude reads from globals as restrict sources
3535 : : if those are not (indirectly) from incoming parameters. */
3536 : 11232 : rvi->is_restrict_var = false;
3537 : 11232 : continue;
3538 : 11232 : }
3539 : :
3540 : : /* In non-IPA mode the initializer from nonlocal is all we need. */
3541 : 7916088 : if (!in_ipa_mode
3542 : 7952640 : || DECL_HARD_REGISTER (decl))
3543 : 7879536 : make_copy_constraint (vi, nonlocal_id);
3544 : :
3545 : : /* In IPA mode parse the initializer and generate proper constraints
3546 : : for it. */
3547 : : else
3548 : : {
3549 : 36552 : varpool_node *vnode = varpool_node::get (decl);
3550 : :
3551 : : /* For escaped variables initialize them from nonlocal. */
3552 : 36552 : if (!vnode || !vnode->all_refs_explicit_p ())
3553 : 1450 : make_copy_constraint (vi, nonlocal_id);
3554 : :
3555 : : /* While we can in theory walk references for the varpool
3556 : : node that does not cover zero-initialization or references
3557 : : to the constant pool. */
3558 : 36552 : if (DECL_INITIAL (decl))
3559 : : {
3560 : 35462 : auto_vec<ce_s> rhsc;
3561 : 35462 : struct constraint_expr lhs, *rhsp;
3562 : 35462 : unsigned i;
3563 : 35462 : lhs.var = vi->id;
3564 : 35462 : lhs.offset = 0;
3565 : 35462 : lhs.type = SCALAR;
3566 : 35462 : get_constraint_for (DECL_INITIAL (decl), &rhsc);
3567 : 182017 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
3568 : 111093 : process_constraint (new_constraint (lhs, *rhsp));
3569 : : /* If this is a variable that escapes from the unit
3570 : : the initializer escapes as well. */
3571 : 35462 : if (!vnode || !vnode->all_refs_explicit_p ())
3572 : : {
3573 : 2191 : lhs.var = escaped_id;
3574 : 2191 : lhs.offset = 0;
3575 : 2191 : lhs.type = SCALAR;
3576 : 37653 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
3577 : 1578 : process_constraint (new_constraint (lhs, *rhsp));
3578 : : }
3579 : 35462 : }
3580 : : }
3581 : : }
3582 : :
3583 : : return id;
3584 : : }
3585 : :
3586 : : /* Register the constraints for function parameter related VI. */
3587 : :
3588 : : static void
3589 : 9957218 : make_param_constraints (varinfo_t vi)
3590 : : {
3591 : 11349006 : for (; vi; vi = vi_next (vi))
3592 : : {
3593 : 10861227 : if (vi->only_restrict_pointers)
3594 : : ;
3595 : 10267811 : else if (vi->may_have_pointers)
3596 : 10267811 : make_constraint_from (vi, nonlocal_id);
3597 : :
3598 : 10861227 : if (vi->is_full_var)
3599 : : break;
3600 : : }
3601 : 9957218 : }
3602 : :
3603 : : /* Create varinfo structures for all of the variables in the
3604 : : function for intraprocedural mode. */
3605 : :
3606 : : static void
3607 : 4455410 : intra_create_variable_infos (struct function *fn)
3608 : : {
3609 : 4455410 : tree t;
3610 : 4455410 : bitmap handled_struct_type = NULL;
3611 : 4455410 : bool this_parm_in_ctor = DECL_CXX_CONSTRUCTOR_P (fn->decl);
3612 : :
3613 : : /* For each incoming pointer argument arg, create the constraint ARG
3614 : : = NONLOCAL or a dummy variable if it is a restrict qualified
3615 : : passed-by-reference argument. */
3616 : 13819215 : for (t = DECL_ARGUMENTS (fn->decl); t; t = DECL_CHAIN (t))
3617 : : {
3618 : 9363805 : if (handled_struct_type == NULL)
3619 : 3762382 : handled_struct_type = BITMAP_ALLOC (NULL);
3620 : :
3621 : 9363805 : varinfo_t p
3622 : 9363805 : = create_variable_info_for_1 (t, alias_get_name (t), false, true,
3623 : : handled_struct_type, this_parm_in_ctor);
3624 : 9363805 : insert_vi_for_tree (t, p);
3625 : :
3626 : 9363805 : make_param_constraints (p);
3627 : :
3628 : 9363805 : this_parm_in_ctor = false;
3629 : : }
3630 : :
3631 : 4455410 : if (handled_struct_type != NULL)
3632 : 3762382 : BITMAP_FREE (handled_struct_type);
3633 : :
3634 : : /* Add a constraint for a result decl that is passed by reference. */
3635 : 4455410 : if (DECL_RESULT (fn->decl)
3636 : 4455410 : && DECL_BY_REFERENCE (DECL_RESULT (fn->decl)))
3637 : : {
3638 : 58165 : varinfo_t p, result_vi = get_vi_for_tree (DECL_RESULT (fn->decl));
3639 : :
3640 : 174495 : for (p = result_vi; p; p = vi_next (p))
3641 : 58165 : make_constraint_from (p, nonlocal_id);
3642 : : }
3643 : :
3644 : : /* Add a constraint for the incoming static chain parameter. */
3645 : 4455410 : if (fn->static_chain_decl != NULL_TREE)
3646 : : {
3647 : 47233 : varinfo_t p, chain_vi = get_vi_for_tree (fn->static_chain_decl);
3648 : :
3649 : 141699 : for (p = chain_vi; p; p = vi_next (p))
3650 : 47233 : make_constraint_from (p, nonlocal_id);
3651 : : }
3652 : 4455410 : }
3653 : :
3654 : : /* Initialize the always-existing constraint variables for NULL
3655 : : ANYTHING, READONLY, and INTEGER. */
3656 : :
3657 : : static void
3658 : 4459820 : init_base_vars (void)
3659 : : {
3660 : 4459820 : struct constraint_expr lhs, rhs;
3661 : 4459820 : varinfo_t var_anything;
3662 : 4459820 : varinfo_t var_nothing;
3663 : 4459820 : varinfo_t var_string;
3664 : 4459820 : varinfo_t var_escaped;
3665 : 4459820 : varinfo_t var_nonlocal;
3666 : 4459820 : varinfo_t var_escaped_return;
3667 : 4459820 : varinfo_t var_storedanything;
3668 : 4459820 : varinfo_t var_integer;
3669 : :
3670 : : /* Variable ID zero is reserved and should be NULL. */
3671 : 4459820 : varmap.safe_push (NULL);
3672 : :
3673 : : /* Create the NULL variable, used to represent that a variable points
3674 : : to NULL. */
3675 : 4459820 : var_nothing = new_var_info (NULL_TREE, "NULL", false);
3676 : 4459820 : gcc_assert (var_nothing->id == nothing_id);
3677 : 4459820 : var_nothing->is_artificial_var = 1;
3678 : 4459820 : var_nothing->offset = 0;
3679 : 4459820 : var_nothing->size = ~0;
3680 : 4459820 : var_nothing->fullsize = ~0;
3681 : 4459820 : var_nothing->is_special_var = 1;
3682 : 4459820 : var_nothing->may_have_pointers = 0;
3683 : 4459820 : var_nothing->is_global_var = 0;
3684 : :
3685 : : /* Create the ANYTHING variable, used to represent that a variable
3686 : : points to some unknown piece of memory. */
3687 : 4459820 : var_anything = new_var_info (NULL_TREE, "ANYTHING", false);
3688 : 4459820 : gcc_assert (var_anything->id == anything_id);
3689 : 4459820 : var_anything->is_artificial_var = 1;
3690 : 4459820 : var_anything->size = ~0;
3691 : 4459820 : var_anything->offset = 0;
3692 : 4459820 : var_anything->fullsize = ~0;
3693 : 4459820 : var_anything->is_special_var = 1;
3694 : :
3695 : : /* Anything points to anything. This makes deref constraints just
3696 : : work in the presence of linked list and other p = *p type loops,
3697 : : by saying that *ANYTHING = ANYTHING. */
3698 : 4459820 : lhs.type = SCALAR;
3699 : 4459820 : lhs.var = anything_id;
3700 : 4459820 : lhs.offset = 0;
3701 : 4459820 : rhs.type = ADDRESSOF;
3702 : 4459820 : rhs.var = anything_id;
3703 : 4459820 : rhs.offset = 0;
3704 : :
3705 : : /* This specifically does not use process_constraint because
3706 : : process_constraint ignores all anything = anything constraints, since all
3707 : : but this one are redundant. */
3708 : 4459820 : constraints.safe_push (new_constraint (lhs, rhs));
3709 : :
3710 : : /* Create the STRING variable, used to represent that a variable
3711 : : points to a string literal. String literals don't contain
3712 : : pointers so STRING doesn't point to anything. */
3713 : 4459820 : var_string = new_var_info (NULL_TREE, "STRING", false);
3714 : 4459820 : gcc_assert (var_string->id == string_id);
3715 : 4459820 : var_string->is_artificial_var = 1;
3716 : 4459820 : var_string->offset = 0;
3717 : 4459820 : var_string->size = ~0;
3718 : 4459820 : var_string->fullsize = ~0;
3719 : 4459820 : var_string->is_special_var = 1;
3720 : 4459820 : var_string->may_have_pointers = 0;
3721 : :
3722 : : /* Create the ESCAPED variable, used to represent the set of escaped
3723 : : memory. */
3724 : 4459820 : var_escaped = new_var_info (NULL_TREE, "ESCAPED", false);
3725 : 4459820 : gcc_assert (var_escaped->id == escaped_id);
3726 : 4459820 : var_escaped->is_artificial_var = 1;
3727 : 4459820 : var_escaped->offset = 0;
3728 : 4459820 : var_escaped->size = ~0;
3729 : 4459820 : var_escaped->fullsize = ~0;
3730 : 4459820 : var_escaped->is_special_var = 0;
3731 : :
3732 : : /* Create the NONLOCAL variable, used to represent the set of nonlocal
3733 : : memory. */
3734 : 4459820 : var_nonlocal = new_var_info (NULL_TREE, "NONLOCAL", false);
3735 : 4459820 : gcc_assert (var_nonlocal->id == nonlocal_id);
3736 : 4459820 : var_nonlocal->is_artificial_var = 1;
3737 : 4459820 : var_nonlocal->offset = 0;
3738 : 4459820 : var_nonlocal->size = ~0;
3739 : 4459820 : var_nonlocal->fullsize = ~0;
3740 : 4459820 : var_nonlocal->is_special_var = 1;
3741 : :
3742 : : /* Create the ESCAPED_RETURN variable, used to represent the set of escaped
3743 : : memory via a regular return stmt. */
3744 : 4459820 : var_escaped_return = new_var_info (NULL_TREE, "ESCAPED_RETURN", false);
3745 : 4459820 : gcc_assert (var_escaped_return->id == escaped_return_id);
3746 : 4459820 : var_escaped_return->is_artificial_var = 1;
3747 : 4459820 : var_escaped_return->offset = 0;
3748 : 4459820 : var_escaped_return->size = ~0;
3749 : 4459820 : var_escaped_return->fullsize = ~0;
3750 : 4459820 : var_escaped_return->is_special_var = 0;
3751 : :
3752 : : /* ESCAPED = *ESCAPED, because escaped is may-deref'd at calls, etc. */
3753 : 4459820 : lhs.type = SCALAR;
3754 : 4459820 : lhs.var = escaped_id;
3755 : 4459820 : lhs.offset = 0;
3756 : 4459820 : rhs.type = DEREF;
3757 : 4459820 : rhs.var = escaped_id;
3758 : 4459820 : rhs.offset = 0;
3759 : 4459820 : process_constraint (new_constraint (lhs, rhs));
3760 : :
3761 : : /* ESCAPED = ESCAPED + UNKNOWN_OFFSET, because if a sub-field escapes the
3762 : : whole variable escapes. */
3763 : 4459820 : lhs.type = SCALAR;
3764 : 4459820 : lhs.var = escaped_id;
3765 : 4459820 : lhs.offset = 0;
3766 : 4459820 : rhs.type = SCALAR;
3767 : 4459820 : rhs.var = escaped_id;
3768 : 4459820 : rhs.offset = UNKNOWN_OFFSET;
3769 : 4459820 : process_constraint (new_constraint (lhs, rhs));
3770 : :
3771 : : /* *ESCAPED = NONLOCAL. This is true because we have to assume
3772 : : everything pointed to by escaped points to what global memory can
3773 : : point to. */
3774 : 4459820 : lhs.type = DEREF;
3775 : 4459820 : lhs.var = escaped_id;
3776 : 4459820 : lhs.offset = 0;
3777 : 4459820 : rhs.type = SCALAR;
3778 : 4459820 : rhs.var = nonlocal_id;
3779 : 4459820 : rhs.offset = 0;
3780 : 4459820 : process_constraint (new_constraint (lhs, rhs));
3781 : :
3782 : : /* NONLOCAL = &NONLOCAL, NONLOCAL = &ESCAPED. This is true because
3783 : : global memory may point to global memory and escaped memory. */
3784 : 4459820 : lhs.type = SCALAR;
3785 : 4459820 : lhs.var = nonlocal_id;
3786 : 4459820 : lhs.offset = 0;
3787 : 4459820 : rhs.type = ADDRESSOF;
3788 : 4459820 : rhs.var = nonlocal_id;
3789 : 4459820 : rhs.offset = 0;
3790 : 4459820 : process_constraint (new_constraint (lhs, rhs));
3791 : 4459820 : rhs.type = ADDRESSOF;
3792 : 4459820 : rhs.var = escaped_id;
3793 : 4459820 : rhs.offset = 0;
3794 : 4459820 : process_constraint (new_constraint (lhs, rhs));
3795 : :
3796 : : /* Transitively close ESCAPED_RETURN.
3797 : : ESCAPED_RETURN = ESCAPED_RETURN + UNKNOWN_OFFSET
3798 : : ESCAPED_RETURN = *ESCAPED_RETURN. */
3799 : 4459820 : lhs.type = SCALAR;
3800 : 4459820 : lhs.var = escaped_return_id;
3801 : 4459820 : lhs.offset = 0;
3802 : 4459820 : rhs.type = SCALAR;
3803 : 4459820 : rhs.var = escaped_return_id;
3804 : 4459820 : rhs.offset = UNKNOWN_OFFSET;
3805 : 4459820 : process_constraint (new_constraint (lhs, rhs));
3806 : 4459820 : lhs.type = SCALAR;
3807 : 4459820 : lhs.var = escaped_return_id;
3808 : 4459820 : lhs.offset = 0;
3809 : 4459820 : rhs.type = DEREF;
3810 : 4459820 : rhs.var = escaped_return_id;
3811 : 4459820 : rhs.offset = 0;
3812 : 4459820 : process_constraint (new_constraint (lhs, rhs));
3813 : :
3814 : : /* Create the STOREDANYTHING variable, used to represent the set of
3815 : : variables stored to *ANYTHING. */
3816 : 4459820 : var_storedanything = new_var_info (NULL_TREE, "STOREDANYTHING", false);
3817 : 4459820 : gcc_assert (var_storedanything->id == storedanything_id);
3818 : 4459820 : var_storedanything->is_artificial_var = 1;
3819 : 4459820 : var_storedanything->offset = 0;
3820 : 4459820 : var_storedanything->size = ~0;
3821 : 4459820 : var_storedanything->fullsize = ~0;
3822 : 4459820 : var_storedanything->is_special_var = 0;
3823 : :
3824 : : /* Create the INTEGER variable, used to represent that a variable points
3825 : : to what an INTEGER "points to". */
3826 : 4459820 : var_integer = new_var_info (NULL_TREE, "INTEGER", false);
3827 : 4459820 : gcc_assert (var_integer->id == integer_id);
3828 : 4459820 : var_integer->is_artificial_var = 1;
3829 : 4459820 : var_integer->size = ~0;
3830 : 4459820 : var_integer->fullsize = ~0;
3831 : 4459820 : var_integer->offset = 0;
3832 : 4459820 : var_integer->is_special_var = 1;
3833 : :
3834 : : /* INTEGER = ANYTHING, because we don't know where a dereference of
3835 : : a random integer will point to. */
3836 : 4459820 : lhs.type = SCALAR;
3837 : 4459820 : lhs.var = integer_id;
3838 : 4459820 : lhs.offset = 0;
3839 : 4459820 : rhs.type = ADDRESSOF;
3840 : 4459820 : rhs.var = anything_id;
3841 : 4459820 : rhs.offset = 0;
3842 : 4459820 : process_constraint (new_constraint (lhs, rhs));
3843 : 4459820 : }
3844 : :
3845 : : /* Associate node with varinfo DATA. Worker for
3846 : : cgraph_for_symbol_thunks_and_aliases. */
3847 : : static bool
3848 : 23434 : associate_varinfo_to_alias (struct cgraph_node *node, void *data)
3849 : : {
3850 : 23434 : if ((node->alias
3851 : 23381 : || (node->thunk
3852 : 3 : && ! node->inlined_to))
3853 : 53 : && node->analyzed
3854 : 53 : && !node->ifunc_resolver)
3855 : 52 : insert_vi_for_tree (node->decl, (varinfo_t)data);
3856 : 23434 : return false;
3857 : : }
3858 : :
3859 : : /* Compute whether node is refered to non-locally. Worker for
3860 : : cgraph_for_symbol_thunks_and_aliases. */
3861 : : static bool
3862 : 23434 : refered_from_nonlocal_fn (struct cgraph_node *node, void *data)
3863 : : {
3864 : 23434 : bool *nonlocal_p = (bool *)data;
3865 : 46868 : *nonlocal_p |= (node->used_from_other_partition
3866 : 23388 : || DECL_EXTERNAL (node->decl)
3867 : 23383 : || TREE_PUBLIC (node->decl)
3868 : 16416 : || node->force_output
3869 : 39840 : || lookup_attribute ("noipa", DECL_ATTRIBUTES (node->decl)));
3870 : 23434 : return false;
3871 : : }
3872 : :
3873 : : /* Same for varpool nodes. */
3874 : : static bool
3875 : 36755 : refered_from_nonlocal_var (struct varpool_node *node, void *data)
3876 : : {
3877 : 36755 : bool *nonlocal_p = (bool *)data;
3878 : 73510 : *nonlocal_p |= (node->used_from_other_partition
3879 : 36654 : || DECL_EXTERNAL (node->decl)
3880 : 36170 : || TREE_PUBLIC (node->decl)
3881 : 71877 : || node->force_output);
3882 : 36755 : return false;
3883 : : }
3884 : :
3885 : : /* Create function infos. */
3886 : :
3887 : : static void
3888 : 4410 : ipa_create_function_infos (void)
3889 : : {
3890 : 4410 : struct cgraph_node *node;
3891 : 4410 : unsigned int constr_count = constraints.length ();
3892 : :
3893 : 29034 : FOR_EACH_DEFINED_FUNCTION (node)
3894 : : {
3895 : 24624 : varinfo_t vi;
3896 : : /* Nodes without a body in this partition are not interesting.
3897 : : Especially do not visit clones at this point for now - we
3898 : : get duplicate decls there for inline clones at least. */
3899 : 25870 : if (!node->has_gimple_body_p ()
3900 : 24523 : || node->in_other_partition
3901 : 49147 : || node->inlined_to)
3902 : 1246 : continue;
3903 : 23378 : node->get_body ();
3904 : :
3905 : 23378 : gcc_assert (!node->clone_of);
3906 : :
3907 : : /* For externally visible or attribute used annotated functions use
3908 : : local constraints for their arguments.
3909 : : For local functions we see all callers and thus do not need initial
3910 : : constraints for parameters. */
3911 : 23378 : bool nonlocal_p = (node->used_from_other_partition
3912 : 23332 : || DECL_EXTERNAL (node->decl)
3913 : 23328 : || TREE_PUBLIC (node->decl)
3914 : 16412 : || node->force_output
3915 : 39780 : || lookup_attribute ("noipa",
3916 : 16402 : DECL_ATTRIBUTES (node->decl)));
3917 : 23378 : node->call_for_symbol_thunks_and_aliases (refered_from_nonlocal_fn,
3918 : : &nonlocal_p, true);
3919 : :
3920 : 23378 : vi = create_function_info_for (node->decl,
3921 : : alias_get_name (node->decl), false,
3922 : : nonlocal_p);
3923 : 54 : if (dump_file && (dump_flags & TDF_DETAILS)
3924 : 23430 : && constr_count != constraints.length ())
3925 : : {
3926 : 22 : fprintf (dump_file,
3927 : : "Generating initial constraints for %s",
3928 : : node->dump_name ());
3929 : 22 : if (DECL_ASSEMBLER_NAME_SET_P (node->decl))
3930 : 44 : fprintf (dump_file, " (%s)",
3931 : 22 : IDENTIFIER_POINTER
3932 : : (DECL_ASSEMBLER_NAME (node->decl)));
3933 : 22 : fprintf (dump_file, "\n\n");
3934 : 22 : dump_constraints (dump_file, constr_count);
3935 : 22 : fprintf (dump_file, "\n");
3936 : :
3937 : 22 : constr_count = constraints.length ();
3938 : : }
3939 : :
3940 : 23378 : node->call_for_symbol_thunks_and_aliases
3941 : 23378 : (associate_varinfo_to_alias, vi, true);
3942 : : }
3943 : 4410 : }
3944 : :
3945 : : /* Create constraints for global variables and their initializers. */
3946 : :
3947 : : static void
3948 : 4410 : ipa_create_global_variable_infos (void)
3949 : : {
3950 : 4410 : varpool_node *var;
3951 : 4410 : unsigned int constr_count = constraints.length ();
3952 : :
3953 : 82330 : FOR_EACH_VARIABLE (var)
3954 : : {
3955 : 36755 : if (var->alias && var->analyzed)
3956 : 17 : continue;
3957 : :
3958 : 36738 : varinfo_t vi = get_vi_for_tree (var->decl);
3959 : :
3960 : : /* For the purpose of IPA PTA unit-local globals are not
3961 : : escape points. */
3962 : 36738 : bool nonlocal_p = (DECL_EXTERNAL (var->decl)
3963 : 36254 : || TREE_PUBLIC (var->decl)
3964 : 35106 : || var->used_from_other_partition
3965 : 71844 : || var->force_output);
3966 : 36738 : var->call_for_symbol_and_aliases (refered_from_nonlocal_var,
3967 : : &nonlocal_p, true);
3968 : 36738 : if (nonlocal_p)
3969 : 1637 : vi->is_ipa_escape_point = true;
3970 : : }
3971 : :
3972 : 19 : if (dump_file && (dump_flags & TDF_DETAILS)
3973 : 4427 : && constr_count != constraints.length ())
3974 : : {
3975 : 11 : fprintf (dump_file,
3976 : : "Generating constraints for global initializers\n\n");
3977 : 11 : dump_constraints (dump_file, constr_count);
3978 : 11 : fprintf (dump_file, "\n");
3979 : 11 : constr_count = constraints.length ();
3980 : : }
3981 : 4410 : }
3982 : :
3983 : :
3984 : : namespace pointer_analysis {
3985 : :
3986 : : /* Find the variable info for tree T in VI_FOR_TREE. If T does not
3987 : : exist in the map, return NULL, otherwise, return the varinfo we found. */
3988 : :
3989 : : varinfo_t
3990 : 52114582 : lookup_vi_for_tree (tree t)
3991 : : {
3992 : 52114582 : varinfo_t *slot = vi_for_tree->get (t);
3993 : 52114582 : if (slot == NULL)
3994 : : return NULL;
3995 : :
3996 : 50048777 : return *slot;
3997 : : }
3998 : :
3999 : : /* Lookup the variable for the call statement CALL representing
4000 : : the uses. Returns NULL if there is nothing special about this call. */
4001 : :
4002 : : varinfo_t
4003 : 30356082 : lookup_call_use_vi (gcall *call)
4004 : : {
4005 : 30356082 : varinfo_t *slot_p = call_stmt_vars->get (call);
4006 : 30356082 : if (slot_p)
4007 : 28619878 : return *slot_p;
4008 : :
4009 : : return NULL;
4010 : : }
4011 : :
4012 : : /* Lookup the variable for the call statement CALL representing
4013 : : the clobbers. Returns NULL if there is nothing special about this call. */
4014 : :
4015 : : varinfo_t
4016 : 14560530 : lookup_call_clobber_vi (gcall *call)
4017 : : {
4018 : 14560530 : varinfo_t uses = lookup_call_use_vi (call);
4019 : 14560530 : if (!uses)
4020 : : return NULL;
4021 : :
4022 : 13700958 : return vi_next (uses);
4023 : : }
4024 : :
4025 : : /* Return the varinfo for the callee of CALL. */
4026 : :
4027 : : varinfo_t
4028 : 16610176 : get_fi_for_callee (gcall *call)
4029 : : {
4030 : 16610176 : tree decl, fn = gimple_call_fn (call);
4031 : :
4032 : 16610176 : if (fn && TREE_CODE (fn) == OBJ_TYPE_REF)
4033 : 155590 : fn = OBJ_TYPE_REF_EXPR (fn);
4034 : :
4035 : : /* If we can directly resolve the function being called, do so.
4036 : : Otherwise, it must be some sort of indirect expression that
4037 : : we should still be able to handle. */
4038 : 16610176 : decl = gimple_call_addr_fndecl (fn);
4039 : 16610176 : if (decl)
4040 : 15189280 : return get_vi_for_tree (decl);
4041 : :
4042 : : /* If the function is anything other than a SSA name pointer we have no
4043 : : clue and should be getting ANYFN (well, ANYTHING for now). */
4044 : 1420896 : if (!fn || TREE_CODE (fn) != SSA_NAME)
4045 : 929410 : return get_varinfo (anything_id);
4046 : :
4047 : 491486 : if (SSA_NAME_IS_DEFAULT_DEF (fn)
4048 : 491486 : && (TREE_CODE (SSA_NAME_VAR (fn)) == PARM_DECL
4049 : 15 : || TREE_CODE (SSA_NAME_VAR (fn)) == RESULT_DECL))
4050 : 12770 : fn = SSA_NAME_VAR (fn);
4051 : :
4052 : 491486 : return get_vi_for_tree (fn);
4053 : : }
4054 : :
4055 : : /* Initialize constraint builder. */
4056 : :
4057 : : void
4058 : 4459820 : init_constraint_builder (void)
4059 : : {
4060 : 4459820 : vi_for_tree = new hash_map<tree, varinfo_t>;
4061 : 4459820 : call_stmt_vars = new hash_map<gimple *, varinfo_t>;
4062 : 4459820 : gcc_obstack_init (&fake_var_decl_obstack);
4063 : :
4064 : 4459820 : init_base_vars ();
4065 : 4459820 : }
4066 : :
4067 : : /* Deallocate constraint builder globals. */
4068 : :
4069 : : void
4070 : 4459820 : delete_constraint_builder (void)
4071 : : {
4072 : 8919640 : delete vi_for_tree;
4073 : 8919640 : delete call_stmt_vars;
4074 : 4459820 : constraint_pool.release ();
4075 : 4459820 : obstack_free (&fake_var_decl_obstack, NULL);
4076 : 4459820 : }
4077 : :
4078 : : /* Build constraints for intraprocedural mode. */
4079 : :
4080 : : void
4081 : 4455410 : intra_build_constraints (void)
4082 : : {
4083 : 4455410 : basic_block bb;
4084 : :
4085 : 4455410 : intra_create_variable_infos (cfun);
4086 : :
4087 : : /* Now walk all statements and build the constraint set. */
4088 : 39847851 : FOR_EACH_BB_FN (bb, cfun)
4089 : : {
4090 : 47581836 : for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
4091 : 12189395 : gsi_next (&gsi))
4092 : : {
4093 : 12189395 : gphi *phi = gsi.phi ();
4094 : :
4095 : 24378790 : if (! virtual_operand_p (gimple_phi_result (phi)))
4096 : 6376372 : find_func_aliases (cfun, phi);
4097 : : }
4098 : :
4099 : 319581151 : for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
4100 : 248796269 : gsi_next (&gsi))
4101 : : {
4102 : 248796269 : gimple *stmt = gsi_stmt (gsi);
4103 : :
4104 : 248796269 : find_func_aliases (cfun, stmt);
4105 : : }
4106 : : }
4107 : :
4108 : 4455410 : if (dump_file && (dump_flags & TDF_DETAILS))
4109 : : {
4110 : 282 : fprintf (dump_file, "Points-to analysis\n\nConstraints:\n\n");
4111 : 282 : dump_constraints (dump_file, 0);
4112 : : }
4113 : 4455410 : }
4114 : :
4115 : : /* Build constraints for ipa mode. */
4116 : :
4117 : : void
4118 : 4410 : ipa_build_constraints (void)
4119 : : {
4120 : 4410 : struct cgraph_node *node;
4121 : :
4122 : 4410 : ipa_create_function_infos ();
4123 : 4410 : ipa_create_global_variable_infos ();
4124 : :
4125 : 4410 : unsigned int constr_count = constraints.length ();
4126 : :
4127 : 27841 : FOR_EACH_DEFINED_FUNCTION (node)
4128 : : {
4129 : 23431 : struct function *func;
4130 : 23431 : basic_block bb;
4131 : :
4132 : : /* Nodes without a body in this partition are not interesting. */
4133 : 23484 : if (!node->has_gimple_body_p ()
4134 : 23378 : || node->in_other_partition
4135 : 46809 : || node->clone_of)
4136 : 53 : continue;
4137 : :
4138 : 23378 : if (dump_file && (dump_flags & TDF_DETAILS))
4139 : : {
4140 : 52 : fprintf (dump_file,
4141 : : "Generating constraints for %s", node->dump_name ());
4142 : 52 : if (DECL_ASSEMBLER_NAME_SET_P (node->decl))
4143 : 104 : fprintf (dump_file, " (%s)",
4144 : 52 : IDENTIFIER_POINTER
4145 : : (DECL_ASSEMBLER_NAME (node->decl)));
4146 : 52 : fprintf (dump_file, "\n");
4147 : : }
4148 : :
4149 : 23378 : func = DECL_STRUCT_FUNCTION (node->decl);
4150 : 23378 : gcc_assert (cfun == NULL);
4151 : :
4152 : : /* Build constraints for the function body. */
4153 : 354520 : FOR_EACH_BB_FN (bb, func)
4154 : : {
4155 : 438176 : for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
4156 : 107034 : gsi_next (&gsi))
4157 : : {
4158 : 107034 : gphi *phi = gsi.phi ();
4159 : :
4160 : 214068 : if (! virtual_operand_p (gimple_phi_result (phi)))
4161 : 63732 : find_func_aliases (func, phi);
4162 : : }
4163 : :
4164 : 1617290 : for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
4165 : 955006 : gsi_next (&gsi))
4166 : : {
4167 : 955006 : gimple *stmt = gsi_stmt (gsi);
4168 : :
4169 : 955006 : find_func_aliases (func, stmt);
4170 : 955006 : find_func_clobbers (func, stmt);
4171 : : }
4172 : : }
4173 : :
4174 : 23378 : if (dump_file && (dump_flags & TDF_DETAILS))
4175 : : {
4176 : 52 : fprintf (dump_file, "\n");
4177 : 52 : dump_constraints (dump_file, constr_count);
4178 : 52 : fprintf (dump_file, "\n");
4179 : 23483 : constr_count = constraints.length ();
4180 : : }
4181 : : }
4182 : 4410 : }
4183 : :
4184 : : } // namespace pointer_analysis
|