Line data Source code
1 : /* Constraint builder for tree based points-to analysis
2 : Copyright (C) 2005-2026 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 69220045 : get_call_vi (gcall *call)
71 : {
72 69220045 : varinfo_t vi, vi2;
73 :
74 69220045 : bool existed;
75 69220045 : varinfo_t *slot_p = &call_stmt_vars->get_or_insert (call, &existed);
76 69220045 : if (existed)
77 53014934 : return *slot_p;
78 :
79 16205111 : vi = new_var_info (NULL_TREE, "CALLUSED", true);
80 16205111 : vi->offset = 0;
81 16205111 : vi->size = 1;
82 16205111 : vi->fullsize = 2;
83 16205111 : vi->is_full_var = true;
84 16205111 : vi->is_reg_var = true;
85 :
86 16205111 : vi2 = new_var_info (NULL_TREE, "CALLCLOBBERED", true);
87 16205111 : vi2->offset = 1;
88 16205111 : vi2->size = 1;
89 16205111 : vi2->fullsize = 2;
90 16205111 : vi2->is_full_var = true;
91 16205111 : vi2->is_reg_var = true;
92 :
93 16205111 : vi->next = vi2->id;
94 :
95 16205111 : *slot_p = vi;
96 16205111 : 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 43432772 : 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 25787273 : get_call_clobber_vi (gcall *call)
113 : {
114 25787273 : 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 452838048 : new_constraint (const struct constraint_expr lhs,
131 : const struct constraint_expr rhs)
132 : {
133 0 : constraint_t ret = constraint_pool.allocate ();
134 452838048 : ret->lhs = lhs;
135 452838048 : ret->rhs = rhs;
136 452838048 : 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 94417453 : insert_vi_for_tree (tree t, varinfo_t vi)
143 : {
144 94417453 : gcc_assert (vi);
145 94417453 : bool existed = vi_for_tree->put (t, vi);
146 94417453 : gcc_assert (!existed);
147 94417453 : }
148 :
149 : /* Return a printable name for DECL. */
150 :
151 : static const char *
152 93319645 : alias_get_name (tree decl)
153 : {
154 93319645 : const char *res = "NULL";
155 93319645 : if (dump_file)
156 : {
157 4074 : char *temp = NULL;
158 4074 : if (TREE_CODE (decl) == SSA_NAME)
159 : {
160 2320 : res = get_name (decl);
161 3800 : temp = xasprintf ("%s_%u", res ? res : "", SSA_NAME_VERSION (decl));
162 : }
163 1754 : else if (HAS_DECL_ASSEMBLER_NAME_P (decl)
164 1754 : && DECL_ASSEMBLER_NAME_SET_P (decl))
165 766 : res = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME_RAW (decl));
166 988 : else if (DECL_P (decl))
167 : {
168 988 : res = get_name (decl);
169 988 : if (!res)
170 4 : temp = xasprintf ("D.%u", DECL_UID (decl));
171 : }
172 :
173 3090 : if (temp)
174 : {
175 2324 : res = ggc_strdup (temp);
176 2324 : free (temp);
177 : }
178 : }
179 :
180 93319645 : 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 247879936 : get_vi_for_tree (tree t)
188 : {
189 247879936 : varinfo_t *slot = vi_for_tree->get (t);
190 247879936 : if (slot == NULL)
191 : {
192 83690462 : unsigned int id = create_variable_info_for (t, alias_get_name (t), false);
193 83690462 : return get_varinfo (id);
194 : }
195 :
196 164189474 : return *slot;
197 : }
198 :
199 : /* Get a scalar constraint expression for a new temporary variable. */
200 :
201 : static struct constraint_expr
202 3264621 : new_scalar_tmp_constraint_exp (const char *name, bool add_id)
203 : {
204 3264621 : struct constraint_expr tmp;
205 3264621 : varinfo_t vi;
206 :
207 3264621 : vi = new_var_info (NULL_TREE, name, add_id);
208 3264621 : vi->offset = 0;
209 3264621 : vi->size = -1;
210 3264621 : vi->fullsize = -1;
211 3264621 : vi->is_full_var = 1;
212 3264621 : vi->is_reg_var = 1;
213 :
214 3264621 : tmp.var = vi->id;
215 3264621 : tmp.type = SCALAR;
216 3264621 : tmp.offset = 0;
217 :
218 3264621 : 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 208875637 : get_constraint_for_ssa_var (tree t, vec<ce_s> *results, bool address_p)
226 : {
227 227163238 : struct constraint_expr cexpr;
228 227163238 : varinfo_t vi;
229 :
230 : /* We allow FUNCTION_DECLs here even though it doesn't make much sense. */
231 227163238 : gcc_assert (TREE_CODE (t) == SSA_NAME || DECL_P (t));
232 :
233 227163238 : if (TREE_CODE (t) == SSA_NAME
234 227163238 : && SSA_NAME_IS_DEFAULT_DEF (t))
235 : {
236 : /* For parameters, get at the points-to set for the actual parm
237 : decl. */
238 18557646 : if (TREE_CODE (SSA_NAME_VAR (t)) == PARM_DECL
239 18557646 : || TREE_CODE (SSA_NAME_VAR (t)) == RESULT_DECL)
240 : {
241 18287601 : get_constraint_for_ssa_var (SSA_NAME_VAR (t), results, address_p);
242 24624041 : return;
243 : }
244 : /* For undefined SSA names return nothing. */
245 270045 : else if (!ssa_defined_default_def_p (t))
246 : {
247 270045 : cexpr.var = nothing_id;
248 270045 : cexpr.type = SCALAR;
249 270045 : cexpr.offset = 0;
250 270045 : results->safe_push (cexpr);
251 270045 : return;
252 : }
253 : }
254 :
255 : /* For global variables resort to the alias target. */
256 208605592 : if (VAR_P (t) && (TREE_STATIC (t) || DECL_EXTERNAL (t)))
257 : {
258 11572688 : varpool_node *node = varpool_node::get (t);
259 11572688 : if (node && node->alias && node->analyzed)
260 : {
261 19113 : 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 19113 : 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 19113 : DECL_PT_UID (t) = DECL_UID (node->decl);
270 19113 : t = node->decl;
271 : }
272 :
273 : /* If this is decl may bind to NULL note that. */
274 11572688 : if (address_p
275 11572688 : && (! node || ! node->nonzero_address ()))
276 : {
277 9546 : cexpr.var = nothing_id;
278 9546 : cexpr.type = SCALAR;
279 9546 : cexpr.offset = 0;
280 9546 : results->safe_push (cexpr);
281 : }
282 : }
283 :
284 208605592 : vi = get_vi_for_tree (t);
285 208605592 : cexpr.var = vi->id;
286 208605592 : cexpr.type = SCALAR;
287 208605592 : cexpr.offset = 0;
288 :
289 : /* If we are not taking the address of the constraint expr, add all
290 : sub-fields of the variable as well. */
291 208605592 : if (!address_p
292 170239764 : && !vi->is_full_var)
293 : {
294 20392566 : for (; vi; vi = vi_next (vi))
295 : {
296 14326171 : cexpr.var = vi->id;
297 14326171 : results->safe_push (cexpr);
298 : }
299 : return;
300 : }
301 :
302 202539197 : 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 448256141 : process_constraint (constraint_t t)
310 : {
311 448256141 : struct constraint_expr rhs = t->rhs;
312 448256141 : struct constraint_expr lhs = t->lhs;
313 :
314 448256141 : gcc_assert (rhs.var < varmap.length ());
315 448256141 : 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 448256141 : 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 448256141 : 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 448256141 : if (rhs.type != ADDRESSOF
330 448256141 : && !get_varinfo (rhs.var)->may_have_pointers)
331 : return;
332 :
333 : /* Likewise adding to the solution of a non-pointer var isn't useful. */
334 447854044 : 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 447852326 : if (rhs.type == DEREF && lhs.type == DEREF && rhs.var != anything_id)
339 : {
340 : /* Split into tmp = *rhs, *lhs = tmp. */
341 317669 : struct constraint_expr tmplhs;
342 317669 : tmplhs = new_scalar_tmp_constraint_exp ("doubledereftmp", true);
343 317669 : process_constraint (new_constraint (tmplhs, rhs));
344 317669 : process_constraint (new_constraint (lhs, tmplhs));
345 317669 : }
346 447534657 : else if ((rhs.type != SCALAR || rhs.offset != 0) && lhs.type == DEREF)
347 : {
348 : /* Split into tmp = &rhs, *lhs = tmp. */
349 2116439 : struct constraint_expr tmplhs;
350 2116439 : tmplhs = new_scalar_tmp_constraint_exp ("derefaddrtmp", true);
351 2116439 : process_constraint (new_constraint (tmplhs, rhs));
352 2116439 : process_constraint (new_constraint (lhs, tmplhs));
353 2116439 : }
354 : else
355 : {
356 445418218 : gcc_assert (rhs.type != ADDRESSOF || rhs.offset == 0);
357 445418218 : if (rhs.type == ADDRESSOF)
358 87881654 : get_varinfo (get_varinfo (rhs.var)->head)->address_taken = true;
359 445418218 : 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 41194498 : bitpos_of_field (const tree fdecl)
369 : {
370 41194498 : if (!tree_fits_uhwi_p (DECL_FIELD_OFFSET (fdecl))
371 41194498 : || !tree_fits_uhwi_p (DECL_FIELD_BIT_OFFSET (fdecl)))
372 : return -1;
373 :
374 41194498 : return (tree_to_uhwi (DECL_FIELD_OFFSET (fdecl)) * BITS_PER_UNIT
375 41194498 : + 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 41981777 : get_constraint_for_ptr_offset (tree ptr, tree offset,
384 : vec<ce_s> *results)
385 : {
386 41981777 : struct constraint_expr c;
387 41981777 : unsigned int j, n;
388 41981777 : 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 41981777 : if (!use_field_sensitive)
393 : {
394 2121519 : get_constraint_for_rhs (ptr, results);
395 2121519 : 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 39860258 : if (offset == NULL_TREE
403 14105152 : || TREE_CODE (offset) != INTEGER_CST)
404 : rhsoffset = UNKNOWN_OFFSET;
405 : else
406 : {
407 : /* Sign-extend the offset. */
408 12107828 : offset_int soffset = offset_int::from (wi::to_wide (offset), SIGNED);
409 12107828 : if (!wi::fits_shwi_p (soffset))
410 : rhsoffset = UNKNOWN_OFFSET;
411 : else
412 : {
413 : /* Make sure the bit-offset also fits. */
414 12107828 : HOST_WIDE_INT rhsunitoffset = soffset.to_shwi ();
415 12107828 : rhsoffset = rhsunitoffset * (unsigned HOST_WIDE_INT) BITS_PER_UNIT;
416 12107828 : if (rhsunitoffset != rhsoffset / BITS_PER_UNIT)
417 362 : rhsoffset = UNKNOWN_OFFSET;
418 : }
419 : }
420 :
421 39860258 : get_constraint_for_rhs (ptr, results);
422 39860258 : if (rhsoffset == 0)
423 : return;
424 :
425 : /* As we are eventually appending to the solution do not use
426 : vec::iterate here. */
427 33514801 : n = results->length ();
428 67029794 : for (j = 0; j < n; j++)
429 : {
430 33514993 : varinfo_t curr;
431 33514993 : c = (*results)[j];
432 33514993 : curr = get_varinfo (c.var);
433 :
434 33514993 : if (c.type == ADDRESSOF
435 : /* If this varinfo represents a full variable just use it. */
436 11040049 : && curr->is_full_var)
437 : ;
438 24996709 : else if (c.type == ADDRESSOF
439 : /* If we do not know the offset add all subfields. */
440 2521765 : && rhsoffset == UNKNOWN_OFFSET)
441 : {
442 40750 : varinfo_t temp = get_varinfo (curr->head);
443 273807 : do
444 : {
445 273807 : struct constraint_expr c2;
446 273807 : c2.var = temp->id;
447 273807 : c2.type = ADDRESSOF;
448 273807 : c2.offset = 0;
449 273807 : if (c2.var != c.var)
450 233057 : results->safe_push (c2);
451 273807 : temp = vi_next (temp);
452 : }
453 273807 : while (temp);
454 : }
455 24955959 : else if (c.type == ADDRESSOF)
456 : {
457 2481015 : varinfo_t temp;
458 2481015 : unsigned HOST_WIDE_INT offset = curr->offset + rhsoffset;
459 :
460 : /* If curr->offset + rhsoffset is less than zero adjust it. */
461 2481015 : if (rhsoffset < 0
462 0 : && curr->offset < offset)
463 2481015 : 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 2481015 : temp = first_or_preceding_vi_for_offset (curr, offset);
471 2481015 : c.var = temp->id;
472 2481015 : c.offset = 0;
473 2481015 : temp = vi_next (temp);
474 2481015 : while (temp
475 2605686 : && temp->offset < offset + curr->size)
476 : {
477 124671 : struct constraint_expr c2;
478 124671 : c2.var = temp->id;
479 124671 : c2.type = ADDRESSOF;
480 124671 : c2.offset = 0;
481 124671 : results->safe_push (c2);
482 124671 : temp = vi_next (temp);
483 : }
484 : }
485 22474944 : else if (c.type == SCALAR)
486 : {
487 22474944 : 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 33514993 : (*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 32926201 : get_constraint_for_component_ref (tree t, vec<ce_s> *results,
506 : bool address_p, bool lhs_p)
507 : {
508 32926201 : tree orig_t = t;
509 32926201 : poly_int64 bitsize = -1;
510 32926201 : poly_int64 bitmaxsize = -1;
511 32926201 : poly_int64 bitpos;
512 32926201 : bool reverse;
513 32926201 : tree forzero;
514 :
515 : /* Some people like to do cute things like take the address of
516 : &0->a.b. */
517 32926201 : forzero = t;
518 32926201 : while (handled_component_p (forzero)
519 48349170 : || INDIRECT_REF_P (forzero)
520 144663839 : || TREE_CODE (forzero) == MEM_REF)
521 63388468 : forzero = TREE_OPERAND (forzero, 0);
522 :
523 32926201 : if (CONSTANT_CLASS_P (forzero) && integer_zerop (forzero))
524 : {
525 1773 : struct constraint_expr temp;
526 :
527 1773 : temp.offset = 0;
528 1773 : temp.var = integer_id;
529 1773 : temp.type = SCALAR;
530 1773 : results->safe_push (temp);
531 1773 : return;
532 : }
533 :
534 32924428 : 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 32924428 : 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 32924418 : if (TREE_CODE (t) == MEM_REF
554 32924418 : && !integer_zerop (TREE_OPERAND (t, 0)))
555 : {
556 12186711 : poly_offset_int off = mem_ref_offset (t);
557 12186711 : off <<= LOG2_BITS_PER_UNIT;
558 12186711 : off += bitpos;
559 12186711 : poly_int64 off_hwi;
560 12186711 : if (off.to_shwi (&off_hwi))
561 12186709 : bitpos = off_hwi;
562 : else
563 : {
564 2 : bitpos = 0;
565 2 : bitmaxsize = -1;
566 : }
567 12186711 : get_constraint_for_1 (TREE_OPERAND (t, 0), results, false, lhs_p);
568 12186711 : do_deref (results);
569 : }
570 : else
571 20737707 : get_constraint_for_1 (t, results, true, lhs_p);
572 :
573 : /* Strip off nothing_id. */
574 32924418 : if (results->length () == 2)
575 : {
576 8567 : gcc_assert ((*results)[0].var == nothing_id);
577 8567 : results->unordered_remove (0);
578 : }
579 32924418 : gcc_assert (results->length () == 1);
580 32924418 : struct constraint_expr &result = results->last ();
581 :
582 32924418 : if (result.type == SCALAR
583 32924418 : && get_varinfo (result.var)->is_full_var)
584 : /* For single-field vars do not bother about the offset. */
585 8603576 : result.offset = 0;
586 24320842 : 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 12134206 : if (maybe_lt (poly_uint64 (bitpos), get_varinfo (result.var)->fullsize)
594 12134206 : && 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 12124162 : struct constraint_expr cexpr = result;
601 12124162 : varinfo_t curr;
602 12124162 : results->pop ();
603 12124162 : cexpr.offset = 0;
604 63756722 : for (curr = get_varinfo (cexpr.var); curr; curr = vi_next (curr))
605 : {
606 52502018 : if (ranges_maybe_overlap_p (poly_int64 (curr->offset),
607 52502018 : curr->size, bitpos, bitmaxsize))
608 : {
609 12362221 : cexpr.var = curr->id;
610 12362221 : results->safe_push (cexpr);
611 12362221 : 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 12993644 : 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 12124138 : 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 10044 : else if (known_eq (bitmaxsize, 0))
641 : {
642 9733 : 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 311 : if (dump_file && (dump_flags & TDF_DETAILS))
648 0 : fprintf (dump_file, "Access to past the end of variable, ignoring\n");
649 : }
650 12186636 : 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 12186585 : HOST_WIDE_INT const_bitpos;
656 12186585 : if (!bitpos.is_constant (&const_bitpos)
657 12186585 : || const_bitpos == -1
658 12186585 : || maybe_ne (bitsize, bitmaxsize)
659 11458290 : || AGGREGATE_TYPE_P (TREE_TYPE (orig_t))
660 9782744 : || result.offset == UNKNOWN_OFFSET)
661 2403841 : result.offset = UNKNOWN_OFFSET;
662 : else
663 9782744 : 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 24709366 : do_deref (vec<ce_s> *constraints)
686 : {
687 24709366 : struct constraint_expr *c;
688 24709366 : unsigned int i = 0;
689 :
690 49585135 : FOR_EACH_VEC_ELT (*constraints, i, c)
691 : {
692 24875769 : if (c->type == SCALAR)
693 18776587 : c->type = DEREF;
694 6099182 : else if (c->type == ADDRESSOF)
695 6099176 : 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 24709366 : }
707 :
708 : /* Given a tree T, return the constraint expression for taking the
709 : address of it. */
710 :
711 : static void
712 28743257 : get_constraint_for_address_of (tree t, vec<ce_s> *results)
713 : {
714 28743257 : struct constraint_expr *c;
715 28743257 : unsigned int i;
716 :
717 28743257 : get_constraint_for_1 (t, results, true, true);
718 :
719 86232869 : FOR_EACH_VEC_ELT (*results, i, c)
720 : {
721 28746355 : if (c->type == DEREF)
722 : c->type = SCALAR;
723 : else
724 27064575 : c->type = ADDRESSOF;
725 : }
726 28743257 : }
727 :
728 : /* Given a tree T, return the constraint expression for it. */
729 :
730 : static void
731 325161628 : get_constraint_for_1 (tree t, vec<ce_s> *results, bool address_p,
732 : bool lhs_p)
733 : {
734 326020966 : 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 326020966 : if ((TREE_CODE (t) == INTEGER_CST
750 33181424 : && 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 348418198 : || (TREE_CODE (t) == CONSTRUCTOR
755 583377 : && CONSTRUCTOR_NELTS (t) == 0))
756 : {
757 11303956 : if (flag_delete_null_pointer_checks)
758 : temp.var = nothing_id;
759 : else
760 20095 : temp.var = nonlocal_id;
761 11303956 : temp.type = ADDRESSOF;
762 11303956 : temp.offset = 0;
763 11303956 : results->safe_push (temp);
764 335601074 : return;
765 : }
766 :
767 : /* String constants are read-only, ideally we'd have a CONST_DECL
768 : for those. */
769 314717010 : if (TREE_CODE (t) == STRING_CST)
770 : {
771 6613126 : temp.var = string_id;
772 6613126 : temp.type = SCALAR;
773 6613126 : temp.offset = 0;
774 6613126 : results->safe_push (temp);
775 6613126 : return;
776 : }
777 :
778 308103884 : switch (TREE_CODE_CLASS (TREE_CODE (t)))
779 : {
780 28557476 : case tcc_expression:
781 28557476 : {
782 28557476 : switch (TREE_CODE (t))
783 : {
784 28493029 : case ADDR_EXPR:
785 28493029 : get_constraint_for_address_of (TREE_OPERAND (t, 0), results);
786 28493029 : return;
787 : default:;
788 : }
789 : break;
790 : }
791 45658842 : case tcc_reference:
792 45658842 : {
793 45658842 : if (!lhs_p && TREE_THIS_VOLATILE (t))
794 : /* Fall back to anything. */
795 : break;
796 :
797 45551897 : switch (TREE_CODE (t))
798 : {
799 11766358 : case MEM_REF:
800 11766358 : {
801 11766358 : struct constraint_expr cs;
802 11766358 : varinfo_t vi, curr;
803 11766358 : get_constraint_for_ptr_offset (TREE_OPERAND (t, 0),
804 11766358 : TREE_OPERAND (t, 1), results);
805 11766358 : do_deref (results);
806 :
807 : /* If we are not taking the address then make sure to process
808 : all subvariables we might access. */
809 11766358 : if (address_p)
810 : return;
811 :
812 11134445 : cs = results->last ();
813 11134445 : if (cs.type == DEREF
814 11134445 : && type_can_have_subvars (TREE_TYPE (t)))
815 : {
816 : /* For dereferences this means we have to defer it
817 : to solving time. */
818 592843 : results->last ().offset = UNKNOWN_OFFSET;
819 592843 : return;
820 : }
821 10541602 : if (cs.type != SCALAR)
822 : return;
823 :
824 5135767 : vi = get_varinfo (cs.var);
825 5135767 : curr = vi_next (vi);
826 5135767 : if (!vi->is_full_var
827 3972156 : && curr)
828 : {
829 2580210 : unsigned HOST_WIDE_INT size;
830 2580210 : if (tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (t))))
831 2580210 : size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (t)));
832 : else
833 2580210 : size = -1;
834 5179321 : 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 3522140 : if (curr->offset - (vi->offset + vi->size - 1) < size)
840 : {
841 2599111 : cs.var = curr->id;
842 2599111 : results->safe_push (cs);
843 : }
844 : else
845 : break;
846 : }
847 : }
848 : return;
849 : }
850 32926201 : case ARRAY_REF:
851 32926201 : case ARRAY_RANGE_REF:
852 32926201 : case COMPONENT_REF:
853 32926201 : case IMAGPART_EXPR:
854 32926201 : case REALPART_EXPR:
855 32926201 : case BIT_FIELD_REF:
856 32926201 : get_constraint_for_component_ref (t, results, address_p, lhs_p);
857 32926201 : return;
858 859338 : case VIEW_CONVERT_EXPR:
859 859338 : get_constraint_for_1 (TREE_OPERAND (t, 0), results, address_p,
860 : lhs_p);
861 859338 : return;
862 : /* We are missing handling for TARGET_MEM_REF here. */
863 : default:;
864 : }
865 : break;
866 : }
867 159964384 : case tcc_exceptional:
868 159964384 : {
869 159964384 : switch (TREE_CODE (t))
870 : {
871 159900571 : case SSA_NAME:
872 159900571 : {
873 159900571 : get_constraint_for_ssa_var (t, results, address_p);
874 159900571 : return;
875 : }
876 63613 : case CONSTRUCTOR:
877 63613 : {
878 63613 : unsigned int i;
879 63613 : tree val;
880 63613 : auto_vec<ce_s> tmp;
881 353832 : FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (t), i, val)
882 : {
883 290219 : struct constraint_expr *rhsp;
884 290219 : unsigned j;
885 290219 : get_constraint_for_1 (val, &tmp, address_p, lhs_p);
886 580655 : FOR_EACH_VEC_ELT (tmp, j, rhsp)
887 290436 : results->safe_push (*rhsp);
888 290219 : 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 63613 : return;
894 63613 : }
895 : default:;
896 : }
897 : break;
898 : }
899 49667949 : case tcc_declaration:
900 49667949 : {
901 49667949 : if (!lhs_p && VAR_P (t) && TREE_THIS_VOLATILE (t))
902 : /* Fall back to anything. */
903 : break;
904 48975066 : get_constraint_for_ssa_var (t, results, address_p);
905 48975066 : return;
906 : }
907 24255198 : case tcc_constant:
908 24255198 : {
909 : /* We cannot refer to automatic variables through constants. */
910 24255198 : temp.type = ADDRESSOF;
911 24255198 : temp.var = nonlocal_id;
912 24255198 : temp.offset = 0;
913 24255198 : results->safe_push (temp);
914 24255198 : return;
915 : }
916 799828 : default:;
917 : }
918 :
919 : /* The default fallback is a constraint from anything. */
920 864510 : temp.type = ADDRESSOF;
921 864510 : temp.var = anything_id;
922 864510 : temp.offset = 0;
923 864510 : results->safe_push (temp);
924 : }
925 :
926 : /* Given a gimple tree T, return the constraint expression vector for it. */
927 :
928 : static void
929 89828678 : get_constraint_for (tree t, vec<ce_s> *results)
930 : {
931 89828678 : gcc_assert (results->length () == 0);
932 :
933 89828678 : get_constraint_for_1 (t, results, false, true);
934 89828678 : }
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 173375056 : get_constraint_for_rhs (tree t, vec<ce_s> *results)
941 : {
942 173375056 : gcc_assert (results->length () == 0);
943 :
944 173375056 : get_constraint_for_1 (t, results, false, false);
945 173375056 : }
946 :
947 :
948 : /* Efficiently generates constraints from all entries in *RHSC to all
949 : entries in *LHSC. */
950 :
951 : static void
952 96776120 : process_all_all_constraints (const vec<ce_s> &lhsc,
953 : const vec<ce_s> &rhsc)
954 : {
955 96776120 : struct constraint_expr *lhsp, *rhsp;
956 96776120 : unsigned i, j;
957 :
958 99031012 : if (lhsc.length () <= 1 || rhsc.length () <= 1)
959 : {
960 291126143 : FOR_EACH_VEC_ELT (lhsc, i, lhsp)
961 314571642 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
962 119391112 : process_constraint (new_constraint (*lhsp, *rhsp));
963 : }
964 : else
965 : {
966 830507 : struct constraint_expr tmp;
967 830507 : tmp = new_scalar_tmp_constraint_exp ("allalltmp", true);
968 4338186 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
969 2677172 : process_constraint (new_constraint (tmp, *rhsp));
970 3677228 : FOR_EACH_VEC_ELT (lhsc, i, lhsp)
971 2016214 : process_constraint (new_constraint (*lhsp, tmp));
972 : }
973 96776120 : }
974 :
975 : /* Handle aggregate copies by expanding into copies of the respective
976 : fields of the structures. */
977 :
978 : static void
979 2579300 : do_structure_copy (tree lhsop, tree rhsop)
980 : {
981 2579300 : struct constraint_expr *lhsp, *rhsp;
982 2579300 : auto_vec<ce_s> lhsc;
983 2579300 : auto_vec<ce_s> rhsc;
984 2579300 : unsigned j;
985 :
986 2579300 : get_constraint_for (lhsop, &lhsc);
987 2579300 : get_constraint_for_rhs (rhsop, &rhsc);
988 2579300 : lhsp = &lhsc[0];
989 2579300 : rhsp = &rhsc[0];
990 2579300 : if (lhsp->type == DEREF
991 2020016 : || (lhsp->type == ADDRESSOF && lhsp->var == anything_id)
992 2020016 : || rhsp->type == DEREF)
993 : {
994 905809 : if (lhsp->type == DEREF)
995 : {
996 559284 : gcc_assert (lhsc.length () == 1);
997 559284 : lhsp->offset = UNKNOWN_OFFSET;
998 : }
999 905809 : if (rhsp->type == DEREF)
1000 : {
1001 456273 : gcc_assert (rhsc.length () == 1);
1002 456273 : rhsp->offset = UNKNOWN_OFFSET;
1003 : }
1004 905809 : process_all_all_constraints (lhsc, rhsc);
1005 : }
1006 1673491 : else if (lhsp->type == SCALAR
1007 1673491 : && (rhsp->type == SCALAR
1008 466426 : || rhsp->type == ADDRESSOF))
1009 : {
1010 1673491 : HOST_WIDE_INT lhssize, lhsoffset;
1011 1673491 : HOST_WIDE_INT rhssize, rhsoffset;
1012 1673491 : bool reverse;
1013 1673491 : unsigned k = 0;
1014 1673491 : if (!get_ref_base_and_extent_hwi (lhsop, &lhsoffset, &lhssize, &reverse)
1015 1673491 : || !get_ref_base_and_extent_hwi (rhsop, &rhsoffset, &rhssize,
1016 : &reverse))
1017 : {
1018 4937 : process_all_all_constraints (lhsc, rhsc);
1019 4937 : return;
1020 : }
1021 6235533 : for (j = 0; lhsc.iterate (j, &lhsp);)
1022 : {
1023 4640135 : varinfo_t lhsv, rhsv;
1024 4640135 : rhsp = &rhsc[k];
1025 4640135 : lhsv = get_varinfo (lhsp->var);
1026 4640135 : rhsv = get_varinfo (rhsp->var);
1027 4640135 : if (lhsv->may_have_pointers
1028 4640135 : && (lhsv->is_full_var
1029 4071850 : || rhsv->is_full_var
1030 3177637 : || ranges_overlap_p (lhsv->offset + rhsoffset, lhsv->size,
1031 3177637 : rhsv->offset + lhsoffset, rhsv->size)))
1032 3469072 : process_constraint (new_constraint (*lhsp, *rhsp));
1033 4640135 : if (!rhsv->is_full_var
1034 3314707 : && (lhsv->is_full_var
1035 3177637 : || (lhsv->offset + rhsoffset + lhsv->size
1036 3177637 : > rhsv->offset + lhsoffset + rhsv->size)))
1037 : {
1038 1315807 : ++k;
1039 2911205 : if (k >= rhsc.length ())
1040 : break;
1041 : }
1042 : else
1043 3324328 : ++j;
1044 : }
1045 1668554 : }
1046 : else
1047 0 : gcc_unreachable ();
1048 2579300 : }
1049 :
1050 : /* Create constraints ID = { rhsc }. */
1051 :
1052 : static void
1053 57354697 : make_constraints_to (unsigned id, const vec<ce_s> &rhsc)
1054 : {
1055 57354697 : struct constraint_expr *c;
1056 57354697 : struct constraint_expr includes;
1057 57354697 : unsigned int j;
1058 :
1059 57354697 : includes.var = id;
1060 57354697 : includes.offset = 0;
1061 57354697 : includes.type = SCALAR;
1062 :
1063 118039234 : FOR_EACH_VEC_ELT (rhsc, j, c)
1064 60684537 : process_constraint (new_constraint (includes, *c));
1065 57354697 : }
1066 :
1067 : /* Create a constraint ID = OP. */
1068 :
1069 : static void
1070 57189789 : make_constraint_to (unsigned id, tree op)
1071 : {
1072 57189789 : auto_vec<ce_s> rhsc;
1073 57189789 : get_constraint_for_rhs (op, &rhsc);
1074 57189789 : make_constraints_to (id, rhsc);
1075 57189789 : }
1076 :
1077 : /* Create a constraint ID = &FROM. */
1078 :
1079 : static void
1080 11782326 : make_constraint_from (varinfo_t vi, int from)
1081 : {
1082 11782326 : struct constraint_expr lhs, rhs;
1083 :
1084 11782326 : lhs.var = vi->id;
1085 11782326 : lhs.offset = 0;
1086 11782326 : lhs.type = SCALAR;
1087 :
1088 11782326 : rhs.var = from;
1089 11782326 : rhs.offset = 0;
1090 11782326 : rhs.type = ADDRESSOF;
1091 11782326 : process_constraint (new_constraint (lhs, rhs));
1092 11782326 : }
1093 :
1094 : /* Create a constraint ID = FROM. */
1095 :
1096 : static void
1097 78482825 : make_copy_constraint (varinfo_t vi, int from)
1098 : {
1099 78482825 : struct constraint_expr lhs, rhs;
1100 :
1101 78482825 : lhs.var = vi->id;
1102 78482825 : lhs.offset = 0;
1103 78482825 : lhs.type = SCALAR;
1104 :
1105 78482825 : rhs.var = from;
1106 78482825 : rhs.offset = 0;
1107 78482825 : rhs.type = SCALAR;
1108 78482825 : process_constraint (new_constraint (lhs, rhs));
1109 78482825 : }
1110 :
1111 : /* Make constraints necessary to make OP escape. */
1112 :
1113 : static void
1114 23769633 : make_escape_constraint (tree op)
1115 : {
1116 0 : make_constraint_to (escaped_id, op);
1117 0 : }
1118 :
1119 : /* Make constraint necessary to make all indirect references
1120 : from VI escape. */
1121 :
1122 : static void
1123 1244171 : make_indirect_escape_constraint (varinfo_t vi)
1124 : {
1125 1244171 : struct constraint_expr lhs, rhs;
1126 : /* escaped = *(VAR + UNKNOWN); */
1127 1244171 : lhs.type = SCALAR;
1128 1244171 : lhs.var = escaped_id;
1129 1244171 : lhs.offset = 0;
1130 1244171 : rhs.type = DEREF;
1131 1244171 : rhs.var = vi->id;
1132 1244171 : rhs.offset = UNKNOWN_OFFSET;
1133 1244171 : process_constraint (new_constraint (lhs, rhs));
1134 1244171 : }
1135 :
1136 : /* Add constraints to that the solution of VI is transitively closed. */
1137 :
1138 : static void
1139 26213547 : make_transitive_closure_constraints (varinfo_t vi)
1140 : {
1141 26213547 : struct constraint_expr lhs, rhs;
1142 :
1143 : /* VAR = *(VAR + UNKNOWN); */
1144 26213547 : lhs.type = SCALAR;
1145 26213547 : lhs.var = vi->id;
1146 26213547 : lhs.offset = 0;
1147 26213547 : rhs.type = DEREF;
1148 26213547 : rhs.var = vi->id;
1149 26213547 : rhs.offset = UNKNOWN_OFFSET;
1150 26213547 : process_constraint (new_constraint (lhs, rhs));
1151 26213547 : }
1152 :
1153 : /* Add constraints to that the solution of VI has all subvariables added. */
1154 :
1155 : static void
1156 31961828 : make_any_offset_constraints (varinfo_t vi)
1157 : {
1158 31961828 : struct constraint_expr lhs, rhs;
1159 :
1160 : /* VAR = VAR + UNKNOWN; */
1161 31961828 : lhs.type = SCALAR;
1162 31961828 : lhs.var = vi->id;
1163 31961828 : lhs.offset = 0;
1164 31961828 : rhs.type = SCALAR;
1165 31961828 : rhs.var = vi->id;
1166 31961828 : rhs.offset = UNKNOWN_OFFSET;
1167 31961828 : process_constraint (new_constraint (lhs, rhs));
1168 31961828 : }
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 1048109 : build_fake_var_decl (tree type)
1177 : {
1178 1048109 : tree decl = (tree) XOBNEW (&fake_var_decl_obstack, struct tree_var_decl);
1179 1048109 : memset (decl, 0, sizeof (struct tree_var_decl));
1180 1048109 : TREE_SET_CODE (decl, VAR_DECL);
1181 1048109 : TREE_TYPE (decl) = type;
1182 1048109 : DECL_UID (decl) = allocate_decl_uid ();
1183 1048109 : SET_DECL_PT_UID (decl, -1);
1184 1048109 : layout_decl (decl, 0);
1185 1048109 : return decl;
1186 : }
1187 :
1188 : /* Create a new artificial heap variable with NAME.
1189 : Return the created variable. */
1190 :
1191 : static varinfo_t
1192 434781 : make_heapvar (const char *name, bool add_id)
1193 : {
1194 434781 : varinfo_t vi;
1195 434781 : tree heapvar;
1196 :
1197 434781 : heapvar = build_fake_var_decl (ptr_type_node);
1198 434781 : DECL_EXTERNAL (heapvar) = 1;
1199 :
1200 434781 : vi = new_var_info (heapvar, name, add_id);
1201 434781 : vi->is_heap_var = true;
1202 434781 : vi->is_unknown_size_var = true;
1203 434781 : vi->offset = 0;
1204 434781 : vi->fullsize = ~0;
1205 434781 : vi->size = ~0;
1206 434781 : vi->is_full_var = true;
1207 434781 : insert_vi_for_tree (heapvar, vi);
1208 :
1209 434781 : 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 13186 : make_constraint_from_restrict (varinfo_t lhs, const char *name, bool add_id)
1218 : {
1219 13186 : varinfo_t vi = make_heapvar (name, add_id);
1220 13186 : vi->is_restrict_var = 1;
1221 13186 : vi->is_global_var = 1;
1222 13186 : vi->may_have_pointers = 1;
1223 13186 : make_constraint_from (lhs, vi->id);
1224 13186 : 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 13186 : make_constraint_from_global_restrict (varinfo_t lhs, const char *name,
1234 : bool add_id)
1235 : {
1236 13186 : varinfo_t vi = make_constraint_from_restrict (lhs, name, add_id);
1237 13186 : make_copy_constraint (vi, nonlocal_id);
1238 13186 : 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 1473079 : get_function_part_constraint (varinfo_t fi, unsigned part)
1246 : {
1247 1473079 : struct constraint_expr c;
1248 :
1249 1473079 : gcc_assert (in_ipa_mode);
1250 :
1251 1473079 : 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 506913 : else if (fi->decl && TREE_CODE (fi->decl) == FUNCTION_DECL)
1259 : {
1260 503524 : varinfo_t ai = first_vi_for_offset (fi, part);
1261 503524 : if (ai)
1262 503524 : c.var = ai->id;
1263 : else
1264 : c.var = anything_id;
1265 : c.offset = 0;
1266 : c.type = SCALAR;
1267 : }
1268 : else
1269 : {
1270 3389 : c.var = fi->id;
1271 3389 : c.offset = part;
1272 3389 : c.type = DEREF;
1273 : }
1274 :
1275 1473079 : 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 30827339 : handle_call_arg (gcall *stmt, tree arg, vec<ce_s> *results, int flags,
1285 : int callescape_id, bool writes_global_memory)
1286 : {
1287 30827339 : int relevant_indirect_flags = EAF_NO_INDIRECT_CLOBBER | EAF_NO_INDIRECT_READ
1288 : | EAF_NO_INDIRECT_ESCAPE;
1289 30827339 : int relevant_flags = relevant_indirect_flags
1290 : | EAF_NO_DIRECT_CLOBBER
1291 : | EAF_NO_DIRECT_READ
1292 : | EAF_NO_DIRECT_ESCAPE;
1293 30827339 : if (gimple_call_lhs (stmt))
1294 : {
1295 11537201 : relevant_flags |= EAF_NOT_RETURNED_DIRECTLY | EAF_NOT_RETURNED_INDIRECTLY;
1296 11537201 : 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 11537201 : if (flags & EAF_NO_DIRECT_READ)
1304 2152369 : 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 30827339 : if ((flags & EAF_UNUSED) || ((flags & relevant_flags) == relevant_flags))
1311 : return;
1312 :
1313 : /* Produce varinfo for direct accesses to ARG. */
1314 29534374 : varinfo_t tem = new_var_info (NULL_TREE, "callarg", true);
1315 29534374 : tem->is_reg_var = true;
1316 29534374 : make_constraint_to (tem->id, arg);
1317 29534374 : make_any_offset_constraints (tem);
1318 :
1319 29534374 : 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 29534374 : if (((flags & EAF_NO_INDIRECT_CLOBBER) != 0)
1325 29534374 : == ((flags & EAF_NO_DIRECT_CLOBBER) != 0)
1326 28132291 : && (((flags & EAF_NO_INDIRECT_READ) != 0)
1327 28132291 : == ((flags & EAF_NO_DIRECT_READ) != 0))
1328 27149948 : && (((flags & EAF_NO_INDIRECT_ESCAPE) != 0)
1329 27149948 : == ((flags & EAF_NO_DIRECT_ESCAPE) != 0))
1330 26589837 : && (((flags & EAF_NOT_RETURNED_INDIRECTLY) != 0)
1331 26589837 : == ((flags & EAF_NOT_RETURNED_DIRECTLY) != 0)))
1332 : {
1333 24586316 : make_transitive_closure_constraints (tem);
1334 24586316 : callarg_transitive = true;
1335 : }
1336 :
1337 : /* If necessary, produce varinfo for indirect accesses to ARG. */
1338 29534374 : varinfo_t indir_tem = NULL;
1339 24586316 : if (!callarg_transitive
1340 4948058 : && (flags & relevant_indirect_flags) != relevant_indirect_flags)
1341 : {
1342 1743929 : struct constraint_expr lhs, rhs;
1343 1743929 : indir_tem = new_var_info (NULL_TREE, "indircallarg", true);
1344 1743929 : indir_tem->is_reg_var = true;
1345 :
1346 : /* indir_term = *tem. */
1347 1743929 : lhs.type = SCALAR;
1348 1743929 : lhs.var = indir_tem->id;
1349 1743929 : lhs.offset = 0;
1350 :
1351 1743929 : rhs.type = DEREF;
1352 1743929 : rhs.var = tem->id;
1353 1743929 : rhs.offset = UNKNOWN_OFFSET;
1354 1743929 : process_constraint (new_constraint (lhs, rhs));
1355 :
1356 1743929 : 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 1743929 : if (!(flags & EAF_NO_INDIRECT_READ))
1361 1627231 : make_transitive_closure_constraints (indir_tem);
1362 1743929 : gcc_checking_assert (!(flags & EAF_NO_DIRECT_READ));
1363 : }
1364 :
1365 29534374 : if (gimple_call_lhs (stmt))
1366 : {
1367 11273079 : if (!(flags & EAF_NOT_RETURNED_DIRECTLY))
1368 : {
1369 10307232 : struct constraint_expr cexpr;
1370 10307232 : cexpr.var = tem->id;
1371 10307232 : cexpr.type = SCALAR;
1372 10307232 : cexpr.offset = 0;
1373 10307232 : results->safe_push (cexpr);
1374 : }
1375 11273079 : if (!callarg_transitive & !(flags & EAF_NOT_RETURNED_INDIRECTLY))
1376 : {
1377 620054 : struct constraint_expr cexpr;
1378 620054 : cexpr.var = indir_tem->id;
1379 620054 : cexpr.type = SCALAR;
1380 620054 : cexpr.offset = 0;
1381 620054 : results->safe_push (cexpr);
1382 : }
1383 : }
1384 :
1385 29534374 : if (!(flags & EAF_NO_DIRECT_READ))
1386 : {
1387 27247840 : varinfo_t uses = get_call_use_vi (stmt);
1388 27247840 : make_copy_constraint (uses, tem->id);
1389 27247840 : if (!callarg_transitive & !(flags & EAF_NO_INDIRECT_READ))
1390 1627231 : make_copy_constraint (uses, indir_tem->id);
1391 : }
1392 : else
1393 : /* To read indirectly we need to read directly. */
1394 2286534 : gcc_checking_assert (flags & EAF_NO_INDIRECT_READ);
1395 :
1396 29534374 : if (!(flags & EAF_NO_DIRECT_CLOBBER))
1397 : {
1398 24326276 : struct constraint_expr lhs, rhs;
1399 :
1400 : /* *arg = callescape. */
1401 24326276 : lhs.type = DEREF;
1402 24326276 : lhs.var = tem->id;
1403 24326276 : lhs.offset = 0;
1404 :
1405 24326276 : rhs.type = SCALAR;
1406 24326276 : rhs.var = callescape_id;
1407 24326276 : rhs.offset = 0;
1408 24326276 : process_constraint (new_constraint (lhs, rhs));
1409 :
1410 : /* callclobbered = arg. */
1411 24326276 : make_copy_constraint (get_call_clobber_vi (stmt), tem->id);
1412 : }
1413 29534374 : if (!callarg_transitive & !(flags & EAF_NO_INDIRECT_CLOBBER))
1414 : {
1415 1432398 : struct constraint_expr lhs, rhs;
1416 :
1417 : /* *indir_arg = callescape. */
1418 1432398 : lhs.type = DEREF;
1419 1432398 : lhs.var = indir_tem->id;
1420 1432398 : lhs.offset = 0;
1421 :
1422 1432398 : rhs.type = SCALAR;
1423 1432398 : rhs.var = callescape_id;
1424 1432398 : rhs.offset = 0;
1425 1432398 : process_constraint (new_constraint (lhs, rhs));
1426 :
1427 : /* callclobbered = indir_arg. */
1428 1432398 : make_copy_constraint (get_call_clobber_vi (stmt), indir_tem->id);
1429 : }
1430 :
1431 29534374 : if (!(flags & (EAF_NO_DIRECT_ESCAPE | EAF_NO_INDIRECT_ESCAPE)))
1432 : {
1433 22757345 : struct constraint_expr lhs, rhs;
1434 :
1435 : /* callescape = arg; */
1436 22757345 : lhs.var = callescape_id;
1437 22757345 : lhs.offset = 0;
1438 22757345 : lhs.type = SCALAR;
1439 :
1440 22757345 : rhs.var = tem->id;
1441 22757345 : rhs.offset = 0;
1442 22757345 : rhs.type = SCALAR;
1443 22757345 : process_constraint (new_constraint (lhs, rhs));
1444 :
1445 22757345 : if (writes_global_memory)
1446 21967336 : make_escape_constraint (arg);
1447 : }
1448 6777029 : else if (!callarg_transitive & !(flags & EAF_NO_INDIRECT_ESCAPE))
1449 : {
1450 1361036 : struct constraint_expr lhs, rhs;
1451 :
1452 : /* callescape = *(indir_arg + UNKNOWN); */
1453 1361036 : lhs.var = callescape_id;
1454 1361036 : lhs.offset = 0;
1455 1361036 : lhs.type = SCALAR;
1456 :
1457 1361036 : rhs.var = indir_tem->id;
1458 1361036 : rhs.offset = 0;
1459 1361036 : rhs.type = SCALAR;
1460 1361036 : process_constraint (new_constraint (lhs, rhs));
1461 :
1462 1361036 : if (writes_global_memory)
1463 1244171 : make_indirect_escape_constraint (tem);
1464 : }
1465 : }
1466 :
1467 : /* For non-IPA mode or for a function with body not available.
1468 : Generate constraints necessary for a call on the RHS and collect return
1469 : value constraint to RESULTS to be used later in 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 15492987 : 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 15492987 : determine_global_memory_access (stmt, &writes_global_memory,
1482 : &reads_global_memory,
1483 : NULL);
1484 :
1485 15492987 : 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 15492987 : struct constraint_expr lhs, rhs;
1491 :
1492 15492987 : lhs.type = SCALAR;
1493 15492987 : lhs.var = callescape->id;
1494 15492987 : lhs.offset = 0;
1495 :
1496 15492987 : rhs.type = reads_global_memory ? SCALAR : ADDRESSOF;
1497 15492987 : rhs.var = nonlocal_id;
1498 15492987 : rhs.offset = 0;
1499 :
1500 15492987 : process_constraint (new_constraint (lhs, rhs));
1501 15492987 : results->safe_push (rhs);
1502 :
1503 15492987 : varinfo_t uses = get_call_use_vi (stmt);
1504 15492987 : make_copy_constraint (uses, callescape->id);
1505 :
1506 61729300 : for (unsigned i = 0; i < gimple_call_num_args (stmt); ++i)
1507 : {
1508 30743326 : tree arg = gimple_call_arg (stmt, i);
1509 30743326 : int flags = gimple_call_arg_flags (stmt, i);
1510 30743326 : handle_call_arg (stmt, arg, results,
1511 : flags | implicit_eaf_flags,
1512 30743326 : callescape->id, writes_global_memory);
1513 : }
1514 :
1515 : /* The static chain escapes as well. */
1516 15492987 : if (gimple_call_chain (stmt))
1517 84013 : handle_call_arg (stmt, gimple_call_chain (stmt), results,
1518 : implicit_eaf_flags
1519 84013 : | gimple_call_static_chain_flags (stmt),
1520 84013 : callescape->id, writes_global_memory);
1521 :
1522 : /* And if we applied NRV the address of the return slot escapes as well. */
1523 15492987 : if (gimple_call_return_slot_opt_p (stmt)
1524 639072 : && gimple_call_lhs (stmt) != NULL_TREE
1525 16102938 : && TREE_ADDRESSABLE (TREE_TYPE (gimple_call_lhs (stmt))))
1526 : {
1527 84253 : int flags = gimple_call_retslot_flags (stmt);
1528 84253 : const int relevant_flags = EAF_NO_DIRECT_ESCAPE
1529 : | EAF_NOT_RETURNED_DIRECTLY;
1530 :
1531 84253 : if (!(flags & EAF_UNUSED) && (flags & relevant_flags) != relevant_flags)
1532 : {
1533 62740 : auto_vec<ce_s> tmpc;
1534 :
1535 62740 : get_constraint_for_address_of (gimple_call_lhs (stmt), &tmpc);
1536 :
1537 62740 : if (!(flags & EAF_NO_DIRECT_ESCAPE))
1538 : {
1539 62738 : make_constraints_to (callescape->id, tmpc);
1540 62738 : if (writes_global_memory)
1541 61240 : make_constraints_to (escaped_id, tmpc);
1542 : }
1543 62740 : if (!(flags & EAF_NOT_RETURNED_DIRECTLY))
1544 : {
1545 : struct constraint_expr *c;
1546 : unsigned i;
1547 185692 : FOR_EACH_VEC_ELT (tmpc, i, c)
1548 61476 : results->safe_push (*c);
1549 : }
1550 62740 : }
1551 : }
1552 15492987 : }
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 5887537 : handle_lhs_call (gcall *stmt, tree lhs, int flags, vec<ce_s> &rhsc,
1560 : tree fndecl)
1561 : {
1562 5887537 : auto_vec<ce_s> lhsc;
1563 :
1564 5887537 : get_constraint_for (lhs, &lhsc);
1565 : /* If the store is to a global decl make sure to
1566 : add proper escape constraints. */
1567 5887537 : lhs = get_base_address (lhs);
1568 5887537 : if (lhs
1569 5887537 : && DECL_P (lhs)
1570 6909006 : && is_global_var (lhs))
1571 : {
1572 3146 : struct constraint_expr tmpc;
1573 3146 : tmpc.var = escaped_id;
1574 3146 : tmpc.offset = 0;
1575 3146 : tmpc.type = SCALAR;
1576 3146 : lhsc.safe_push (tmpc);
1577 : }
1578 :
1579 : /* If the call returns an argument unmodified override the rhs
1580 : constraints. */
1581 5887537 : if (flags & ERF_RETURNS_ARG
1582 5887537 : && (flags & ERF_RETURN_ARG_MASK) < gimple_call_num_args (stmt))
1583 : {
1584 106567 : tree arg;
1585 106567 : rhsc.truncate (0);
1586 106567 : arg = gimple_call_arg (stmt, flags & ERF_RETURN_ARG_MASK);
1587 106567 : get_constraint_for (arg, &rhsc);
1588 106567 : process_all_all_constraints (lhsc, rhsc);
1589 106567 : rhsc.truncate (0);
1590 : }
1591 5780970 : else if (flags & ERF_NOALIAS)
1592 : {
1593 388759 : varinfo_t vi;
1594 388759 : struct constraint_expr tmpc;
1595 388759 : rhsc.truncate (0);
1596 388759 : 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 388759 : DECL_EXTERNAL (vi->decl) = 0;
1600 388759 : 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 388759 : if (!fndecl
1605 388759 : || !fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
1606 227803 : make_constraint_from (vi, nonlocal_id);
1607 388759 : tmpc.var = vi->id;
1608 388759 : tmpc.offset = 0;
1609 388759 : tmpc.type = ADDRESSOF;
1610 388759 : rhsc.safe_push (tmpc);
1611 388759 : process_all_all_constraints (lhsc, rhsc);
1612 388759 : rhsc.truncate (0);
1613 : }
1614 : else
1615 5392211 : process_all_all_constraints (lhsc, rhsc);
1616 5887537 : }
1617 :
1618 :
1619 : /* Create constraints for assigning call argument ARG to the incoming parameter
1620 : INDEX of function FI. */
1621 :
1622 : static void
1623 824524 : find_func_aliases_for_call_arg (varinfo_t fi, unsigned index, tree arg)
1624 : {
1625 824524 : struct constraint_expr lhs;
1626 824524 : lhs = get_function_part_constraint (fi, fi_parm_base + index);
1627 :
1628 824524 : auto_vec<ce_s, 2> rhsc;
1629 824524 : get_constraint_for_rhs (arg, &rhsc);
1630 :
1631 824524 : unsigned j;
1632 824524 : struct constraint_expr *rhsp;
1633 3298097 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
1634 824525 : process_constraint (new_constraint (lhs, *rhsp));
1635 824524 : }
1636 :
1637 : /* Create constraints for the builtin call T. Return true if the call
1638 : was handled, otherwise false. */
1639 :
1640 : static bool
1641 5272225 : find_func_aliases_for_builtin_call (struct function *fn, gcall *t)
1642 : {
1643 5272225 : tree fndecl = gimple_call_fndecl (t);
1644 5272225 : auto_vec<ce_s, 2> lhsc;
1645 5272225 : auto_vec<ce_s, 4> rhsc;
1646 5272225 : varinfo_t fi;
1647 :
1648 5272225 : 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 4790158 : 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 309046 : case BUILT_IN_STRCPY:
1659 309046 : case BUILT_IN_STRNCPY:
1660 309046 : case BUILT_IN_BCOPY:
1661 309046 : case BUILT_IN_MEMCPY:
1662 309046 : case BUILT_IN_MEMMOVE:
1663 309046 : case BUILT_IN_MEMPCPY:
1664 309046 : case BUILT_IN_STPCPY:
1665 309046 : case BUILT_IN_STPNCPY:
1666 309046 : case BUILT_IN_STRCAT:
1667 309046 : case BUILT_IN_STRNCAT:
1668 309046 : case BUILT_IN_STRCPY_CHK:
1669 309046 : case BUILT_IN_STRNCPY_CHK:
1670 309046 : case BUILT_IN_MEMCPY_CHK:
1671 309046 : case BUILT_IN_MEMMOVE_CHK:
1672 309046 : case BUILT_IN_MEMPCPY_CHK:
1673 309046 : case BUILT_IN_STPCPY_CHK:
1674 309046 : case BUILT_IN_STPNCPY_CHK:
1675 309046 : case BUILT_IN_STRCAT_CHK:
1676 309046 : case BUILT_IN_STRNCAT_CHK:
1677 309046 : case BUILT_IN_TM_MEMCPY:
1678 309046 : case BUILT_IN_TM_MEMMOVE:
1679 309046 : {
1680 309046 : tree res = gimple_call_lhs (t);
1681 618092 : tree dest = gimple_call_arg (t, (DECL_FUNCTION_CODE (fndecl)
1682 : == BUILT_IN_BCOPY ? 1 : 0));
1683 618092 : tree src = gimple_call_arg (t, (DECL_FUNCTION_CODE (fndecl)
1684 309046 : == BUILT_IN_BCOPY ? 0 : 1));
1685 309046 : if (res != NULL_TREE)
1686 : {
1687 26753 : get_constraint_for (res, &lhsc);
1688 26753 : if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_MEMPCPY
1689 23658 : || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPCPY
1690 22485 : || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPNCPY
1691 20723 : || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_MEMPCPY_CHK
1692 20394 : || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPCPY_CHK
1693 46874 : || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPNCPY_CHK)
1694 6904 : get_constraint_for_ptr_offset (dest, NULL_TREE, &rhsc);
1695 : else
1696 19849 : get_constraint_for (dest, &rhsc);
1697 26753 : process_all_all_constraints (lhsc, rhsc);
1698 26753 : lhsc.truncate (0);
1699 26753 : rhsc.truncate (0);
1700 : }
1701 309046 : get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
1702 309046 : get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
1703 309046 : do_deref (&lhsc);
1704 309046 : do_deref (&rhsc);
1705 309046 : process_all_all_constraints (lhsc, rhsc);
1706 309046 : return true;
1707 : }
1708 74814 : case BUILT_IN_MEMSET:
1709 74814 : case BUILT_IN_MEMSET_CHK:
1710 74814 : case BUILT_IN_TM_MEMSET:
1711 74814 : {
1712 74814 : tree res = gimple_call_lhs (t);
1713 74814 : tree dest = gimple_call_arg (t, 0);
1714 74814 : unsigned i;
1715 74814 : ce_s *lhsp;
1716 74814 : struct constraint_expr ac;
1717 74814 : if (res != NULL_TREE)
1718 : {
1719 5355 : get_constraint_for (res, &lhsc);
1720 5355 : get_constraint_for (dest, &rhsc);
1721 5355 : process_all_all_constraints (lhsc, rhsc);
1722 5355 : lhsc.truncate (0);
1723 : }
1724 74814 : get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
1725 74814 : do_deref (&lhsc);
1726 74814 : if (flag_delete_null_pointer_checks
1727 149487 : && 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 74814 : ac.offset = 0;
1738 5428332 : FOR_EACH_VEC_ELT (lhsc, i, lhsp)
1739 81293 : process_constraint (new_constraint (*lhsp, ac));
1740 : return true;
1741 : }
1742 14959 : case BUILT_IN_STACK_SAVE:
1743 14959 : case BUILT_IN_STACK_RESTORE:
1744 : /* Nothing interesting happens. */
1745 14959 : return true;
1746 32717 : case BUILT_IN_ALLOCA:
1747 32717 : case BUILT_IN_ALLOCA_WITH_ALIGN:
1748 32717 : case BUILT_IN_ALLOCA_WITH_ALIGN_AND_MAX:
1749 32717 : {
1750 32717 : tree ptr = gimple_call_lhs (t);
1751 32717 : if (ptr == NULL_TREE)
1752 : return true;
1753 32704 : get_constraint_for (ptr, &lhsc);
1754 32704 : 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 32704 : DECL_EXTERNAL (vi->decl) = 0;
1758 32704 : vi->is_global_var = 0;
1759 32704 : vi->is_heap_var = 0;
1760 32704 : struct constraint_expr tmpc;
1761 32704 : tmpc.var = vi->id;
1762 32704 : tmpc.offset = 0;
1763 32704 : tmpc.type = ADDRESSOF;
1764 32704 : rhsc.safe_push (tmpc);
1765 32704 : process_all_all_constraints (lhsc, rhsc);
1766 32704 : 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 2219 : case BUILT_IN_ASSUME_ALIGNED:
1787 2219 : {
1788 2219 : tree res = gimple_call_lhs (t);
1789 2219 : tree dest = gimple_call_arg (t, 0);
1790 2219 : if (res != NULL_TREE)
1791 : {
1792 2219 : get_constraint_for (res, &lhsc);
1793 2219 : get_constraint_for (dest, &rhsc);
1794 2219 : process_all_all_constraints (lhsc, rhsc);
1795 : }
1796 : 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 133946 : case BUILT_IN_SINCOS:
1802 133946 : case BUILT_IN_SINCOSF:
1803 133946 : case BUILT_IN_SINCOSL:
1804 133946 : case BUILT_IN_FREXP:
1805 133946 : case BUILT_IN_FREXPF:
1806 133946 : case BUILT_IN_FREXPL:
1807 133946 : case BUILT_IN_GAMMA_R:
1808 133946 : case BUILT_IN_GAMMAF_R:
1809 133946 : case BUILT_IN_GAMMAL_R:
1810 133946 : case BUILT_IN_LGAMMA_R:
1811 133946 : case BUILT_IN_LGAMMAF_R:
1812 133946 : case BUILT_IN_LGAMMAL_R:
1813 133946 : case BUILT_IN_MODF:
1814 133946 : case BUILT_IN_MODFF:
1815 133946 : case BUILT_IN_MODFL:
1816 133946 : case BUILT_IN_REMQUO:
1817 133946 : case BUILT_IN_REMQUOF:
1818 133946 : case BUILT_IN_REMQUOL:
1819 133946 : case BUILT_IN_FREE:
1820 133946 : return true;
1821 17347 : case BUILT_IN_STRDUP:
1822 17347 : case BUILT_IN_STRNDUP:
1823 17347 : case BUILT_IN_REALLOC:
1824 17347 : if (gimple_call_lhs (t))
1825 : {
1826 17311 : auto_vec<ce_s> rhsc;
1827 17311 : handle_lhs_call (t, gimple_call_lhs (t),
1828 17311 : gimple_call_return_flags (t) | ERF_NOALIAS,
1829 : rhsc, fndecl);
1830 17311 : get_constraint_for_ptr_offset (gimple_call_lhs (t),
1831 : NULL_TREE, &lhsc);
1832 17311 : get_constraint_for_ptr_offset (gimple_call_arg (t, 0),
1833 : NULL_TREE, &rhsc);
1834 17311 : do_deref (&lhsc);
1835 17311 : do_deref (&rhsc);
1836 17311 : process_all_all_constraints (lhsc, rhsc);
1837 17311 : lhsc.truncate (0);
1838 17311 : 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 17311 : if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_REALLOC)
1843 : {
1844 15654 : get_constraint_for (gimple_call_lhs (t), &lhsc);
1845 15654 : get_constraint_for (gimple_call_arg (t, 0), &rhsc);
1846 15654 : process_all_all_constraints (lhsc, rhsc);
1847 : }
1848 17311 : return true;
1849 17311 : }
1850 : break;
1851 : /* String / character search functions return a pointer into the
1852 : source string or NULL. */
1853 13179 : case BUILT_IN_INDEX:
1854 13179 : case BUILT_IN_STRCHR:
1855 13179 : case BUILT_IN_STRRCHR:
1856 13179 : case BUILT_IN_MEMCHR:
1857 13179 : case BUILT_IN_STRSTR:
1858 13179 : case BUILT_IN_STRPBRK:
1859 13179 : if (gimple_call_lhs (t))
1860 : {
1861 13179 : tree src = gimple_call_arg (t, 0);
1862 13179 : get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
1863 13179 : constraint_expr nul;
1864 13179 : nul.var = nothing_id;
1865 13179 : nul.offset = 0;
1866 13179 : nul.type = ADDRESSOF;
1867 13179 : rhsc.safe_push (nul);
1868 13179 : get_constraint_for (gimple_call_lhs (t), &lhsc);
1869 13179 : process_all_all_constraints (lhsc, rhsc);
1870 : }
1871 : 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 633762 : case BUILT_IN_STRCMP:
1876 633762 : case BUILT_IN_STRCMP_EQ:
1877 633762 : case BUILT_IN_STRNCMP:
1878 633762 : case BUILT_IN_STRNCMP_EQ:
1879 633762 : case BUILT_IN_STRCASECMP:
1880 633762 : case BUILT_IN_STRNCASECMP:
1881 633762 : case BUILT_IN_MEMCMP:
1882 633762 : case BUILT_IN_BCMP:
1883 633762 : case BUILT_IN_STRSPN:
1884 633762 : case BUILT_IN_STRCSPN:
1885 633762 : {
1886 633762 : varinfo_t uses = get_call_use_vi (t);
1887 633762 : make_any_offset_constraints (uses);
1888 633762 : make_constraint_to (uses->id, gimple_call_arg (t, 0));
1889 633762 : make_constraint_to (uses->id, gimple_call_arg (t, 1));
1890 : /* No constraints are necessary for the return value. */
1891 633762 : return true;
1892 : }
1893 49763 : case BUILT_IN_STRLEN:
1894 49763 : {
1895 49763 : varinfo_t uses = get_call_use_vi (t);
1896 49763 : make_any_offset_constraints (uses);
1897 49763 : make_constraint_to (uses->id, gimple_call_arg (t, 0));
1898 : /* No constraints are necessary for the return value. */
1899 49763 : return true;
1900 : }
1901 67506 : case BUILT_IN_OBJECT_SIZE:
1902 67506 : case BUILT_IN_CONSTANT_P:
1903 67506 : {
1904 : /* No constraints are necessary for the return value or the
1905 : arguments. */
1906 67506 : return true;
1907 : }
1908 : /* Trampolines are special - they set up passing the static
1909 : frame. */
1910 482 : case BUILT_IN_INIT_TRAMPOLINE:
1911 482 : {
1912 482 : tree tramp = gimple_call_arg (t, 0);
1913 482 : tree nfunc = gimple_call_arg (t, 1);
1914 482 : tree frame = gimple_call_arg (t, 2);
1915 482 : unsigned i;
1916 482 : struct constraint_expr lhs, *rhsp;
1917 482 : 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 475 : break;
1943 : }
1944 519 : case BUILT_IN_ADJUST_TRAMPOLINE:
1945 519 : {
1946 519 : tree tramp = gimple_call_arg (t, 0);
1947 519 : tree res = gimple_call_lhs (t);
1948 519 : 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 : 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 20179 : case BUILT_IN_VA_START:
2000 20179 : {
2001 20179 : tree valist = gimple_call_arg (t, 0);
2002 20179 : struct constraint_expr rhs, *lhsp;
2003 20179 : unsigned i;
2004 20179 : get_constraint_for_ptr_offset (valist, NULL_TREE, &lhsc);
2005 20179 : 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 20179 : if (in_ipa_mode)
2010 : {
2011 8 : fi = lookup_vi_for_tree (fn->decl);
2012 8 : rhs = get_function_part_constraint (fi, ~0);
2013 8 : rhs.type = SCALAR;
2014 : }
2015 : else
2016 : {
2017 : rhs.var = nonlocal_id;
2018 : rhs.type = SCALAR;
2019 : rhs.offset = 0;
2020 : }
2021 40525 : FOR_EACH_VEC_ELT (lhsc, i, lhsp)
2022 20346 : process_constraint (new_constraint (*lhsp, rhs));
2023 : /* va_list is clobbered. */
2024 20179 : make_constraint_to (get_call_clobber_vi (t)->id, valist);
2025 20179 : return true;
2026 : }
2027 : /* va_end doesn't have any effect that matters. */
2028 9796 : case BUILT_IN_VA_END:
2029 9796 : 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 : return true;
2048 : }
2049 55412 : case BUILT_IN_GOMP_PARALLEL:
2050 55412 : case BUILT_IN_GOACC_PARALLEL:
2051 55412 : {
2052 55412 : if (in_ipa_mode)
2053 : {
2054 14092 : unsigned int fnpos, argpos;
2055 14092 : 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 14079 : case BUILT_IN_GOACC_PARALLEL:
2063 : /* __builtin_GOACC_parallel (flags_m, fn, mapnum, hostaddrs,
2064 : sizes, kinds, ...). */
2065 14079 : fnpos = 1;
2066 14079 : argpos = 3;
2067 14079 : break;
2068 : default:
2069 : gcc_unreachable ();
2070 : }
2071 :
2072 14092 : tree fnarg = gimple_call_arg (t, fnpos);
2073 14092 : gcc_assert (TREE_CODE (fnarg) == ADDR_EXPR);
2074 14092 : tree fndecl = TREE_OPERAND (fnarg, 0);
2075 14092 : if (fndecl_maybe_in_other_partition (fndecl))
2076 : /* Fallthru to general call handling. */
2077 : break;
2078 :
2079 14049 : tree arg = gimple_call_arg (t, argpos);
2080 :
2081 14049 : varinfo_t fi = get_vi_for_tree (fndecl);
2082 14049 : find_func_aliases_for_call_arg (fi, 0, arg);
2083 14049 : 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 5272225 : }
2097 :
2098 : /* Create constraints for the call T. */
2099 :
2100 : static void
2101 18386830 : find_func_aliases_for_call (struct function *fn, gcall *t)
2102 : {
2103 18386830 : tree fndecl = gimple_call_fndecl (t);
2104 18386830 : varinfo_t fi;
2105 :
2106 18386830 : if (fndecl != NULL_TREE
2107 17085534 : && fndecl_built_in_p (fndecl)
2108 23659055 : && find_func_aliases_for_builtin_call (fn, t))
2109 : return;
2110 :
2111 16991972 : if (gimple_call_internal_p (t, IFN_VA_ARG)
2112 16991972 : && gimple_call_lhs (t))
2113 : {
2114 8420 : tree valist = gimple_call_arg (t, 0);
2115 8420 : auto_vec<ce_s, 1> rhsc, lhsc;
2116 8420 : get_constraint_for_rhs (valist, &rhsc);
2117 8420 : do_deref (&rhsc);
2118 8420 : get_constraint_for (gimple_call_lhs (t), &lhsc);
2119 8420 : process_all_all_constraints (lhsc, rhsc);
2120 : /* va_list is used and clobbered. */
2121 8420 : make_constraint_to (get_call_use_vi (t)->id, valist);
2122 8420 : make_constraint_to (get_call_clobber_vi (t)->id, valist);
2123 8420 : return;
2124 8420 : }
2125 :
2126 16983552 : if (gimple_call_internal_p (t, IFN_DEFERRED_INIT))
2127 : return;
2128 :
2129 16754850 : fi = get_fi_for_callee (t);
2130 16754850 : if (!in_ipa_mode
2131 244329 : || (fi->decl && fndecl && !fi->is_fn_info))
2132 : {
2133 16567606 : auto_vec<ce_s, 16> rhsc;
2134 16567606 : int flags = gimple_call_flags (t);
2135 :
2136 : /* Const functions can return their arguments and addresses
2137 : of global memory but not of escaped memory. */
2138 16567606 : if (flags & (ECF_CONST|ECF_NOVOPS))
2139 : {
2140 1640290 : if (gimple_call_lhs (t))
2141 939292 : handle_rhs_call (t, &rhsc, implicit_const_eaf_flags, false, false);
2142 : }
2143 : /* Pure functions can return addresses in and of memory
2144 : reachable from their arguments, but they are not an escape
2145 : point for reachable memory of their arguments. */
2146 14927316 : else if (flags & (ECF_PURE|ECF_LOOPING_CONST_OR_PURE))
2147 562007 : handle_rhs_call (t, &rhsc, implicit_pure_eaf_flags, false, true);
2148 : /* If the call is to a replaceable operator delete and results
2149 : from a delete expression as opposed to a direct call to
2150 : such operator, then the effects for PTA (in particular
2151 : the escaping of the pointer) can be ignored. */
2152 14365309 : else if (fndecl
2153 13754735 : && flag_assume_sane_operators_new_delete
2154 13754329 : && DECL_IS_OPERATOR_DELETE_P (fndecl)
2155 377765 : && DECL_IS_REPLACEABLE_OPERATOR (fndecl)
2156 14742646 : && gimple_call_from_new_or_delete (t))
2157 : ;
2158 : else
2159 13991688 : handle_rhs_call (t, &rhsc, 0, true, true);
2160 16567606 : if (gimple_call_lhs (t))
2161 5870226 : handle_lhs_call (t, gimple_call_lhs (t),
2162 : gimple_call_return_flags (t), rhsc, fndecl);
2163 16567606 : }
2164 : else
2165 : {
2166 187244 : auto_vec<ce_s, 2> rhsc;
2167 187244 : tree lhsop;
2168 187244 : unsigned j;
2169 :
2170 : /* Assign all the passed arguments to the appropriate incoming
2171 : parameters of the function. */
2172 997719 : for (j = 0; j < gimple_call_num_args (t); j++)
2173 : {
2174 810475 : tree arg = gimple_call_arg (t, j);
2175 810475 : find_func_aliases_for_call_arg (fi, j, arg);
2176 : }
2177 :
2178 : /* If we are returning a value, assign it to the result. */
2179 187244 : lhsop = gimple_call_lhs (t);
2180 187244 : if (lhsop)
2181 : {
2182 166820 : auto_vec<ce_s, 2> lhsc;
2183 166820 : struct constraint_expr rhs;
2184 166820 : struct constraint_expr *lhsp;
2185 167674 : bool aggr_p = aggregate_value_p (lhsop, gimple_call_fntype (t));
2186 :
2187 166820 : get_constraint_for (lhsop, &lhsc);
2188 166820 : rhs = get_function_part_constraint (fi, fi_result);
2189 166820 : if (aggr_p)
2190 : {
2191 10 : auto_vec<ce_s, 2> tem;
2192 10 : tem.quick_push (rhs);
2193 10 : do_deref (&tem);
2194 10 : gcc_checking_assert (tem.length () == 1);
2195 10 : rhs = tem[0];
2196 10 : }
2197 333645 : FOR_EACH_VEC_ELT (lhsc, j, lhsp)
2198 166825 : process_constraint (new_constraint (*lhsp, rhs));
2199 :
2200 : /* If we pass the result decl by reference, honor that. */
2201 166820 : if (aggr_p)
2202 : {
2203 10 : struct constraint_expr lhs;
2204 10 : struct constraint_expr *rhsp;
2205 :
2206 10 : get_constraint_for_address_of (lhsop, &rhsc);
2207 10 : lhs = get_function_part_constraint (fi, fi_result);
2208 30 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
2209 10 : process_constraint (new_constraint (lhs, *rhsp));
2210 10 : rhsc.truncate (0);
2211 : }
2212 166820 : }
2213 :
2214 : /* If we use a static chain, pass it along. */
2215 187244 : if (gimple_call_chain (t))
2216 : {
2217 278 : struct constraint_expr lhs;
2218 278 : struct constraint_expr *rhsp;
2219 :
2220 278 : get_constraint_for (gimple_call_chain (t), &rhsc);
2221 278 : lhs = get_function_part_constraint (fi, fi_static_chain);
2222 1112 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
2223 278 : process_constraint (new_constraint (lhs, *rhsp));
2224 : }
2225 187244 : }
2226 : }
2227 :
2228 : /* Walk statement T setting up aliasing constraints according to the
2229 : references found in T. This function is the main part of the
2230 : constraint builder. AI points to auxiliary alias information used
2231 : when building alias sets and computing alias grouping heuristics. */
2232 :
2233 : static void
2234 275616542 : find_func_aliases (struct function *fn, gimple *origt)
2235 : {
2236 275616542 : gimple *t = origt;
2237 275616542 : auto_vec<ce_s, 16> lhsc;
2238 275616542 : auto_vec<ce_s, 16> rhsc;
2239 275616542 : varinfo_t fi;
2240 :
2241 : /* Now build constraints expressions. */
2242 275616542 : if (gimple_code (t) == GIMPLE_PHI)
2243 : {
2244 : /* For a phi node, assign all the arguments to
2245 : the result. */
2246 6288584 : get_constraint_for (gimple_phi_result (t), &lhsc);
2247 27803561 : for (unsigned i = 0; i < gimple_phi_num_args (t); i++)
2248 : {
2249 15226393 : get_constraint_for_rhs (gimple_phi_arg_def (t, i), &rhsc);
2250 15226393 : process_all_all_constraints (lhsc, rhsc);
2251 15226393 : rhsc.truncate (0);
2252 : }
2253 : }
2254 : /* In IPA mode, we need to generate constraints to pass call
2255 : arguments through their calls. There are two cases,
2256 : either a GIMPLE_CALL returning a value, or just a plain
2257 : GIMPLE_CALL when we are not.
2258 :
2259 : In non-ipa mode, we need to generate constraints for each
2260 : pointer passed by address. */
2261 269327958 : else if (is_gimple_call (t))
2262 18386830 : find_func_aliases_for_call (fn, as_a <gcall *> (t));
2263 :
2264 : /* Otherwise, just a regular assignment statement. Only care about
2265 : operations with pointer result, others are dealt with as escape
2266 : points if they have pointer operands. */
2267 250941128 : else if (is_gimple_assign (t))
2268 : {
2269 : /* Otherwise, just a regular assignment statement. */
2270 82392943 : tree lhsop = gimple_assign_lhs (t);
2271 82392943 : tree rhsop = (gimple_num_ops (t) == 2) ? gimple_assign_rhs1 (t) : NULL;
2272 :
2273 64324543 : if (rhsop && TREE_CLOBBER_P (rhsop))
2274 : /* Ignore clobbers, they don't actually store anything into
2275 : the LHS. */
2276 : ;
2277 58831543 : else if (rhsop && AGGREGATE_TYPE_P (TREE_TYPE (lhsop)))
2278 2579300 : do_structure_copy (lhsop, rhsop);
2279 : else
2280 : {
2281 74320643 : enum tree_code code = gimple_assign_rhs_code (t);
2282 :
2283 74320643 : get_constraint_for (lhsop, &lhsc);
2284 :
2285 74320643 : if (code == POINTER_PLUS_EXPR)
2286 2719544 : get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
2287 : gimple_assign_rhs2 (t), &rhsc);
2288 71601099 : else if (code == POINTER_DIFF_EXPR)
2289 : /* The result is not a pointer (part). */
2290 : ;
2291 71238512 : else if (code == BIT_AND_EXPR
2292 71238512 : && TREE_CODE (gimple_assign_rhs2 (t)) == INTEGER_CST)
2293 : {
2294 : /* Aligning a pointer via a BIT_AND_EXPR is offsetting
2295 : the pointer. Handle it by offsetting it by UNKNOWN. */
2296 585061 : get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
2297 : NULL_TREE, &rhsc);
2298 : }
2299 70653451 : else if (code == TRUNC_DIV_EXPR
2300 : || code == CEIL_DIV_EXPR
2301 : || code == FLOOR_DIV_EXPR
2302 70653451 : || code == ROUND_DIV_EXPR
2303 70653451 : || code == EXACT_DIV_EXPR
2304 : || code == TRUNC_MOD_EXPR
2305 70274487 : || code == CEIL_MOD_EXPR
2306 : || code == FLOOR_MOD_EXPR
2307 70106477 : || code == ROUND_MOD_EXPR)
2308 : /* Division and modulo transfer the pointer from the LHS. */
2309 548507 : get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
2310 : NULL_TREE, &rhsc);
2311 70104944 : else if (CONVERT_EXPR_CODE_P (code)
2312 70104944 : || gimple_assign_single_p (t))
2313 : /* See through conversions, single RHS are handled by
2314 : get_constraint_for_rhs. */
2315 55538310 : get_constraint_for_rhs (rhsop, &rhsc);
2316 14566634 : else if (code == COND_EXPR)
2317 : {
2318 : /* The result is a merge of both COND_EXPR arms. */
2319 11103 : auto_vec<ce_s, 2> tmp;
2320 11103 : struct constraint_expr *rhsp;
2321 11103 : unsigned i;
2322 11103 : get_constraint_for_rhs (gimple_assign_rhs2 (t), &rhsc);
2323 11103 : get_constraint_for_rhs (gimple_assign_rhs3 (t), &tmp);
2324 44412 : FOR_EACH_VEC_ELT (tmp, i, rhsp)
2325 11103 : rhsc.safe_push (*rhsp);
2326 11103 : }
2327 14555531 : else if (truth_value_p (code))
2328 : /* Truth value results are not pointer (parts). Or at least
2329 : very unreasonable obfuscation of a part. */
2330 : ;
2331 : else
2332 : {
2333 : /* All other operations are possibly offsetting merges. */
2334 13095710 : auto_vec<ce_s, 4> tmp;
2335 13095710 : struct constraint_expr *rhsp;
2336 13095710 : unsigned i, j;
2337 13095710 : get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
2338 : NULL_TREE, &rhsc);
2339 38688921 : for (i = 2; i < gimple_num_ops (t); ++i)
2340 : {
2341 12497501 : get_constraint_for_ptr_offset (gimple_op (t, i),
2342 : NULL_TREE, &tmp);
2343 37492503 : FOR_EACH_VEC_ELT (tmp, j, rhsp)
2344 12497501 : rhsc.safe_push (*rhsp);
2345 12497501 : tmp.truncate (0);
2346 : }
2347 13095710 : }
2348 74320643 : process_all_all_constraints (lhsc, rhsc);
2349 : }
2350 : /* If there is a store to a global variable the rhs escapes. */
2351 82392943 : if ((lhsop = get_base_address (lhsop)) != NULL_TREE
2352 82392943 : && DECL_P (lhsop))
2353 : {
2354 22873856 : varinfo_t vi = get_vi_for_tree (lhsop);
2355 22873856 : if ((! in_ipa_mode && vi->is_global_var)
2356 21216461 : || vi->is_ipa_escape_point)
2357 1659961 : make_escape_constraint (rhsop);
2358 : }
2359 : }
2360 : /* Handle escapes through return. */
2361 168548185 : else if (gimple_code (t) == GIMPLE_RETURN
2362 168548185 : && gimple_return_retval (as_a <greturn *> (t)) != NULL_TREE)
2363 : {
2364 2535813 : greturn *return_stmt = as_a <greturn *> (t);
2365 2535813 : tree retval = gimple_return_retval (return_stmt);
2366 2535813 : if (!in_ipa_mode)
2367 2531476 : make_constraint_to (escaped_return_id, retval);
2368 : else
2369 : {
2370 4337 : struct constraint_expr lhs ;
2371 4337 : struct constraint_expr *rhsp;
2372 4337 : unsigned i;
2373 :
2374 4337 : fi = lookup_vi_for_tree (fn->decl);
2375 4337 : lhs = get_function_part_constraint (fi, fi_result);
2376 4337 : get_constraint_for_rhs (retval, &rhsc);
2377 17350 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
2378 4339 : process_constraint (new_constraint (lhs, *rhsp));
2379 : }
2380 : }
2381 : /* Handle asms conservatively by adding escape constraints to everything. */
2382 275844324 : else if (gasm *asm_stmt = dyn_cast <gasm *> (t))
2383 : {
2384 227782 : unsigned i, noutputs;
2385 227782 : const char **oconstraints;
2386 227782 : const char *constraint;
2387 227782 : bool allows_mem, allows_reg, is_inout;
2388 :
2389 227782 : noutputs = gimple_asm_noutputs (asm_stmt);
2390 227782 : oconstraints = XALLOCAVEC (const char *, noutputs);
2391 :
2392 481136 : for (i = 0; i < noutputs; ++i)
2393 : {
2394 253354 : tree link = gimple_asm_output_op (asm_stmt, i);
2395 253354 : tree op = TREE_VALUE (link);
2396 :
2397 253354 : constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
2398 253354 : oconstraints[i] = constraint;
2399 253354 : parse_output_constraint (&constraint, i, 0, 0, &allows_mem,
2400 : &allows_reg, &is_inout, nullptr);
2401 :
2402 : /* A memory constraint makes the address of the operand escape. */
2403 253354 : if (!allows_reg && allows_mem)
2404 : {
2405 19900 : auto_vec<ce_s> tmpc;
2406 19900 : get_constraint_for_address_of (op, &tmpc);
2407 19900 : make_constraints_to (escaped_id, tmpc);
2408 19900 : }
2409 :
2410 : /* The asm may read global memory, so outputs may point to
2411 : any global memory. */
2412 253354 : if (op)
2413 : {
2414 253354 : auto_vec<ce_s, 2> lhsc;
2415 253354 : struct constraint_expr rhsc, *lhsp;
2416 253354 : unsigned j;
2417 253354 : get_constraint_for (op, &lhsc);
2418 253354 : rhsc.var = nonlocal_id;
2419 253354 : rhsc.offset = 0;
2420 253354 : rhsc.type = SCALAR;
2421 1013419 : FOR_EACH_VEC_ELT (lhsc, j, lhsp)
2422 253357 : process_constraint (new_constraint (*lhsp, rhsc));
2423 253354 : }
2424 : }
2425 391148 : for (i = 0; i < gimple_asm_ninputs (asm_stmt); ++i)
2426 : {
2427 163366 : tree link = gimple_asm_input_op (asm_stmt, i);
2428 163366 : tree op = TREE_VALUE (link);
2429 :
2430 163366 : constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
2431 :
2432 163366 : parse_input_constraint (&constraint, 0, 0, noutputs, 0, oconstraints,
2433 : &allows_mem, &allows_reg, nullptr);
2434 :
2435 : /* A memory constraint makes the address of the operand escape. */
2436 163366 : if (!allows_reg && allows_mem)
2437 : {
2438 21030 : auto_vec<ce_s> tmpc;
2439 21030 : get_constraint_for_address_of (op, &tmpc);
2440 21030 : make_constraints_to (escaped_id, tmpc);
2441 21030 : }
2442 : /* Strictly we'd only need the constraint to ESCAPED if
2443 : the asm clobbers memory, otherwise using something
2444 : along the lines of per-call clobbers/uses would be enough. */
2445 142336 : else if (op)
2446 142336 : make_escape_constraint (op);
2447 : }
2448 : }
2449 275616542 : }
2450 :
2451 :
2452 : /* Create a constraint adding to the clobber set of FI the memory
2453 : pointed to by PTR. */
2454 :
2455 : static void
2456 0 : process_ipa_clobber (varinfo_t fi, tree ptr)
2457 : {
2458 0 : vec<ce_s> ptrc = vNULL;
2459 0 : struct constraint_expr *c, lhs;
2460 0 : unsigned i;
2461 0 : get_constraint_for_rhs (ptr, &ptrc);
2462 0 : lhs = get_function_part_constraint (fi, fi_clobbers);
2463 0 : FOR_EACH_VEC_ELT (ptrc, i, c)
2464 0 : process_constraint (new_constraint (lhs, *c));
2465 0 : ptrc.release ();
2466 0 : }
2467 :
2468 : /* Walk statement T setting up clobber and use constraints according to the
2469 : references found in T. This function is a main part of the
2470 : IPA constraint builder. */
2471 :
2472 : static void
2473 976780 : find_func_clobbers (struct function *fn, gimple *origt)
2474 : {
2475 976780 : gimple *t = origt;
2476 976780 : auto_vec<ce_s, 16> lhsc;
2477 976780 : auto_vec<ce_s, 16> rhsc;
2478 976780 : varinfo_t fi;
2479 :
2480 : /* Add constraints for clobbered/used in IPA mode.
2481 : We are not interested in what automatic variables are clobbered
2482 : or used as we only use the information in the caller to which
2483 : they do not escape. */
2484 976780 : gcc_assert (in_ipa_mode);
2485 :
2486 : /* If the stmt refers to memory in any way it better had a VUSE. */
2487 2087768 : if (gimple_vuse (t) == NULL_TREE)
2488 : return;
2489 :
2490 : /* We'd better have function information for the current function. */
2491 643667 : fi = lookup_vi_for_tree (fn->decl);
2492 643667 : gcc_assert (fi != NULL);
2493 :
2494 : /* Account for stores in assignments and calls. */
2495 1287334 : if (gimple_vdef (t) != NULL_TREE
2496 847472 : && gimple_has_lhs (t))
2497 : {
2498 340325 : tree lhs = gimple_get_lhs (t);
2499 340325 : tree tem = lhs;
2500 858690 : while (handled_component_p (tem))
2501 178040 : tem = TREE_OPERAND (tem, 0);
2502 340325 : if ((DECL_P (tem)
2503 193564 : && !auto_var_in_fn_p (tem, fn->decl))
2504 335154 : || INDIRECT_REF_P (tem)
2505 675479 : || (TREE_CODE (tem) == MEM_REF
2506 30373 : && !(TREE_CODE (TREE_OPERAND (tem, 0)) == ADDR_EXPR
2507 : && auto_var_in_fn_p
2508 4126 : (TREE_OPERAND (TREE_OPERAND (tem, 0), 0), fn->decl))))
2509 : {
2510 28186 : struct constraint_expr lhsc, *rhsp;
2511 28186 : unsigned i;
2512 28186 : lhsc = get_function_part_constraint (fi, fi_clobbers);
2513 28186 : get_constraint_for_address_of (lhs, &rhsc);
2514 84558 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
2515 28186 : process_constraint (new_constraint (lhsc, *rhsp));
2516 28186 : rhsc.truncate (0);
2517 : }
2518 : }
2519 :
2520 : /* Account for uses in assignments and returns. */
2521 643667 : if (gimple_assign_single_p (t)
2522 643667 : || (gimple_code (t) == GIMPLE_RETURN
2523 23482 : && gimple_return_retval (as_a <greturn *> (t)) != NULL_TREE))
2524 : {
2525 366344 : tree rhs = (gimple_assign_single_p (t)
2526 366344 : ? gimple_assign_rhs1 (t)
2527 4337 : : gimple_return_retval (as_a <greturn *> (t)));
2528 366344 : tree tem = rhs;
2529 521768 : while (handled_component_p (tem))
2530 155424 : tem = TREE_OPERAND (tem, 0);
2531 366344 : if ((DECL_P (tem)
2532 53661 : && !auto_var_in_fn_p (tem, fn->decl))
2533 357599 : || INDIRECT_REF_P (tem)
2534 723943 : || (TREE_CODE (tem) == MEM_REF
2535 90192 : && !(TREE_CODE (TREE_OPERAND (tem, 0)) == ADDR_EXPR
2536 : && auto_var_in_fn_p
2537 1102 : (TREE_OPERAND (TREE_OPERAND (tem, 0), 0), fn->decl))))
2538 : {
2539 97247 : struct constraint_expr lhs, *rhsp;
2540 97247 : unsigned i;
2541 97247 : lhs = get_function_part_constraint (fi, fi_uses);
2542 97247 : get_constraint_for_address_of (rhs, &rhsc);
2543 291741 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
2544 97247 : process_constraint (new_constraint (lhs, *rhsp));
2545 97247 : rhsc.truncate (0);
2546 : }
2547 : }
2548 :
2549 643667 : if (gcall *call_stmt = dyn_cast <gcall *> (t))
2550 : {
2551 258136 : varinfo_t cfi = NULL;
2552 258136 : tree decl = gimple_call_fndecl (t);
2553 258136 : struct constraint_expr lhs, rhs;
2554 258136 : unsigned i, j;
2555 :
2556 : /* For builtins we do not have separate function info. For those
2557 : we do not generate escapes for we have to generate clobbers/uses. */
2558 258136 : if (gimple_call_builtin_p (t, BUILT_IN_NORMAL))
2559 38289 : switch (DECL_FUNCTION_CODE (decl))
2560 : {
2561 : /* The following functions use and clobber memory pointed to
2562 : by their arguments. */
2563 162 : case BUILT_IN_STRCPY:
2564 162 : case BUILT_IN_STRNCPY:
2565 162 : case BUILT_IN_BCOPY:
2566 162 : case BUILT_IN_MEMCPY:
2567 162 : case BUILT_IN_MEMMOVE:
2568 162 : case BUILT_IN_MEMPCPY:
2569 162 : case BUILT_IN_STPCPY:
2570 162 : case BUILT_IN_STPNCPY:
2571 162 : case BUILT_IN_STRCAT:
2572 162 : case BUILT_IN_STRNCAT:
2573 162 : case BUILT_IN_STRCPY_CHK:
2574 162 : case BUILT_IN_STRNCPY_CHK:
2575 162 : case BUILT_IN_MEMCPY_CHK:
2576 162 : case BUILT_IN_MEMMOVE_CHK:
2577 162 : case BUILT_IN_MEMPCPY_CHK:
2578 162 : case BUILT_IN_STPCPY_CHK:
2579 162 : case BUILT_IN_STPNCPY_CHK:
2580 162 : case BUILT_IN_STRCAT_CHK:
2581 162 : case BUILT_IN_STRNCAT_CHK:
2582 162 : {
2583 324 : tree dest = gimple_call_arg (t, (DECL_FUNCTION_CODE (decl)
2584 : == BUILT_IN_BCOPY ? 1 : 0));
2585 324 : tree src = gimple_call_arg (t, (DECL_FUNCTION_CODE (decl)
2586 162 : == BUILT_IN_BCOPY ? 0 : 1));
2587 162 : unsigned i;
2588 162 : struct constraint_expr *rhsp, *lhsp;
2589 162 : get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
2590 162 : lhs = get_function_part_constraint (fi, fi_clobbers);
2591 486 : FOR_EACH_VEC_ELT (lhsc, i, lhsp)
2592 162 : process_constraint (new_constraint (lhs, *lhsp));
2593 162 : get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
2594 162 : lhs = get_function_part_constraint (fi, fi_uses);
2595 486 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
2596 162 : process_constraint (new_constraint (lhs, *rhsp));
2597 : return;
2598 : }
2599 : /* The following function clobbers memory pointed to by
2600 : its argument. */
2601 890 : case BUILT_IN_MEMSET:
2602 890 : case BUILT_IN_MEMSET_CHK:
2603 890 : case BUILT_IN_POSIX_MEMALIGN:
2604 890 : {
2605 890 : tree dest = gimple_call_arg (t, 0);
2606 890 : unsigned i;
2607 890 : ce_s *lhsp;
2608 890 : get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
2609 890 : lhs = get_function_part_constraint (fi, fi_clobbers);
2610 2670 : FOR_EACH_VEC_ELT (lhsc, i, lhsp)
2611 890 : process_constraint (new_constraint (lhs, *lhsp));
2612 : return;
2613 : }
2614 : /* The following functions clobber their second and third
2615 : arguments. */
2616 0 : case BUILT_IN_SINCOS:
2617 0 : case BUILT_IN_SINCOSF:
2618 0 : case BUILT_IN_SINCOSL:
2619 0 : {
2620 0 : process_ipa_clobber (fi, gimple_call_arg (t, 1));
2621 0 : process_ipa_clobber (fi, gimple_call_arg (t, 2));
2622 0 : return;
2623 : }
2624 : /* The following functions clobber their second argument. */
2625 0 : case BUILT_IN_FREXP:
2626 0 : case BUILT_IN_FREXPF:
2627 0 : case BUILT_IN_FREXPL:
2628 0 : case BUILT_IN_LGAMMA_R:
2629 0 : case BUILT_IN_LGAMMAF_R:
2630 0 : case BUILT_IN_LGAMMAL_R:
2631 0 : case BUILT_IN_GAMMA_R:
2632 0 : case BUILT_IN_GAMMAF_R:
2633 0 : case BUILT_IN_GAMMAL_R:
2634 0 : case BUILT_IN_MODF:
2635 0 : case BUILT_IN_MODFF:
2636 0 : case BUILT_IN_MODFL:
2637 0 : {
2638 0 : process_ipa_clobber (fi, gimple_call_arg (t, 1));
2639 0 : return;
2640 : }
2641 : /* The following functions clobber their third argument. */
2642 0 : case BUILT_IN_REMQUO:
2643 0 : case BUILT_IN_REMQUOF:
2644 0 : case BUILT_IN_REMQUOL:
2645 0 : {
2646 0 : process_ipa_clobber (fi, gimple_call_arg (t, 2));
2647 0 : return;
2648 : }
2649 : /* The following functions use what their first argument
2650 : points to. */
2651 60 : case BUILT_IN_STRDUP:
2652 60 : case BUILT_IN_STRNDUP:
2653 60 : case BUILT_IN_REALLOC:
2654 60 : case BUILT_IN_INDEX:
2655 60 : case BUILT_IN_STRCHR:
2656 60 : case BUILT_IN_STRRCHR:
2657 60 : case BUILT_IN_MEMCHR:
2658 60 : {
2659 60 : tree src = gimple_call_arg (t, 0);
2660 60 : get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
2661 60 : lhs = get_function_part_constraint (fi, fi_uses);
2662 60 : struct constraint_expr *rhsp;
2663 180 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
2664 60 : process_constraint (new_constraint (lhs, *rhsp));
2665 : return;
2666 : }
2667 : /* The following functions use what their first and second argument
2668 : point to. */
2669 16 : case BUILT_IN_STRSTR:
2670 16 : case BUILT_IN_STRPBRK:
2671 16 : {
2672 16 : tree src = gimple_call_arg (t, 0);
2673 16 : get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
2674 16 : lhs = get_function_part_constraint (fi, fi_uses);
2675 16 : struct constraint_expr *rhsp;
2676 48 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
2677 16 : process_constraint (new_constraint (lhs, *rhsp));
2678 16 : rhsc.truncate (0);
2679 16 : src = gimple_call_arg (t, 1);
2680 16 : get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
2681 251413 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
2682 16 : process_constraint (new_constraint (lhs, *rhsp));
2683 : return;
2684 : }
2685 : /* The following functions neither read nor clobber memory. */
2686 : case BUILT_IN_ASSUME_ALIGNED:
2687 : case BUILT_IN_FREE:
2688 : return;
2689 : /* Trampolines are of no interest to us. */
2690 : case BUILT_IN_INIT_TRAMPOLINE:
2691 : case BUILT_IN_ADJUST_TRAMPOLINE:
2692 : return;
2693 : case BUILT_IN_VA_START:
2694 : case BUILT_IN_VA_END:
2695 : return;
2696 14092 : case BUILT_IN_GOMP_PARALLEL:
2697 14092 : case BUILT_IN_GOACC_PARALLEL:
2698 14092 : {
2699 14092 : unsigned int fnpos, argpos;
2700 14092 : unsigned int implicit_use_args[2];
2701 14092 : unsigned int num_implicit_use_args = 0;
2702 14092 : switch (DECL_FUNCTION_CODE (decl))
2703 : {
2704 : case BUILT_IN_GOMP_PARALLEL:
2705 : /* __builtin_GOMP_parallel (fn, data, num_threads, flags). */
2706 : fnpos = 0;
2707 : argpos = 1;
2708 : break;
2709 14079 : case BUILT_IN_GOACC_PARALLEL:
2710 : /* __builtin_GOACC_parallel (flags_m, fn, mapnum, hostaddrs,
2711 : sizes, kinds, ...). */
2712 14079 : fnpos = 1;
2713 14079 : argpos = 3;
2714 14079 : implicit_use_args[num_implicit_use_args++] = 4;
2715 14079 : implicit_use_args[num_implicit_use_args++] = 5;
2716 14079 : break;
2717 : default:
2718 : gcc_unreachable ();
2719 : }
2720 :
2721 14092 : tree fnarg = gimple_call_arg (t, fnpos);
2722 14092 : gcc_assert (TREE_CODE (fnarg) == ADDR_EXPR);
2723 14092 : tree fndecl = TREE_OPERAND (fnarg, 0);
2724 14092 : if (fndecl_maybe_in_other_partition (fndecl))
2725 : /* Fallthru to general call handling. */
2726 : break;
2727 :
2728 14049 : varinfo_t cfi = get_vi_for_tree (fndecl);
2729 :
2730 14049 : tree arg = gimple_call_arg (t, argpos);
2731 :
2732 : /* Parameter passed by value is used. */
2733 14049 : lhs = get_function_part_constraint (fi, fi_uses);
2734 14049 : struct constraint_expr *rhsp;
2735 14049 : get_constraint_for (arg, &rhsc);
2736 42147 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
2737 14049 : process_constraint (new_constraint (lhs, *rhsp));
2738 14049 : rhsc.truncate (0);
2739 :
2740 : /* Handle parameters used by the call, but not used in cfi, as
2741 : implicitly used by cfi. */
2742 14049 : lhs = get_function_part_constraint (cfi, fi_uses);
2743 56176 : for (unsigned i = 0; i < num_implicit_use_args; ++i)
2744 : {
2745 28078 : tree arg = gimple_call_arg (t, implicit_use_args[i]);
2746 28078 : get_constraint_for (arg, &rhsc);
2747 84234 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
2748 28078 : process_constraint (new_constraint (lhs, *rhsp));
2749 28078 : rhsc.truncate (0);
2750 : }
2751 :
2752 : /* The caller clobbers what the callee does. */
2753 14049 : lhs = get_function_part_constraint (fi, fi_clobbers);
2754 14049 : rhs = get_function_part_constraint (cfi, fi_clobbers);
2755 14049 : process_constraint (new_constraint (lhs, rhs));
2756 :
2757 : /* The caller uses what the callee does. */
2758 14049 : lhs = get_function_part_constraint (fi, fi_uses);
2759 14049 : rhs = get_function_part_constraint (cfi, fi_uses);
2760 14049 : process_constraint (new_constraint (lhs, rhs));
2761 :
2762 14049 : return;
2763 : }
2764 : /* printf-style functions may have hooks to set pointers to
2765 : point to somewhere into the generated string. Leave them
2766 : for a later exercise... */
2767 : default:
2768 : /* Fallthru to general call handling. */;
2769 : }
2770 :
2771 : /* Parameters passed by value are used. */
2772 241021 : lhs = get_function_part_constraint (fi, fi_uses);
2773 1417893 : for (i = 0; i < gimple_call_num_args (t); i++)
2774 : {
2775 935851 : struct constraint_expr *rhsp;
2776 935851 : tree arg = gimple_call_arg (t, i);
2777 :
2778 1850587 : if (TREE_CODE (arg) == SSA_NAME
2779 935851 : || is_gimple_min_invariant (arg))
2780 914736 : continue;
2781 :
2782 21115 : get_constraint_for_address_of (arg, &rhsc);
2783 63346 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
2784 21116 : process_constraint (new_constraint (lhs, *rhsp));
2785 21115 : rhsc.truncate (0);
2786 : }
2787 :
2788 : /* Build constraints for propagating clobbers/uses along the
2789 : callgraph edges. */
2790 241021 : cfi = get_fi_for_callee (call_stmt);
2791 241021 : if (cfi->id == anything_id)
2792 : {
2793 356620 : if (gimple_vdef (t))
2794 125194 : make_constraint_from (first_vi_for_offset (fi, fi_clobbers),
2795 : anything_id);
2796 178310 : make_constraint_from (first_vi_for_offset (fi, fi_uses),
2797 : anything_id);
2798 178310 : return;
2799 : }
2800 :
2801 : /* For callees without function info (that's external functions),
2802 : ESCAPED is clobbered and used. */
2803 62711 : if (cfi->decl
2804 62710 : && TREE_CODE (cfi->decl) == FUNCTION_DECL
2805 62031 : && !cfi->is_fn_info)
2806 : {
2807 55940 : varinfo_t vi;
2808 :
2809 111880 : if (gimple_vdef (t))
2810 55755 : make_copy_constraint (first_vi_for_offset (fi, fi_clobbers),
2811 : escaped_id);
2812 55940 : make_copy_constraint (first_vi_for_offset (fi, fi_uses), escaped_id);
2813 :
2814 : /* Also honor the call statement use/clobber info. */
2815 55940 : if ((vi = lookup_call_clobber_vi (call_stmt)) != NULL)
2816 55654 : make_copy_constraint (first_vi_for_offset (fi, fi_clobbers),
2817 55654 : vi->id);
2818 55940 : if ((vi = lookup_call_use_vi (call_stmt)) != NULL)
2819 55654 : make_copy_constraint (first_vi_for_offset (fi, fi_uses),
2820 55654 : vi->id);
2821 : return;
2822 : }
2823 :
2824 : /* Otherwise the caller clobbers and uses what the callee does.
2825 : ??? This should use a new complex constraint that filters
2826 : local variables of the callee. */
2827 13542 : if (gimple_vdef (t))
2828 : {
2829 5757 : lhs = get_function_part_constraint (fi, fi_clobbers);
2830 5757 : rhs = get_function_part_constraint (cfi, fi_clobbers);
2831 5757 : process_constraint (new_constraint (lhs, rhs));
2832 : }
2833 6771 : lhs = get_function_part_constraint (fi, fi_uses);
2834 6771 : rhs = get_function_part_constraint (cfi, fi_uses);
2835 6771 : process_constraint (new_constraint (lhs, rhs));
2836 : }
2837 385531 : else if (gimple_code (t) == GIMPLE_ASM)
2838 : {
2839 : /* ??? Ick. We can do better. */
2840 42 : if (gimple_vdef (t))
2841 42 : make_constraint_from (first_vi_for_offset (fi, fi_clobbers),
2842 : anything_id);
2843 42 : make_constraint_from (first_vi_for_offset (fi, fi_uses),
2844 : anything_id);
2845 : }
2846 976780 : }
2847 :
2848 :
2849 : /* This structure is used during pushing fields onto the fieldstack
2850 : to track the offset of the field, since bitpos_of_field gives it
2851 : relative to its immediate containing type, and we want it relative
2852 : to the ultimate containing object. */
2853 :
2854 : struct fieldoff
2855 : {
2856 : /* Offset from the base of the base containing object to this field. */
2857 : HOST_WIDE_INT offset;
2858 :
2859 : /* Size, in bits, of the field. */
2860 : unsigned HOST_WIDE_INT size;
2861 :
2862 : unsigned has_unknown_size : 1;
2863 :
2864 : unsigned must_have_pointers : 1;
2865 :
2866 : unsigned may_have_pointers : 1;
2867 :
2868 : unsigned only_restrict_pointers : 1;
2869 :
2870 : tree restrict_pointed_type;
2871 : };
2872 : typedef struct fieldoff fieldoff_s;
2873 :
2874 :
2875 : /* qsort comparison function for two fieldoff's PA and PB. */
2876 :
2877 : static int
2878 191652126 : fieldoff_compare (const void *pa, const void *pb)
2879 : {
2880 191652126 : const fieldoff_s *foa = (const fieldoff_s *)pa;
2881 191652126 : const fieldoff_s *fob = (const fieldoff_s *)pb;
2882 191652126 : unsigned HOST_WIDE_INT foasize, fobsize;
2883 :
2884 191652126 : if (foa->offset < fob->offset)
2885 : return -1;
2886 99856832 : else if (foa->offset > fob->offset)
2887 : return 1;
2888 :
2889 1220594 : foasize = foa->size;
2890 1220594 : fobsize = fob->size;
2891 1220594 : if (foasize < fobsize)
2892 : return -1;
2893 1023010 : else if (foasize > fobsize)
2894 115682 : return 1;
2895 : return 0;
2896 : }
2897 :
2898 : /* Sort a fieldstack according to the field offset and sizes. */
2899 : static void
2900 7847175 : sort_fieldstack (vec<fieldoff_s> &fieldstack)
2901 : {
2902 7847175 : fieldstack.qsort (fieldoff_compare);
2903 7847175 : }
2904 :
2905 : /* Return true if T is a type that can have subvars. */
2906 :
2907 : static inline bool
2908 67699651 : type_can_have_subvars (const_tree t)
2909 : {
2910 : /* Aggregates without overlapping fields can have subvars. */
2911 5998678 : return TREE_CODE (t) == RECORD_TYPE;
2912 : }
2913 :
2914 : /* Return true if V is a tree that we can have subvars for.
2915 : Normally, this is any aggregate type. Also complex
2916 : types which are not gimple registers can have subvars. */
2917 :
2918 : static inline bool
2919 123776223 : var_can_have_subvars (const_tree v)
2920 : {
2921 : /* Volatile variables should never have subvars. */
2922 123776223 : if (TREE_THIS_VOLATILE (v))
2923 : return false;
2924 :
2925 : /* Non decls or memory tags can never have subvars. */
2926 123479789 : if (!DECL_P (v))
2927 : return false;
2928 :
2929 61700973 : return type_can_have_subvars (TREE_TYPE (v));
2930 : }
2931 :
2932 : /* Return true if T is a type that does contain pointers. */
2933 :
2934 : static bool
2935 34370299 : type_must_have_pointers (tree type)
2936 : {
2937 35156693 : if (POINTER_TYPE_P (type))
2938 : return true;
2939 :
2940 19696065 : if (TREE_CODE (type) == ARRAY_TYPE)
2941 786394 : return type_must_have_pointers (TREE_TYPE (type));
2942 :
2943 : /* A function or method can have pointers as arguments, so track
2944 : those separately. */
2945 18909671 : if (FUNC_OR_METHOD_TYPE_P (type))
2946 0 : return true;
2947 :
2948 : return false;
2949 : }
2950 :
2951 : static bool
2952 34370299 : field_must_have_pointers (tree t)
2953 : {
2954 34370299 : return type_must_have_pointers (TREE_TYPE (t));
2955 : }
2956 :
2957 : /* Given a TYPE, and a vector of field offsets FIELDSTACK, push all
2958 : the fields of TYPE onto fieldstack, recording their offsets along
2959 : the way.
2960 :
2961 : OFFSET is used to keep track of the offset in this entire
2962 : structure, rather than just the immediately containing structure.
2963 : Returns false if the caller is supposed to handle the field we
2964 : recursed for. */
2965 :
2966 : static bool
2967 14912966 : push_fields_onto_fieldstack (tree type, vec<fieldoff_s> *fieldstack,
2968 : unsigned HOST_WIDE_INT offset)
2969 : {
2970 14912966 : tree field;
2971 14912966 : bool empty_p = true;
2972 :
2973 14912966 : if (TREE_CODE (type) != RECORD_TYPE)
2974 : return false;
2975 :
2976 : /* If the vector of fields is growing too big, bail out early.
2977 : Callers check for vec::length <= param_max_fields_for_field_sensitive, make
2978 : sure this fails. */
2979 14912966 : if (fieldstack->length () > (unsigned)param_max_fields_for_field_sensitive)
2980 : return false;
2981 :
2982 362359702 : for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
2983 347634689 : if (TREE_CODE (field) == FIELD_DECL)
2984 : {
2985 41194498 : bool push = false;
2986 41194498 : unsigned HOST_WIDE_INT foff = bitpos_of_field (field);
2987 41194498 : tree field_type = TREE_TYPE (field);
2988 :
2989 41194498 : if (!var_can_have_subvars (field)
2990 7034718 : || TREE_CODE (field_type) == QUAL_UNION_TYPE
2991 48229216 : || TREE_CODE (field_type) == UNION_TYPE)
2992 : push = true;
2993 7034718 : else if (!push_fields_onto_fieldstack
2994 7034718 : (field_type, fieldstack, offset + foff)
2995 7034718 : && (DECL_SIZE (field)
2996 1341034 : && !integer_zerop (DECL_SIZE (field))))
2997 : /* Empty structures may have actual size, like in C++. So
2998 : see if we didn't push any subfields and the size is
2999 : nonzero, push the field onto the stack. */
3000 : push = true;
3001 :
3002 : if (push)
3003 : {
3004 34370299 : fieldoff_s *pair = NULL;
3005 34370299 : bool has_unknown_size = false;
3006 34370299 : bool must_have_pointers_p;
3007 :
3008 34370299 : if (!fieldstack->is_empty ())
3009 26805138 : pair = &fieldstack->last ();
3010 :
3011 : /* If there isn't anything at offset zero, create sth. */
3012 26805138 : if (!pair
3013 7565161 : && offset + foff != 0)
3014 : {
3015 8423 : fieldoff_s e
3016 8423 : = {0, offset + foff, false, false, true, false, NULL_TREE};
3017 8423 : pair = fieldstack->safe_push (e);
3018 : }
3019 :
3020 34370299 : if (!DECL_SIZE (field)
3021 34370299 : || !tree_fits_uhwi_p (DECL_SIZE (field)))
3022 : has_unknown_size = true;
3023 :
3024 : /* If adjacent fields do not contain pointers merge them. */
3025 34370299 : must_have_pointers_p = field_must_have_pointers (field);
3026 34370299 : if (pair
3027 34370299 : && !has_unknown_size
3028 26782543 : && !must_have_pointers_p
3029 16664162 : && !pair->must_have_pointers
3030 11787448 : && !pair->has_unknown_size
3031 11787445 : && pair->offset + pair->size == offset + foff)
3032 : {
3033 11238984 : pair->size += tree_to_uhwi (DECL_SIZE (field));
3034 : }
3035 : else
3036 : {
3037 23131315 : fieldoff_s e;
3038 23131315 : e.offset = offset + foff;
3039 23131315 : e.has_unknown_size = has_unknown_size;
3040 23131315 : if (!has_unknown_size)
3041 23100242 : e.size = tree_to_uhwi (DECL_SIZE (field));
3042 : else
3043 : e.size = -1;
3044 23131315 : e.must_have_pointers = must_have_pointers_p;
3045 23131315 : e.may_have_pointers = true;
3046 23131315 : e.only_restrict_pointers
3047 23131315 : = (!has_unknown_size
3048 23100242 : && POINTER_TYPE_P (field_type)
3049 38583485 : && TYPE_RESTRICT (field_type));
3050 23131315 : if (e.only_restrict_pointers)
3051 121757 : e.restrict_pointed_type = TREE_TYPE (field_type);
3052 23131315 : fieldstack->safe_push (e);
3053 : }
3054 : }
3055 :
3056 : empty_p = false;
3057 : }
3058 :
3059 14725013 : return !empty_p;
3060 : }
3061 :
3062 : /* Count the number of arguments DECL has, and set IS_VARARGS to true
3063 : if it is a varargs function. */
3064 :
3065 : static unsigned int
3066 23884 : count_num_arguments (tree decl, bool *is_varargs)
3067 : {
3068 23884 : unsigned int num = 0;
3069 23884 : tree t;
3070 :
3071 : /* Capture named arguments for K&R functions. They do not
3072 : have a prototype and thus no TYPE_ARG_TYPES. */
3073 49516 : for (t = DECL_ARGUMENTS (decl); t; t = DECL_CHAIN (t))
3074 25632 : ++num;
3075 :
3076 : /* Check if the function has variadic arguments. */
3077 49516 : for (t = TYPE_ARG_TYPES (TREE_TYPE (decl)); t; t = TREE_CHAIN (t))
3078 49508 : if (TREE_VALUE (t) == void_type_node)
3079 : break;
3080 23884 : if (!t)
3081 8 : *is_varargs = true;
3082 :
3083 23884 : return num;
3084 : }
3085 :
3086 : /* Creation function node for DECL, using NAME, and return the index
3087 : of the variable we've created for the function. If NONLOCAL_p, create
3088 : initial constraints. */
3089 :
3090 : static varinfo_t
3091 23884 : create_function_info_for (tree decl, const char *name, bool add_id,
3092 : bool nonlocal_p)
3093 : {
3094 23884 : struct function *fn = DECL_STRUCT_FUNCTION (decl);
3095 23884 : varinfo_t vi, prev_vi;
3096 23884 : tree arg;
3097 23884 : unsigned int i;
3098 23884 : bool is_varargs = false;
3099 23884 : unsigned int num_args = count_num_arguments (decl, &is_varargs);
3100 :
3101 : /* Create the variable info. */
3102 :
3103 23884 : vi = new_var_info (decl, name, add_id);
3104 23884 : vi->offset = 0;
3105 23884 : vi->size = 1;
3106 23884 : vi->fullsize = fi_parm_base + num_args;
3107 23884 : vi->is_fn_info = 1;
3108 23884 : vi->may_have_pointers = false;
3109 23884 : if (is_varargs)
3110 8 : vi->fullsize = ~0;
3111 23884 : insert_vi_for_tree (vi->decl, vi);
3112 :
3113 23884 : prev_vi = vi;
3114 :
3115 : /* Create a variable for things the function clobbers and one for
3116 : things the function uses. */
3117 23884 : {
3118 23884 : varinfo_t clobbervi, usevi;
3119 23884 : const char *newname;
3120 23884 : char *tempname;
3121 :
3122 23884 : tempname = xasprintf ("%s.clobber", name);
3123 23884 : newname = ggc_strdup (tempname);
3124 23884 : free (tempname);
3125 :
3126 23884 : clobbervi = new_var_info (NULL, newname, false);
3127 23884 : clobbervi->offset = fi_clobbers;
3128 23884 : clobbervi->size = 1;
3129 23884 : clobbervi->fullsize = vi->fullsize;
3130 23884 : clobbervi->is_full_var = true;
3131 23884 : clobbervi->is_global_var = false;
3132 23884 : clobbervi->is_reg_var = true;
3133 :
3134 23884 : gcc_assert (prev_vi->offset < clobbervi->offset);
3135 23884 : prev_vi->next = clobbervi->id;
3136 23884 : prev_vi = clobbervi;
3137 :
3138 23884 : tempname = xasprintf ("%s.use", name);
3139 23884 : newname = ggc_strdup (tempname);
3140 23884 : free (tempname);
3141 :
3142 23884 : usevi = new_var_info (NULL, newname, false);
3143 23884 : usevi->offset = fi_uses;
3144 23884 : usevi->size = 1;
3145 23884 : usevi->fullsize = vi->fullsize;
3146 23884 : usevi->is_full_var = true;
3147 23884 : usevi->is_global_var = false;
3148 23884 : usevi->is_reg_var = true;
3149 :
3150 23884 : gcc_assert (prev_vi->offset < usevi->offset);
3151 23884 : prev_vi->next = usevi->id;
3152 23884 : prev_vi = usevi;
3153 : }
3154 :
3155 : /* And one for the static chain. */
3156 23884 : if (fn->static_chain_decl != NULL_TREE)
3157 : {
3158 139 : varinfo_t chainvi;
3159 139 : const char *newname;
3160 139 : char *tempname;
3161 :
3162 139 : tempname = xasprintf ("%s.chain", name);
3163 139 : newname = ggc_strdup (tempname);
3164 139 : free (tempname);
3165 :
3166 139 : chainvi = new_var_info (fn->static_chain_decl, newname, false);
3167 139 : chainvi->offset = fi_static_chain;
3168 139 : chainvi->size = 1;
3169 139 : chainvi->fullsize = vi->fullsize;
3170 139 : chainvi->is_full_var = true;
3171 139 : chainvi->is_global_var = false;
3172 :
3173 139 : insert_vi_for_tree (fn->static_chain_decl, chainvi);
3174 :
3175 139 : if (nonlocal_p
3176 0 : && chainvi->may_have_pointers)
3177 0 : make_constraint_from (chainvi, nonlocal_id);
3178 :
3179 139 : gcc_assert (prev_vi->offset < chainvi->offset);
3180 139 : prev_vi->next = chainvi->id;
3181 139 : prev_vi = chainvi;
3182 : }
3183 :
3184 : /* Create a variable for the return var. */
3185 23884 : if (DECL_RESULT (decl) != NULL
3186 23884 : || !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
3187 : {
3188 23884 : varinfo_t resultvi;
3189 23884 : const char *newname;
3190 23884 : char *tempname;
3191 23884 : tree resultdecl = decl;
3192 :
3193 23884 : if (DECL_RESULT (decl))
3194 23884 : resultdecl = DECL_RESULT (decl);
3195 :
3196 23884 : tempname = xasprintf ("%s.result", name);
3197 23884 : newname = ggc_strdup (tempname);
3198 23884 : free (tempname);
3199 :
3200 23884 : resultvi = new_var_info (resultdecl, newname, false);
3201 23884 : resultvi->offset = fi_result;
3202 23884 : resultvi->size = 1;
3203 23884 : resultvi->fullsize = vi->fullsize;
3204 23884 : resultvi->is_full_var = true;
3205 23884 : if (DECL_RESULT (decl))
3206 23884 : resultvi->may_have_pointers = true;
3207 :
3208 23884 : if (DECL_RESULT (decl))
3209 23884 : insert_vi_for_tree (DECL_RESULT (decl), resultvi);
3210 :
3211 23884 : if (nonlocal_p
3212 7092 : && DECL_RESULT (decl)
3213 30976 : && DECL_BY_REFERENCE (DECL_RESULT (decl)))
3214 6 : make_constraint_from (resultvi, nonlocal_id);
3215 :
3216 23884 : gcc_assert (prev_vi->offset < resultvi->offset);
3217 23884 : prev_vi->next = resultvi->id;
3218 23884 : prev_vi = resultvi;
3219 : }
3220 :
3221 : /* We also need to make function return values escape. Nothing
3222 : escapes by returning from main though. */
3223 23884 : if (nonlocal_p
3224 23884 : && !MAIN_NAME_P (DECL_NAME (decl)))
3225 : {
3226 3504 : varinfo_t fi, rvi;
3227 3504 : fi = lookup_vi_for_tree (decl);
3228 3504 : rvi = first_vi_for_offset (fi, fi_result);
3229 3504 : if (rvi && rvi->offset == fi_result)
3230 3504 : make_copy_constraint (get_varinfo (escaped_id), rvi->id);
3231 : }
3232 :
3233 : /* Set up variables for each argument. */
3234 23884 : arg = DECL_ARGUMENTS (decl);
3235 49516 : for (i = 0; i < num_args; i++)
3236 : {
3237 25632 : varinfo_t argvi;
3238 25632 : const char *newname;
3239 25632 : char *tempname;
3240 25632 : tree argdecl = decl;
3241 :
3242 25632 : if (arg)
3243 25632 : argdecl = arg;
3244 :
3245 25632 : tempname = xasprintf ("%s.arg%d", name, i);
3246 25632 : newname = ggc_strdup (tempname);
3247 25632 : free (tempname);
3248 :
3249 25632 : argvi = new_var_info (argdecl, newname, false);
3250 25632 : argvi->offset = fi_parm_base + i;
3251 25632 : argvi->size = 1;
3252 25632 : argvi->is_full_var = true;
3253 25632 : argvi->fullsize = vi->fullsize;
3254 25632 : if (arg)
3255 25632 : argvi->may_have_pointers = true;
3256 :
3257 25632 : if (arg)
3258 25632 : insert_vi_for_tree (arg, argvi);
3259 :
3260 25632 : if (nonlocal_p
3261 9300 : && argvi->may_have_pointers)
3262 9300 : make_constraint_from (argvi, nonlocal_id);
3263 :
3264 25632 : gcc_assert (prev_vi->offset < argvi->offset);
3265 25632 : prev_vi->next = argvi->id;
3266 25632 : prev_vi = argvi;
3267 25632 : if (arg)
3268 25632 : arg = DECL_CHAIN (arg);
3269 : }
3270 :
3271 : /* Add one representative for all further args. */
3272 23884 : if (is_varargs)
3273 : {
3274 8 : varinfo_t argvi;
3275 8 : const char *newname;
3276 8 : char *tempname;
3277 8 : tree decl;
3278 :
3279 8 : tempname = xasprintf ("%s.varargs", name);
3280 8 : newname = ggc_strdup (tempname);
3281 8 : free (tempname);
3282 :
3283 : /* We need sth that can be pointed to for va_start. */
3284 8 : decl = build_fake_var_decl (ptr_type_node);
3285 :
3286 8 : argvi = new_var_info (decl, newname, false);
3287 8 : argvi->offset = fi_parm_base + num_args;
3288 8 : argvi->size = ~0;
3289 8 : argvi->is_full_var = true;
3290 8 : argvi->is_heap_var = true;
3291 8 : argvi->fullsize = vi->fullsize;
3292 :
3293 8 : if (nonlocal_p
3294 6 : && argvi->may_have_pointers)
3295 6 : make_constraint_from (argvi, nonlocal_id);
3296 :
3297 8 : gcc_assert (prev_vi->offset < argvi->offset);
3298 8 : prev_vi->next = argvi->id;
3299 : }
3300 :
3301 23884 : return vi;
3302 : }
3303 :
3304 :
3305 : /* Return true if FIELDSTACK contains fields that overlap.
3306 : FIELDSTACK is assumed to be sorted by offset. */
3307 :
3308 : static bool
3309 7847175 : check_for_overlaps (const vec<fieldoff_s> &fieldstack)
3310 : {
3311 7847175 : fieldoff_s *fo = NULL;
3312 7847175 : unsigned int i;
3313 7847175 : HOST_WIDE_INT lastoffset = -1;
3314 :
3315 30241540 : FOR_EACH_VEC_ELT (fieldstack, i, fo)
3316 : {
3317 22411685 : if (fo->offset == lastoffset)
3318 : return true;
3319 22394365 : lastoffset = fo->offset;
3320 : }
3321 : return false;
3322 : }
3323 :
3324 : /* Create a varinfo structure for NAME and DECL, and add it to VARMAP.
3325 : This will also create any varinfo structures necessary for fields
3326 : of DECL. DECL is a function parameter if HANDLE_PARAM is set.
3327 : HANDLED_STRUCT_TYPE is used to register struct types reached by following
3328 : restrict pointers. This is needed to prevent infinite recursion.
3329 : If ADD_RESTRICT, pretend that the pointer NAME is restrict even if DECL
3330 : does not advertise it. */
3331 :
3332 : static varinfo_t
3333 93909080 : create_variable_info_for_1 (tree decl, const char *name, bool add_id,
3334 : bool handle_param, bitmap handled_struct_type,
3335 : bool add_restrict = false)
3336 : {
3337 93909080 : varinfo_t vi, newvi;
3338 93909080 : tree decl_type = TREE_TYPE (decl);
3339 93909080 : tree declsize = DECL_P (decl) ? DECL_SIZE (decl) : TYPE_SIZE (decl_type);
3340 93909080 : auto_vec<fieldoff_s> fieldstack;
3341 93909080 : fieldoff_s *fo;
3342 93909080 : unsigned int i;
3343 :
3344 93909080 : if (!declsize
3345 85486544 : || !tree_fits_uhwi_p (declsize))
3346 : {
3347 8436708 : vi = new_var_info (decl, name, add_id);
3348 8436708 : vi->offset = 0;
3349 8436708 : vi->size = ~0;
3350 8436708 : vi->fullsize = ~0;
3351 8436708 : vi->is_unknown_size_var = true;
3352 8436708 : vi->is_full_var = true;
3353 8436708 : vi->may_have_pointers = true;
3354 8436708 : return vi;
3355 : }
3356 :
3357 : /* Collect field information. */
3358 85472372 : if (use_field_sensitive
3359 81355085 : && var_can_have_subvars (decl)
3360 : /* ??? Force us to not use subfields for globals in IPA mode.
3361 : Else we'd have to parse arbitrary initializers. */
3362 93371382 : && !(in_ipa_mode
3363 20299 : && is_global_var (decl)))
3364 : {
3365 7878248 : fieldoff_s *fo = NULL;
3366 7878248 : bool notokay = false;
3367 7878248 : unsigned int i;
3368 :
3369 7878248 : push_fields_onto_fieldstack (decl_type, &fieldstack, 0);
3370 :
3371 38865158 : for (i = 0; !notokay && fieldstack.iterate (i, &fo); i++)
3372 23139735 : if (fo->has_unknown_size
3373 23108662 : || fo->offset < 0)
3374 : {
3375 : notokay = true;
3376 : break;
3377 : }
3378 :
3379 : /* We can't sort them if we have a field with a variable sized type,
3380 : which will make notokay = true. In that case, we are going to return
3381 : without creating varinfos for the fields anyway, so sorting them is a
3382 : waste to boot. */
3383 7878248 : if (!notokay)
3384 : {
3385 7847175 : sort_fieldstack (fieldstack);
3386 : /* Due to some C++ FE issues, like PR 22488, we might end up
3387 : what appear to be overlapping fields even though they,
3388 : in reality, do not overlap. Until the C++ FE is fixed,
3389 : we will simply disable field-sensitivity for these cases. */
3390 7847175 : notokay = check_for_overlaps (fieldstack);
3391 : }
3392 :
3393 7847175 : if (notokay)
3394 48393 : fieldstack.release ();
3395 : }
3396 :
3397 : /* If we didn't end up collecting sub-variables create a full
3398 : variable for the decl. */
3399 85472372 : if (fieldstack.length () == 0
3400 7516768 : || fieldstack.length () > (unsigned)param_max_fields_for_field_sensitive)
3401 : {
3402 77956022 : vi = new_var_info (decl, name, add_id);
3403 77956022 : vi->offset = 0;
3404 77956022 : vi->may_have_pointers = true;
3405 77956022 : vi->fullsize = tree_to_uhwi (declsize);
3406 77956022 : vi->size = vi->fullsize;
3407 77956022 : vi->is_full_var = true;
3408 77956022 : if (POINTER_TYPE_P (decl_type)
3409 77956022 : && (TYPE_RESTRICT (decl_type) || add_restrict))
3410 875994 : vi->only_restrict_pointers = 1;
3411 77956022 : if (vi->only_restrict_pointers
3412 875994 : && !type_contains_placeholder_p (TREE_TYPE (decl_type))
3413 875994 : && handle_param
3414 78539237 : && !bitmap_bit_p (handled_struct_type,
3415 583215 : TYPE_UID (TREE_TYPE (decl_type))))
3416 : {
3417 583215 : varinfo_t rvi;
3418 583215 : tree heapvar = build_fake_var_decl (TREE_TYPE (decl_type));
3419 583215 : DECL_EXTERNAL (heapvar) = 1;
3420 583215 : if (var_can_have_subvars (heapvar))
3421 901090 : bitmap_set_bit (handled_struct_type,
3422 450545 : TYPE_UID (TREE_TYPE (decl_type)));
3423 583215 : rvi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS", true,
3424 : true, handled_struct_type);
3425 583215 : if (var_can_have_subvars (heapvar))
3426 901090 : bitmap_clear_bit (handled_struct_type,
3427 450545 : TYPE_UID (TREE_TYPE (decl_type)));
3428 583215 : rvi->is_restrict_var = 1;
3429 583215 : insert_vi_for_tree (heapvar, rvi);
3430 583215 : make_constraint_from (vi, rvi->id);
3431 583215 : make_param_constraints (rvi);
3432 : }
3433 77956022 : fieldstack.release ();
3434 77956022 : return vi;
3435 : }
3436 :
3437 7516350 : vi = new_var_info (decl, name, add_id);
3438 7516350 : vi->fullsize = tree_to_uhwi (declsize);
3439 7516350 : if (fieldstack.length () == 1)
3440 1638159 : vi->is_full_var = true;
3441 7516350 : for (i = 0, newvi = vi;
3442 123733779 : fieldstack.iterate (i, &fo);
3443 22308349 : ++i, newvi = vi_next (newvi))
3444 : {
3445 22308349 : const char *newname = NULL;
3446 22308349 : char *tempname;
3447 :
3448 22308349 : if (dump_file)
3449 : {
3450 334 : if (fieldstack.length () != 1)
3451 : {
3452 304 : tempname
3453 304 : = xasprintf ("%s." HOST_WIDE_INT_PRINT_DEC
3454 : "+" HOST_WIDE_INT_PRINT_DEC, name,
3455 : fo->offset, fo->size);
3456 304 : newname = ggc_strdup (tempname);
3457 304 : free (tempname);
3458 : }
3459 : }
3460 : else
3461 : newname = "NULL";
3462 :
3463 304 : if (newname)
3464 22308319 : newvi->name = newname;
3465 22308349 : newvi->offset = fo->offset;
3466 22308349 : newvi->size = fo->size;
3467 22308349 : newvi->fullsize = vi->fullsize;
3468 22308349 : newvi->may_have_pointers = fo->may_have_pointers;
3469 22308349 : newvi->only_restrict_pointers = fo->only_restrict_pointers;
3470 22308349 : if (handle_param
3471 1698668 : && newvi->only_restrict_pointers
3472 30108 : && !type_contains_placeholder_p (fo->restrict_pointed_type)
3473 22338457 : && !bitmap_bit_p (handled_struct_type,
3474 30108 : TYPE_UID (fo->restrict_pointed_type)))
3475 : {
3476 30105 : varinfo_t rvi;
3477 30105 : tree heapvar = build_fake_var_decl (fo->restrict_pointed_type);
3478 30105 : DECL_EXTERNAL (heapvar) = 1;
3479 30105 : if (var_can_have_subvars (heapvar))
3480 82 : bitmap_set_bit (handled_struct_type,
3481 41 : TYPE_UID (fo->restrict_pointed_type));
3482 30105 : rvi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS", true,
3483 : true, handled_struct_type);
3484 30105 : if (var_can_have_subvars (heapvar))
3485 82 : bitmap_clear_bit (handled_struct_type,
3486 41 : TYPE_UID (fo->restrict_pointed_type));
3487 30105 : rvi->is_restrict_var = 1;
3488 30105 : insert_vi_for_tree (heapvar, rvi);
3489 30105 : make_constraint_from (newvi, rvi->id);
3490 30105 : make_param_constraints (rvi);
3491 : }
3492 37100348 : if (i + 1 < fieldstack.length ())
3493 : {
3494 14791999 : varinfo_t tem = new_var_info (decl, name, false);
3495 14791999 : newvi->next = tem->id;
3496 14791999 : tem->head = vi->id;
3497 : }
3498 : }
3499 :
3500 : return vi;
3501 93909080 : }
3502 :
3503 : static unsigned int
3504 83690462 : create_variable_info_for (tree decl, const char *name, bool add_id)
3505 : {
3506 : /* First see if we are dealing with an ifunc resolver call and
3507 : associate that with a call to the resolver function result. */
3508 83690462 : cgraph_node *node;
3509 83690462 : if (in_ipa_mode
3510 705433 : && TREE_CODE (decl) == FUNCTION_DECL
3511 18342 : && (node = cgraph_node::get (decl))
3512 83708803 : && node->ifunc_resolver)
3513 : {
3514 1 : varinfo_t fi = get_vi_for_tree (node->get_alias_target ()->decl);
3515 1 : constraint_expr rhs
3516 1 : = get_function_part_constraint (fi, fi_result);
3517 1 : fi = new_var_info (NULL_TREE, "ifuncres", true);
3518 1 : fi->is_reg_var = true;
3519 1 : constraint_expr lhs;
3520 1 : lhs.type = SCALAR;
3521 1 : lhs.var = fi->id;
3522 1 : lhs.offset = 0;
3523 1 : process_constraint (new_constraint (lhs, rhs));
3524 1 : insert_vi_for_tree (decl, fi);
3525 1 : return fi->id;
3526 : }
3527 :
3528 83690461 : varinfo_t vi = create_variable_info_for_1 (decl, name, add_id, false, NULL);
3529 83690461 : unsigned int id = vi->id;
3530 :
3531 83690461 : insert_vi_for_tree (decl, vi);
3532 :
3533 83690461 : if (!VAR_P (decl))
3534 : return id;
3535 :
3536 : /* Create initial constraints for globals. */
3537 33644089 : for (; vi; vi = vi_next (vi))
3538 : {
3539 23644476 : if (!vi->may_have_pointers
3540 23644476 : || !vi->is_global_var)
3541 15479334 : continue;
3542 :
3543 : /* Mark global restrict qualified pointers. */
3544 15971437 : if ((POINTER_TYPE_P (TREE_TYPE (decl))
3545 359002 : && TYPE_RESTRICT (TREE_TYPE (decl)))
3546 16322846 : || vi->only_restrict_pointers)
3547 : {
3548 13186 : varinfo_t rvi
3549 13186 : = make_constraint_from_global_restrict (vi, "GLOBAL_RESTRICT",
3550 : true);
3551 : /* ??? For now exclude reads from globals as restrict sources
3552 : if those are not (indirectly) from incoming parameters. */
3553 13186 : rvi->is_restrict_var = false;
3554 13186 : continue;
3555 13186 : }
3556 :
3557 : /* In non-IPA mode the initializer from nonlocal is all we need. */
3558 8151956 : if (!in_ipa_mode
3559 8188966 : || DECL_HARD_REGISTER (decl))
3560 8114946 : make_copy_constraint (vi, nonlocal_id);
3561 :
3562 : /* In IPA mode parse the initializer and generate proper constraints
3563 : for it. */
3564 : else
3565 : {
3566 37010 : varpool_node *vnode = varpool_node::get (decl);
3567 :
3568 : /* For escaped variables initialize them from nonlocal. */
3569 37010 : if (!vnode || !vnode->all_refs_explicit_p ())
3570 1454 : make_copy_constraint (vi, nonlocal_id);
3571 :
3572 : /* While we can in theory walk references for the varpool
3573 : node that does not cover zero-initialization or references
3574 : to the constant pool. */
3575 37010 : if (DECL_INITIAL (decl))
3576 : {
3577 35912 : auto_vec<ce_s> rhsc;
3578 35912 : struct constraint_expr lhs, *rhsp;
3579 35912 : unsigned i;
3580 35912 : lhs.var = vi->id;
3581 35912 : lhs.offset = 0;
3582 35912 : lhs.type = SCALAR;
3583 35912 : get_constraint_for (DECL_INITIAL (decl), &rhsc);
3584 184573 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
3585 112749 : process_constraint (new_constraint (lhs, *rhsp));
3586 : /* If this is a variable that escapes from the unit
3587 : the initializer escapes as well. */
3588 35912 : if (!vnode || !vnode->all_refs_explicit_p ())
3589 : {
3590 2159 : lhs.var = escaped_id;
3591 2159 : lhs.offset = 0;
3592 2159 : lhs.type = SCALAR;
3593 38071 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
3594 1550 : process_constraint (new_constraint (lhs, *rhsp));
3595 : }
3596 35912 : }
3597 : }
3598 : }
3599 :
3600 : return id;
3601 : }
3602 :
3603 : /* Register the constraints for function parameter related VI. */
3604 :
3605 : static void
3606 10218619 : make_param_constraints (varinfo_t vi)
3607 : {
3608 11607441 : for (; vi; vi = vi_next (vi))
3609 : {
3610 11121949 : if (vi->only_restrict_pointers)
3611 : ;
3612 10508626 : else if (vi->may_have_pointers)
3613 10508626 : make_constraint_from (vi, nonlocal_id);
3614 :
3615 11121949 : if (vi->is_full_var)
3616 : break;
3617 : }
3618 10218619 : }
3619 :
3620 : /* Create varinfo structures for parameters, return value and the static
3621 : chain of FN. Intended for intraprocedural mode. */
3622 :
3623 : static void
3624 4577412 : intra_create_variable_infos (struct function *fn)
3625 : {
3626 4577412 : tree t;
3627 4577412 : bitmap handled_struct_type = NULL;
3628 4577412 : bool this_parm_in_ctor = DECL_CXX_CONSTRUCTOR_P (fn->decl);
3629 :
3630 : /* For each incoming pointer argument arg, create the constraint ARG
3631 : = NONLOCAL or a dummy variable if it is a restrict qualified
3632 : passed-by-reference argument. */
3633 14182711 : for (t = DECL_ARGUMENTS (fn->decl); t; t = DECL_CHAIN (t))
3634 : {
3635 9605299 : if (handled_struct_type == NULL)
3636 3864573 : handled_struct_type = BITMAP_ALLOC (NULL);
3637 :
3638 9605299 : varinfo_t p
3639 9605299 : = create_variable_info_for_1 (t, alias_get_name (t), false, true,
3640 : handled_struct_type, this_parm_in_ctor);
3641 9605299 : insert_vi_for_tree (t, p);
3642 :
3643 9605299 : make_param_constraints (p);
3644 :
3645 9605299 : this_parm_in_ctor = false;
3646 : }
3647 :
3648 4577412 : if (handled_struct_type != NULL)
3649 3864573 : BITMAP_FREE (handled_struct_type);
3650 :
3651 : /* Add a constraint for a result decl that is passed by reference. */
3652 4577412 : if (DECL_RESULT (fn->decl)
3653 4577412 : && DECL_BY_REFERENCE (DECL_RESULT (fn->decl)))
3654 : {
3655 58103 : varinfo_t p, result_vi = get_vi_for_tree (DECL_RESULT (fn->decl));
3656 :
3657 174309 : for (p = result_vi; p; p = vi_next (p))
3658 58103 : make_constraint_from (p, nonlocal_id);
3659 : }
3660 :
3661 : /* Add a constraint for the incoming static chain parameter. */
3662 4577412 : if (fn->static_chain_decl != NULL_TREE)
3663 : {
3664 47448 : varinfo_t p, chain_vi = get_vi_for_tree (fn->static_chain_decl);
3665 :
3666 142344 : for (p = chain_vi; p; p = vi_next (p))
3667 47448 : make_constraint_from (p, nonlocal_id);
3668 : }
3669 4577412 : }
3670 :
3671 : /* Initialize the always-existing constraint variables for NULL
3672 : ANYTHING, READONLY, and INTEGER. */
3673 :
3674 : static void
3675 4581907 : init_base_vars (void)
3676 : {
3677 4581907 : struct constraint_expr lhs, rhs;
3678 4581907 : varinfo_t var_anything;
3679 4581907 : varinfo_t var_nothing;
3680 4581907 : varinfo_t var_string;
3681 4581907 : varinfo_t var_escaped;
3682 4581907 : varinfo_t var_nonlocal;
3683 4581907 : varinfo_t var_escaped_return;
3684 4581907 : varinfo_t var_storedanything;
3685 4581907 : varinfo_t var_integer;
3686 :
3687 : /* Variable ID zero is reserved and should be NULL. */
3688 4581907 : varmap.safe_push (NULL);
3689 :
3690 : /* Create the NULL variable, used to represent that a variable points
3691 : to NULL. */
3692 4581907 : var_nothing = new_var_info (NULL_TREE, "NULL", false);
3693 4581907 : gcc_assert (var_nothing->id == nothing_id);
3694 4581907 : var_nothing->is_artificial_var = 1;
3695 4581907 : var_nothing->offset = 0;
3696 4581907 : var_nothing->size = ~0;
3697 4581907 : var_nothing->fullsize = ~0;
3698 4581907 : var_nothing->is_special_var = 1;
3699 4581907 : var_nothing->may_have_pointers = 0;
3700 4581907 : var_nothing->is_global_var = 0;
3701 :
3702 : /* Create the ANYTHING variable, used to represent that a variable
3703 : points to some unknown piece of memory. */
3704 4581907 : var_anything = new_var_info (NULL_TREE, "ANYTHING", false);
3705 4581907 : gcc_assert (var_anything->id == anything_id);
3706 4581907 : var_anything->is_artificial_var = 1;
3707 4581907 : var_anything->size = ~0;
3708 4581907 : var_anything->offset = 0;
3709 4581907 : var_anything->fullsize = ~0;
3710 4581907 : var_anything->is_special_var = 1;
3711 :
3712 : /* Anything points to anything. This makes deref constraints just
3713 : work in the presence of linked list and other p = *p type loops,
3714 : by saying that *ANYTHING = ANYTHING. */
3715 4581907 : lhs.type = SCALAR;
3716 4581907 : lhs.var = anything_id;
3717 4581907 : lhs.offset = 0;
3718 4581907 : rhs.type = ADDRESSOF;
3719 4581907 : rhs.var = anything_id;
3720 4581907 : rhs.offset = 0;
3721 :
3722 : /* This specifically does not use process_constraint because
3723 : process_constraint ignores all anything = anything constraints, since all
3724 : but this one are redundant. */
3725 4581907 : constraints.safe_push (new_constraint (lhs, rhs));
3726 :
3727 : /* Create the STRING variable, used to represent that a variable
3728 : points to a string literal. String literals don't contain
3729 : pointers so STRING doesn't point to anything. */
3730 4581907 : var_string = new_var_info (NULL_TREE, "STRING", false);
3731 4581907 : gcc_assert (var_string->id == string_id);
3732 4581907 : var_string->is_artificial_var = 1;
3733 4581907 : var_string->offset = 0;
3734 4581907 : var_string->size = ~0;
3735 4581907 : var_string->fullsize = ~0;
3736 4581907 : var_string->is_special_var = 1;
3737 4581907 : var_string->may_have_pointers = 0;
3738 :
3739 : /* Create the ESCAPED variable, used to represent the set of escaped
3740 : memory. */
3741 4581907 : var_escaped = new_var_info (NULL_TREE, "ESCAPED", false);
3742 4581907 : gcc_assert (var_escaped->id == escaped_id);
3743 4581907 : var_escaped->is_artificial_var = 1;
3744 4581907 : var_escaped->offset = 0;
3745 4581907 : var_escaped->size = ~0;
3746 4581907 : var_escaped->fullsize = ~0;
3747 4581907 : var_escaped->is_special_var = 0;
3748 :
3749 : /* Create the NONLOCAL variable, used to represent the set of nonlocal
3750 : memory. */
3751 4581907 : var_nonlocal = new_var_info (NULL_TREE, "NONLOCAL", false);
3752 4581907 : gcc_assert (var_nonlocal->id == nonlocal_id);
3753 4581907 : var_nonlocal->is_artificial_var = 1;
3754 4581907 : var_nonlocal->offset = 0;
3755 4581907 : var_nonlocal->size = ~0;
3756 4581907 : var_nonlocal->fullsize = ~0;
3757 4581907 : var_nonlocal->is_special_var = 1;
3758 :
3759 : /* Create the ESCAPED_RETURN variable, used to represent the set of escaped
3760 : memory via a regular return stmt. */
3761 4581907 : var_escaped_return = new_var_info (NULL_TREE, "ESCAPED_RETURN", false);
3762 4581907 : gcc_assert (var_escaped_return->id == escaped_return_id);
3763 4581907 : var_escaped_return->is_artificial_var = 1;
3764 4581907 : var_escaped_return->offset = 0;
3765 4581907 : var_escaped_return->size = ~0;
3766 4581907 : var_escaped_return->fullsize = ~0;
3767 4581907 : var_escaped_return->is_special_var = 0;
3768 :
3769 : /* ESCAPED = *ESCAPED, because escaped is may-deref'd at calls, etc. */
3770 4581907 : lhs.type = SCALAR;
3771 4581907 : lhs.var = escaped_id;
3772 4581907 : lhs.offset = 0;
3773 4581907 : rhs.type = DEREF;
3774 4581907 : rhs.var = escaped_id;
3775 4581907 : rhs.offset = 0;
3776 4581907 : process_constraint (new_constraint (lhs, rhs));
3777 :
3778 : /* ESCAPED = ESCAPED + UNKNOWN_OFFSET, because if a sub-field escapes the
3779 : whole variable escapes. */
3780 4581907 : lhs.type = SCALAR;
3781 4581907 : lhs.var = escaped_id;
3782 4581907 : lhs.offset = 0;
3783 4581907 : rhs.type = SCALAR;
3784 4581907 : rhs.var = escaped_id;
3785 4581907 : rhs.offset = UNKNOWN_OFFSET;
3786 4581907 : process_constraint (new_constraint (lhs, rhs));
3787 :
3788 : /* *ESCAPED = NONLOCAL. This is true because we have to assume
3789 : everything pointed to by escaped points to what global memory can
3790 : point to. */
3791 4581907 : lhs.type = DEREF;
3792 4581907 : lhs.var = escaped_id;
3793 4581907 : lhs.offset = 0;
3794 4581907 : rhs.type = SCALAR;
3795 4581907 : rhs.var = nonlocal_id;
3796 4581907 : rhs.offset = 0;
3797 4581907 : process_constraint (new_constraint (lhs, rhs));
3798 :
3799 : /* NONLOCAL = &NONLOCAL, NONLOCAL = &ESCAPED. This is true because
3800 : global memory may point to global memory and escaped memory. */
3801 4581907 : lhs.type = SCALAR;
3802 4581907 : lhs.var = nonlocal_id;
3803 4581907 : lhs.offset = 0;
3804 4581907 : rhs.type = ADDRESSOF;
3805 4581907 : rhs.var = nonlocal_id;
3806 4581907 : rhs.offset = 0;
3807 4581907 : process_constraint (new_constraint (lhs, rhs));
3808 4581907 : rhs.type = ADDRESSOF;
3809 4581907 : rhs.var = escaped_id;
3810 4581907 : rhs.offset = 0;
3811 4581907 : process_constraint (new_constraint (lhs, rhs));
3812 :
3813 : /* Transitively close ESCAPED_RETURN.
3814 : ESCAPED_RETURN = ESCAPED_RETURN + UNKNOWN_OFFSET
3815 : ESCAPED_RETURN = *ESCAPED_RETURN. */
3816 4581907 : lhs.type = SCALAR;
3817 4581907 : lhs.var = escaped_return_id;
3818 4581907 : lhs.offset = 0;
3819 4581907 : rhs.type = SCALAR;
3820 4581907 : rhs.var = escaped_return_id;
3821 4581907 : rhs.offset = UNKNOWN_OFFSET;
3822 4581907 : process_constraint (new_constraint (lhs, rhs));
3823 4581907 : lhs.type = SCALAR;
3824 4581907 : lhs.var = escaped_return_id;
3825 4581907 : lhs.offset = 0;
3826 4581907 : rhs.type = DEREF;
3827 4581907 : rhs.var = escaped_return_id;
3828 4581907 : rhs.offset = 0;
3829 4581907 : process_constraint (new_constraint (lhs, rhs));
3830 :
3831 : /* Create the STOREDANYTHING variable, used to represent the set of
3832 : variables stored to *ANYTHING. */
3833 4581907 : var_storedanything = new_var_info (NULL_TREE, "STOREDANYTHING", false);
3834 4581907 : gcc_assert (var_storedanything->id == storedanything_id);
3835 4581907 : var_storedanything->is_artificial_var = 1;
3836 4581907 : var_storedanything->offset = 0;
3837 4581907 : var_storedanything->size = ~0;
3838 4581907 : var_storedanything->fullsize = ~0;
3839 4581907 : var_storedanything->is_special_var = 0;
3840 :
3841 : /* Create the INTEGER variable, used to represent that a variable points
3842 : to what an INTEGER "points to". */
3843 4581907 : var_integer = new_var_info (NULL_TREE, "INTEGER", false);
3844 4581907 : gcc_assert (var_integer->id == integer_id);
3845 4581907 : var_integer->is_artificial_var = 1;
3846 4581907 : var_integer->size = ~0;
3847 4581907 : var_integer->fullsize = ~0;
3848 4581907 : var_integer->offset = 0;
3849 4581907 : var_integer->is_special_var = 1;
3850 :
3851 : /* INTEGER = ANYTHING, because we don't know where a dereference of
3852 : a random integer will point to. */
3853 4581907 : lhs.type = SCALAR;
3854 4581907 : lhs.var = integer_id;
3855 4581907 : lhs.offset = 0;
3856 4581907 : rhs.type = ADDRESSOF;
3857 4581907 : rhs.var = anything_id;
3858 4581907 : rhs.offset = 0;
3859 4581907 : process_constraint (new_constraint (lhs, rhs));
3860 4581907 : }
3861 :
3862 : /* Associate node with varinfo DATA. Worker for
3863 : cgraph_for_symbol_thunks_and_aliases. */
3864 : static bool
3865 23940 : associate_varinfo_to_alias (struct cgraph_node *node, void *data)
3866 : {
3867 23940 : if ((node->alias
3868 23887 : || (node->thunk
3869 3 : && ! node->inlined_to))
3870 53 : && node->analyzed
3871 53 : && !node->ifunc_resolver)
3872 52 : insert_vi_for_tree (node->decl, (varinfo_t)data);
3873 23940 : return false;
3874 : }
3875 :
3876 : /* Compute whether node is referred to non-locally. Worker for
3877 : cgraph_for_symbol_thunks_and_aliases. */
3878 : static bool
3879 23940 : refered_from_nonlocal_fn (struct cgraph_node *node, void *data)
3880 : {
3881 23940 : bool *nonlocal_p = (bool *)data;
3882 47880 : *nonlocal_p |= (node->used_from_other_partition
3883 23894 : || DECL_EXTERNAL (node->decl)
3884 23889 : || TREE_PUBLIC (node->decl)
3885 16807 : || node->force_output
3886 16797 : || node->ref_by_asm
3887 40737 : || lookup_attribute ("noipa", DECL_ATTRIBUTES (node->decl)));
3888 23940 : return false;
3889 : }
3890 :
3891 : /* Same for varpool nodes. */
3892 : static bool
3893 37213 : refered_from_nonlocal_var (struct varpool_node *node, void *data)
3894 : {
3895 37213 : bool *nonlocal_p = (bool *)data;
3896 74426 : *nonlocal_p |= (node->used_from_other_partition
3897 37112 : || DECL_EXTERNAL (node->decl)
3898 36628 : || TREE_PUBLIC (node->decl)
3899 35576 : || node->ref_by_asm
3900 72789 : || node->force_output);
3901 37213 : return false;
3902 : }
3903 :
3904 : /* Create function infos. */
3905 :
3906 : static void
3907 4495 : ipa_create_function_infos (void)
3908 : {
3909 4495 : struct cgraph_node *node;
3910 4495 : unsigned int constr_count = constraints.length ();
3911 :
3912 29622 : FOR_EACH_DEFINED_FUNCTION (node)
3913 : {
3914 25127 : varinfo_t vi;
3915 : /* Nodes without a body in this partition are not interesting.
3916 : Especially do not visit clones at this point for now - we
3917 : get duplicate decls there for inline clones at least. */
3918 26370 : if (!node->has_gimple_body_p ()
3919 25026 : || node->in_other_partition
3920 50153 : || node->inlined_to)
3921 1243 : continue;
3922 23884 : node->get_body ();
3923 :
3924 23884 : gcc_assert (!node->clone_of);
3925 :
3926 : /* For externally visible or attribute used annotated functions use
3927 : local constraints for their arguments.
3928 : For local functions we see all callers and thus do not need initial
3929 : constraints for parameters. */
3930 23884 : bool nonlocal_p = (node->used_from_other_partition
3931 23838 : || DECL_EXTERNAL (node->decl)
3932 23834 : || TREE_PUBLIC (node->decl)
3933 16803 : || node->force_output
3934 40677 : || lookup_attribute ("noipa",
3935 16793 : DECL_ATTRIBUTES (node->decl)));
3936 23884 : node->call_for_symbol_thunks_and_aliases (refered_from_nonlocal_fn,
3937 : &nonlocal_p, true);
3938 :
3939 23884 : vi = create_function_info_for (node->decl,
3940 : alias_get_name (node->decl), false,
3941 : nonlocal_p);
3942 57 : if (dump_file && (dump_flags & TDF_DETAILS)
3943 23939 : && constr_count != constraints.length ())
3944 : {
3945 22 : fprintf (dump_file,
3946 : "Generating initial constraints for %s",
3947 : node->dump_name ());
3948 22 : if (DECL_ASSEMBLER_NAME_SET_P (node->decl))
3949 44 : fprintf (dump_file, " (%s)",
3950 22 : IDENTIFIER_POINTER
3951 : (DECL_ASSEMBLER_NAME (node->decl)));
3952 22 : fprintf (dump_file, "\n\n");
3953 22 : dump_constraints (dump_file, constr_count);
3954 22 : fprintf (dump_file, "\n");
3955 :
3956 22 : constr_count = constraints.length ();
3957 : }
3958 :
3959 23884 : node->call_for_symbol_thunks_and_aliases
3960 23884 : (associate_varinfo_to_alias, vi, true);
3961 : }
3962 4495 : }
3963 :
3964 : /* Create constraints for global variables and their initializers. */
3965 :
3966 : static void
3967 4495 : ipa_create_global_variable_infos (void)
3968 : {
3969 4495 : varpool_node *var;
3970 4495 : unsigned int constr_count = constraints.length ();
3971 :
3972 41708 : FOR_EACH_VARIABLE (var)
3973 : {
3974 37213 : if (var->alias && var->analyzed)
3975 17 : continue;
3976 :
3977 37196 : varinfo_t vi = get_vi_for_tree (var->decl);
3978 :
3979 : /* For the purpose of IPA PTA unit-local globals are not
3980 : escape points. */
3981 37196 : bool nonlocal_p = (DECL_EXTERNAL (var->decl)
3982 36712 : || TREE_PUBLIC (var->decl)
3983 35560 : || var->used_from_other_partition
3984 35560 : || var->force_output
3985 72752 : || var->ref_by_asm);
3986 37196 : var->call_for_symbol_and_aliases (refered_from_nonlocal_var,
3987 : &nonlocal_p, true);
3988 37196 : if (nonlocal_p)
3989 1641 : vi->is_ipa_escape_point = true;
3990 : }
3991 :
3992 20 : if (dump_file && (dump_flags & TDF_DETAILS)
3993 4513 : && constr_count != constraints.length ())
3994 : {
3995 11 : fprintf (dump_file,
3996 : "Generating constraints for global initializers\n\n");
3997 11 : dump_constraints (dump_file, constr_count);
3998 11 : fprintf (dump_file, "\n");
3999 11 : constr_count = constraints.length ();
4000 : }
4001 4495 : }
4002 :
4003 :
4004 : namespace pointer_analysis {
4005 :
4006 : /* Find the variable info for tree T in VI_FOR_TREE. If T does not
4007 : exist in the map, return NULL, otherwise, return the varinfo we found. */
4008 :
4009 : varinfo_t
4010 53204931 : lookup_vi_for_tree (tree t)
4011 : {
4012 53204931 : varinfo_t *slot = vi_for_tree->get (t);
4013 53204931 : if (slot == NULL)
4014 : return NULL;
4015 :
4016 51119671 : return *slot;
4017 : }
4018 :
4019 : /* Lookup the variable for the call statement CALL representing
4020 : the uses. Returns NULL if there is nothing special about this call. */
4021 :
4022 : varinfo_t
4023 31362827 : lookup_call_use_vi (gcall *call)
4024 : {
4025 31362827 : varinfo_t *slot_p = call_stmt_vars->get (call);
4026 31362827 : if (slot_p)
4027 29408486 : return *slot_p;
4028 :
4029 : return NULL;
4030 : }
4031 :
4032 : /* Lookup the variable for the call statement CALL representing
4033 : the clobbers. Returns NULL if there is nothing special about this call. */
4034 :
4035 : varinfo_t
4036 15043484 : lookup_call_clobber_vi (gcall *call)
4037 : {
4038 15043484 : varinfo_t uses = lookup_call_use_vi (call);
4039 15043484 : if (!uses)
4040 : return NULL;
4041 :
4042 14075932 : return vi_next (uses);
4043 : }
4044 :
4045 : /* Return the varinfo for the callee of CALL. */
4046 :
4047 : varinfo_t
4048 17177081 : get_fi_for_callee (gcall *call)
4049 : {
4050 17177081 : tree decl, fn = gimple_call_fn (call);
4051 :
4052 17177081 : if (fn && TREE_CODE (fn) == OBJ_TYPE_REF)
4053 137795 : fn = OBJ_TYPE_REF_EXPR (fn);
4054 :
4055 : /* If we can directly resolve the function being called, do so.
4056 : Otherwise, it must be some sort of indirect expression that
4057 : we should still be able to handle. */
4058 17177081 : decl = gimple_call_addr_fndecl (fn);
4059 17177081 : if (decl)
4060 15752709 : return get_vi_for_tree (decl);
4061 :
4062 : /* If the function is anything other than a SSA name pointer we have no
4063 : clue and should be getting ANYFN (well, ANYTHING for now). */
4064 1424372 : if (!fn || TREE_CODE (fn) != SSA_NAME)
4065 947439 : return get_varinfo (anything_id);
4066 :
4067 476933 : if (SSA_NAME_IS_DEFAULT_DEF (fn)
4068 476933 : && (TREE_CODE (SSA_NAME_VAR (fn)) == PARM_DECL
4069 15 : || TREE_CODE (SSA_NAME_VAR (fn)) == RESULT_DECL))
4070 13334 : fn = SSA_NAME_VAR (fn);
4071 :
4072 476933 : return get_vi_for_tree (fn);
4073 : }
4074 :
4075 : /* Initialize constraint builder. */
4076 :
4077 : void
4078 4581907 : init_constraint_builder (void)
4079 : {
4080 4581907 : vi_for_tree = new hash_map<tree, varinfo_t>;
4081 4581907 : call_stmt_vars = new hash_map<gimple *, varinfo_t>;
4082 4581907 : gcc_obstack_init (&fake_var_decl_obstack);
4083 :
4084 4581907 : init_base_vars ();
4085 4581907 : }
4086 :
4087 : /* Deallocate constraint builder globals. */
4088 :
4089 : void
4090 4581907 : delete_constraint_builder (void)
4091 : {
4092 9163814 : delete vi_for_tree;
4093 9163814 : delete call_stmt_vars;
4094 4581907 : constraint_pool.release ();
4095 4581907 : obstack_free (&fake_var_decl_obstack, NULL);
4096 4581907 : }
4097 :
4098 : /* Build constraints for intraprocedural mode. */
4099 :
4100 : void
4101 4577412 : intra_build_constraints (void)
4102 : {
4103 4577412 : basic_block bb;
4104 :
4105 4577412 : intra_create_variable_infos (cfun);
4106 :
4107 : /* Now walk all statements and build the constraint set. */
4108 40596384 : FOR_EACH_BB_FN (bb, cfun)
4109 : {
4110 47871952 : for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
4111 11852980 : gsi_next (&gsi))
4112 : {
4113 11852980 : gphi *phi = gsi.phi ();
4114 :
4115 23705960 : if (! virtual_operand_p (gimple_phi_result (phi)))
4116 6224002 : find_func_aliases (cfun, phi);
4117 : }
4118 :
4119 340389122 : for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
4120 268351178 : gsi_next (&gsi))
4121 : {
4122 268351178 : gimple *stmt = gsi_stmt (gsi);
4123 :
4124 268351178 : find_func_aliases (cfun, stmt);
4125 : }
4126 : }
4127 :
4128 4577412 : if (dump_file && (dump_flags & TDF_DETAILS))
4129 : {
4130 283 : fprintf (dump_file, "Points-to analysis\n\nConstraints:\n\n");
4131 283 : dump_constraints (dump_file, 0);
4132 : }
4133 4577412 : }
4134 :
4135 : /* Build constraints for ipa mode. */
4136 :
4137 : void
4138 4495 : ipa_build_constraints (void)
4139 : {
4140 4495 : struct cgraph_node *node;
4141 :
4142 4495 : ipa_create_function_infos ();
4143 4495 : ipa_create_global_variable_infos ();
4144 :
4145 4495 : unsigned int constr_count = constraints.length ();
4146 :
4147 28432 : FOR_EACH_DEFINED_FUNCTION (node)
4148 : {
4149 23937 : struct function *func;
4150 23937 : basic_block bb;
4151 :
4152 : /* Nodes without a body in this partition are not interesting. */
4153 23990 : if (!node->has_gimple_body_p ()
4154 23884 : || node->in_other_partition
4155 47821 : || node->clone_of)
4156 53 : continue;
4157 :
4158 23884 : if (dump_file && (dump_flags & TDF_DETAILS))
4159 : {
4160 55 : fprintf (dump_file,
4161 : "Generating constraints for %s", node->dump_name ());
4162 55 : if (DECL_ASSEMBLER_NAME_SET_P (node->decl))
4163 110 : fprintf (dump_file, " (%s)",
4164 55 : IDENTIFIER_POINTER
4165 : (DECL_ASSEMBLER_NAME (node->decl)));
4166 55 : fprintf (dump_file, "\n");
4167 : }
4168 :
4169 23884 : func = DECL_STRUCT_FUNCTION (node->decl);
4170 23884 : gcc_assert (cfun == NULL);
4171 :
4172 : /* Build constraints for the function body. */
4173 363678 : FOR_EACH_BB_FN (bb, func)
4174 : {
4175 448917 : for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
4176 109123 : gsi_next (&gsi))
4177 : {
4178 109123 : gphi *phi = gsi.phi ();
4179 :
4180 218246 : if (! virtual_operand_p (gimple_phi_result (phi)))
4181 64582 : find_func_aliases (func, phi);
4182 : }
4183 :
4184 1656368 : for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
4185 976780 : gsi_next (&gsi))
4186 : {
4187 976780 : gimple *stmt = gsi_stmt (gsi);
4188 :
4189 976780 : find_func_aliases (func, stmt);
4190 976780 : find_func_clobbers (func, stmt);
4191 : }
4192 : }
4193 :
4194 23884 : if (dump_file && (dump_flags & TDF_DETAILS))
4195 : {
4196 55 : fprintf (dump_file, "\n");
4197 55 : dump_constraints (dump_file, constr_count);
4198 55 : fprintf (dump_file, "\n");
4199 23992 : constr_count = constraints.length ();
4200 : }
4201 : }
4202 4495 : }
4203 :
4204 : } // namespace pointer_analysis
|