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 67025414 : get_call_vi (gcall *call)
71 : {
72 67025414 : varinfo_t vi, vi2;
73 :
74 67025414 : bool existed;
75 67025414 : varinfo_t *slot_p = &call_stmt_vars->get_or_insert (call, &existed);
76 67025414 : if (existed)
77 51289452 : return *slot_p;
78 :
79 15735962 : vi = new_var_info (NULL_TREE, "CALLUSED", true);
80 15735962 : vi->offset = 0;
81 15735962 : vi->size = 1;
82 15735962 : vi->fullsize = 2;
83 15735962 : vi->is_full_var = true;
84 15735962 : vi->is_reg_var = true;
85 :
86 15735962 : vi2 = new_var_info (NULL_TREE, "CALLCLOBBERED", true);
87 15735962 : vi2->offset = 1;
88 15735962 : vi2->size = 1;
89 15735962 : vi2->fullsize = 2;
90 15735962 : vi2->is_full_var = true;
91 15735962 : vi2->is_reg_var = true;
92 :
93 15735962 : vi->next = vi2->id;
94 :
95 15735962 : *slot_p = vi;
96 15735962 : 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 42057333 : 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 24968081 : get_call_clobber_vi (gcall *call)
113 : {
114 24968081 : 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 437862011 : new_constraint (const struct constraint_expr lhs,
131 : const struct constraint_expr rhs)
132 : {
133 0 : constraint_t ret = constraint_pool.allocate ();
134 437862011 : ret->lhs = lhs;
135 437862011 : ret->rhs = rhs;
136 437862011 : 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 91096128 : insert_vi_for_tree (tree t, varinfo_t vi)
143 : {
144 91096128 : gcc_assert (vi);
145 91096128 : bool existed = vi_for_tree->put (t, vi);
146 91096128 : gcc_assert (!existed);
147 91096128 : }
148 :
149 : /* Return a printable name for DECL. */
150 :
151 : static const char *
152 90046373 : alias_get_name (tree decl)
153 : {
154 90046373 : const char *res = "NULL";
155 90046373 : if (dump_file)
156 : {
157 4004 : char *temp = NULL;
158 4004 : if (TREE_CODE (decl) == SSA_NAME)
159 : {
160 2264 : res = get_name (decl);
161 3711 : temp = xasprintf ("%s_%u", res ? res : "", SSA_NAME_VERSION (decl));
162 : }
163 1740 : else if (HAS_DECL_ASSEMBLER_NAME_P (decl)
164 1740 : && DECL_ASSEMBLER_NAME_SET_P (decl))
165 759 : res = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME_RAW (decl));
166 981 : else if (DECL_P (decl))
167 : {
168 981 : res = get_name (decl);
169 981 : if (!res)
170 4 : temp = xasprintf ("D.%u", DECL_UID (decl));
171 : }
172 :
173 3027 : if (temp)
174 : {
175 2268 : res = ggc_strdup (temp);
176 2268 : free (temp);
177 : }
178 : }
179 :
180 90046373 : 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 238680435 : get_vi_for_tree (tree t)
188 : {
189 238680435 : varinfo_t *slot = vi_for_tree->get (t);
190 238680435 : if (slot == NULL)
191 : {
192 80722907 : unsigned int id = create_variable_info_for (t, alias_get_name (t), false);
193 80722907 : return get_varinfo (id);
194 : }
195 :
196 157957528 : return *slot;
197 : }
198 :
199 : /* Get a scalar constraint expression for a new temporary variable. */
200 :
201 : static struct constraint_expr
202 3110653 : new_scalar_tmp_constraint_exp (const char *name, bool add_id)
203 : {
204 3110653 : struct constraint_expr tmp;
205 3110653 : varinfo_t vi;
206 :
207 3110653 : vi = new_var_info (NULL_TREE, name, add_id);
208 3110653 : vi->offset = 0;
209 3110653 : vi->size = -1;
210 3110653 : vi->fullsize = -1;
211 3110653 : vi->is_full_var = 1;
212 3110653 : vi->is_reg_var = 1;
213 :
214 3110653 : tmp.var = vi->id;
215 3110653 : tmp.type = SCALAR;
216 3110653 : tmp.offset = 0;
217 :
218 3110653 : 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 219089905 : get_constraint_for_ssa_var (tree t, vec<ce_s> *results, bool address_p)
226 : {
227 219089905 : struct constraint_expr cexpr;
228 219089905 : varinfo_t vi;
229 :
230 : /* We allow FUNCTION_DECLs here even though it doesn't make much sense. */
231 219089905 : gcc_assert (TREE_CODE (t) == SSA_NAME || DECL_P (t));
232 :
233 219089905 : if (TREE_CODE (t) == SSA_NAME
234 219089905 : && SSA_NAME_IS_DEFAULT_DEF (t))
235 : {
236 : /* For parameters, get at the points-to set for the actual parm
237 : decl. */
238 17957824 : if (TREE_CODE (SSA_NAME_VAR (t)) == PARM_DECL
239 17957824 : || TREE_CODE (SSA_NAME_VAR (t)) == RESULT_DECL)
240 : {
241 17699444 : get_constraint_for_ssa_var (SSA_NAME_VAR (t), results, address_p);
242 41501619 : return;
243 : }
244 : /* For undefined SSA names return nothing. */
245 258380 : else if (!ssa_defined_default_def_p (t))
246 : {
247 258380 : cexpr.var = nothing_id;
248 258380 : cexpr.type = SCALAR;
249 258380 : cexpr.offset = 0;
250 258380 : results->safe_push (cexpr);
251 258380 : return;
252 : }
253 : }
254 :
255 : /* For global variables resort to the alias target. */
256 201132081 : if (VAR_P (t) && (TREE_STATIC (t) || DECL_EXTERNAL (t)))
257 : {
258 11266605 : varpool_node *node = varpool_node::get (t);
259 11266605 : if (node && node->alias && node->analyzed)
260 : {
261 17570 : 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 17570 : 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 17570 : DECL_PT_UID (t) = DECL_UID (node->decl);
270 17570 : t = node->decl;
271 : }
272 :
273 : /* If this is decl may bind to NULL note that. */
274 11266605 : if (address_p
275 11266605 : && (! node || ! node->nonzero_address ()))
276 : {
277 9472 : cexpr.var = nothing_id;
278 9472 : cexpr.type = SCALAR;
279 9472 : cexpr.offset = 0;
280 9472 : results->safe_push (cexpr);
281 : }
282 : }
283 :
284 201132081 : vi = get_vi_for_tree (t);
285 201132081 : cexpr.var = vi->id;
286 201132081 : cexpr.type = SCALAR;
287 201132081 : cexpr.offset = 0;
288 :
289 : /* If we are not taking the address of the constraint expr, add all
290 : sub-fiels of the variable as well. */
291 201132081 : if (!address_p
292 164501830 : && !vi->is_full_var)
293 : {
294 19722188 : for (; vi; vi = vi_next (vi))
295 : {
296 13877837 : cexpr.var = vi->id;
297 13877837 : results->safe_push (cexpr);
298 : }
299 : return;
300 : }
301 :
302 195287730 : 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 433446095 : process_constraint (constraint_t t)
310 : {
311 433446095 : struct constraint_expr rhs = t->rhs;
312 433446095 : struct constraint_expr lhs = t->lhs;
313 :
314 433446095 : gcc_assert (rhs.var < varmap.length ());
315 433446095 : 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 433446095 : 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 433446095 : 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 433446095 : if (rhs.type != ADDRESSOF
330 433446095 : && !get_varinfo (rhs.var)->may_have_pointers)
331 433446095 : return;
332 :
333 : /* Likewise adding to the solution of a non-pointer var isn't useful. */
334 433056390 : 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 433054704 : if (rhs.type == DEREF && lhs.type == DEREF && rhs.var != anything_id)
339 : {
340 : /* Split into tmp = *rhs, *lhs = tmp. */
341 310191 : struct constraint_expr tmplhs;
342 310191 : tmplhs = new_scalar_tmp_constraint_exp ("doubledereftmp", true);
343 310191 : process_constraint (new_constraint (tmplhs, rhs));
344 310191 : process_constraint (new_constraint (lhs, tmplhs));
345 310191 : }
346 432744513 : else if ((rhs.type != SCALAR || rhs.offset != 0) && lhs.type == DEREF)
347 : {
348 : /* Split into tmp = &rhs, *lhs = tmp. */
349 2001784 : struct constraint_expr tmplhs;
350 2001784 : tmplhs = new_scalar_tmp_constraint_exp ("derefaddrtmp", true);
351 2001784 : process_constraint (new_constraint (tmplhs, rhs));
352 2001784 : process_constraint (new_constraint (lhs, tmplhs));
353 2001784 : }
354 : else
355 : {
356 430742729 : gcc_assert (rhs.type != ADDRESSOF || rhs.offset == 0);
357 430742729 : if (rhs.type == ADDRESSOF)
358 84950172 : get_varinfo (get_varinfo (rhs.var)->head)->address_taken = true;
359 430742729 : 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 39187803 : bitpos_of_field (const tree fdecl)
369 : {
370 39187803 : if (!tree_fits_uhwi_p (DECL_FIELD_OFFSET (fdecl))
371 39187803 : || !tree_fits_uhwi_p (DECL_FIELD_BIT_OFFSET (fdecl)))
372 : return -1;
373 :
374 39187803 : return (tree_to_uhwi (DECL_FIELD_OFFSET (fdecl)) * BITS_PER_UNIT
375 39187803 : + 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 40571153 : get_constraint_for_ptr_offset (tree ptr, tree offset,
384 : vec<ce_s> *results)
385 : {
386 40571153 : struct constraint_expr c;
387 40571153 : unsigned int j, n;
388 40571153 : 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 40571153 : if (!use_field_sensitive)
393 : {
394 2043188 : get_constraint_for_rhs (ptr, results);
395 2043188 : 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 38527965 : if (offset == NULL_TREE
403 13592060 : || TREE_CODE (offset) != INTEGER_CST)
404 : rhsoffset = UNKNOWN_OFFSET;
405 : else
406 : {
407 : /* Sign-extend the offset. */
408 11648590 : offset_int soffset = offset_int::from (wi::to_wide (offset), SIGNED);
409 11648590 : if (!wi::fits_shwi_p (soffset))
410 : rhsoffset = UNKNOWN_OFFSET;
411 : else
412 : {
413 : /* Make sure the bit-offset also fits. */
414 11648590 : HOST_WIDE_INT rhsunitoffset = soffset.to_shwi ();
415 11648590 : rhsoffset = rhsunitoffset * (unsigned HOST_WIDE_INT) BITS_PER_UNIT;
416 11648590 : if (rhsunitoffset != rhsoffset / BITS_PER_UNIT)
417 359 : rhsoffset = UNKNOWN_OFFSET;
418 : }
419 : }
420 :
421 38527965 : get_constraint_for_rhs (ptr, results);
422 38527965 : if (rhsoffset == 0)
423 : return;
424 :
425 : /* As we are eventually appending to the solution do not use
426 : vec::iterate here. */
427 32351566 : n = results->length ();
428 64703318 : for (j = 0; j < n; j++)
429 : {
430 32351752 : varinfo_t curr;
431 32351752 : c = (*results)[j];
432 32351752 : curr = get_varinfo (c.var);
433 :
434 32351752 : if (c.type == ADDRESSOF
435 : /* If this varinfo represents a full variable just use it. */
436 10600231 : && curr->is_full_var)
437 : ;
438 24153623 : else if (c.type == ADDRESSOF
439 : /* If we do not know the offset add all subfields. */
440 2402102 : && rhsoffset == UNKNOWN_OFFSET)
441 : {
442 30799 : varinfo_t temp = get_varinfo (curr->head);
443 173768 : do
444 : {
445 173768 : struct constraint_expr c2;
446 173768 : c2.var = temp->id;
447 173768 : c2.type = ADDRESSOF;
448 173768 : c2.offset = 0;
449 173768 : if (c2.var != c.var)
450 142969 : results->safe_push (c2);
451 173768 : temp = vi_next (temp);
452 : }
453 173768 : while (temp);
454 : }
455 24122824 : else if (c.type == ADDRESSOF)
456 : {
457 2371303 : varinfo_t temp;
458 2371303 : unsigned HOST_WIDE_INT offset = curr->offset + rhsoffset;
459 :
460 : /* If curr->offset + rhsoffset is less than zero adjust it. */
461 2371303 : if (rhsoffset < 0
462 0 : && curr->offset < offset)
463 2371303 : 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 2371303 : temp = first_or_preceding_vi_for_offset (curr, offset);
471 2371303 : c.var = temp->id;
472 2371303 : c.offset = 0;
473 2371303 : temp = vi_next (temp);
474 2371303 : while (temp
475 2488593 : && temp->offset < offset + curr->size)
476 : {
477 117290 : struct constraint_expr c2;
478 117290 : c2.var = temp->id;
479 117290 : c2.type = ADDRESSOF;
480 117290 : c2.offset = 0;
481 117290 : results->safe_push (c2);
482 117290 : temp = vi_next (temp);
483 : }
484 : }
485 21751521 : else if (c.type == SCALAR)
486 : {
487 21751521 : 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 32351752 : (*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 31542487 : get_constraint_for_component_ref (tree t, vec<ce_s> *results,
506 : bool address_p, bool lhs_p)
507 : {
508 31542487 : tree orig_t = t;
509 31542487 : poly_int64 bitsize = -1;
510 31542487 : poly_int64 bitmaxsize = -1;
511 31542487 : poly_int64 bitpos;
512 31542487 : bool reverse;
513 31542487 : tree forzero;
514 :
515 : /* Some people like to do cute things like take the address of
516 : &0->a.b. */
517 31542487 : forzero = t;
518 31542487 : while (handled_component_p (forzero)
519 46344227 : || INDIRECT_REF_P (forzero)
520 138632648 : || TREE_CODE (forzero) == MEM_REF)
521 60745934 : forzero = TREE_OPERAND (forzero, 0);
522 :
523 31542487 : if (CONSTANT_CLASS_P (forzero) && integer_zerop (forzero))
524 : {
525 1759 : struct constraint_expr temp;
526 :
527 1759 : temp.offset = 0;
528 1759 : temp.var = integer_id;
529 1759 : temp.type = SCALAR;
530 1759 : results->safe_push (temp);
531 1759 : return;
532 : }
533 :
534 31540728 : 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 31540728 : 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 31540718 : if (TREE_CODE (t) == MEM_REF
554 31540718 : && !integer_zerop (TREE_OPERAND (t, 0)))
555 : {
556 11737722 : poly_offset_int off = mem_ref_offset (t);
557 11737722 : off <<= LOG2_BITS_PER_UNIT;
558 11737722 : off += bitpos;
559 11737722 : poly_int64 off_hwi;
560 11737722 : if (off.to_shwi (&off_hwi))
561 11737720 : bitpos = off_hwi;
562 : else
563 : {
564 2 : bitpos = 0;
565 2 : bitmaxsize = -1;
566 : }
567 11737722 : get_constraint_for_1 (TREE_OPERAND (t, 0), results, false, lhs_p);
568 11737722 : do_deref (results);
569 : }
570 : else
571 19802996 : get_constraint_for_1 (t, results, true, lhs_p);
572 :
573 : /* Strip off nothing_id. */
574 31540718 : if (results->length () == 2)
575 : {
576 8493 : gcc_assert ((*results)[0].var == nothing_id);
577 8493 : results->unordered_remove (0);
578 : }
579 31540718 : gcc_assert (results->length () == 1);
580 31540718 : struct constraint_expr &result = results->last ();
581 :
582 31540718 : if (result.type == SCALAR
583 31540718 : && get_varinfo (result.var)->is_full_var)
584 : /* For single-field vars do not bother about the offset. */
585 8227762 : result.offset = 0;
586 23312956 : 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 11575309 : if (maybe_lt (poly_uint64 (bitpos), get_varinfo (result.var)->fullsize)
594 11575309 : && 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 11565785 : struct constraint_expr cexpr = result;
601 11565785 : varinfo_t curr;
602 11565785 : results->pop ();
603 11565785 : cexpr.offset = 0;
604 60957269 : for (curr = get_varinfo (cexpr.var); curr; curr = vi_next (curr))
605 : {
606 50191812 : if (ranges_maybe_overlap_p (poly_int64 (curr->offset),
607 50191812 : curr->size, bitpos, bitmaxsize))
608 : {
609 11791113 : cexpr.var = curr->id;
610 11791113 : results->safe_push (cexpr);
611 11791113 : 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 12366137 : 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 11565761 : 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 9524 : else if (known_eq (bitmaxsize, 0))
641 : {
642 9193 : 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 331 : if (dump_file && (dump_flags & TDF_DETAILS))
648 0 : fprintf (dump_file, "Access to past the end of variable, ignoring\n");
649 : }
650 11737647 : 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 11737596 : HOST_WIDE_INT const_bitpos;
656 11737596 : if (!bitpos.is_constant (&const_bitpos)
657 11737596 : || const_bitpos == -1
658 11737596 : || maybe_ne (bitsize, bitmaxsize)
659 11026280 : || AGGREGATE_TYPE_P (TREE_TYPE (orig_t))
660 9410341 : || result.offset == UNKNOWN_OFFSET)
661 2327255 : result.offset = UNKNOWN_OFFSET;
662 : else
663 9410341 : 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 23731806 : do_deref (vec<ce_s> *constraints)
686 : {
687 23731806 : struct constraint_expr *c;
688 23731806 : unsigned int i = 0;
689 :
690 47618794 : FOR_EACH_VEC_ELT (*constraints, i, c)
691 : {
692 23886988 : if (c->type == SCALAR)
693 18074003 : c->type = DEREF;
694 5812985 : else if (c->type == ADDRESSOF)
695 5812979 : 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 23731806 : }
707 :
708 : /* Given a tree T, return the constraint expression for taking the
709 : address of it. */
710 :
711 : static void
712 27421214 : get_constraint_for_address_of (tree t, vec<ce_s> *results)
713 : {
714 27421214 : struct constraint_expr *c;
715 27421214 : unsigned int i;
716 :
717 27421214 : get_constraint_for_1 (t, results, true, true);
718 :
719 82267109 : FOR_EACH_VEC_ELT (*results, i, c)
720 : {
721 27424681 : if (c->type == DEREF)
722 1605950 : c->type = SCALAR;
723 : else
724 25818731 : c->type = ADDRESSOF;
725 : }
726 27421214 : }
727 :
728 : /* Given a tree T, return the constraint expression for it. */
729 :
730 : static void
731 313958075 : get_constraint_for_1 (tree t, vec<ce_s> *results, bool address_p,
732 : bool lhs_p)
733 : {
734 313958075 : 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 313958075 : if ((TREE_CODE (t) == INTEGER_CST
750 32294934 : && 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 335664627 : || (TREE_CODE (t) == CONSTRUCTOR
755 550740 : && CONSTRUCTOR_NELTS (t) == 0))
756 : {
757 11090007 : if (flag_delete_null_pointer_checks)
758 11069972 : temp.var = nothing_id;
759 : else
760 20035 : temp.var = nonlocal_id;
761 11090007 : temp.type = ADDRESSOF;
762 11090007 : temp.offset = 0;
763 11090007 : results->safe_push (temp);
764 324194933 : return;
765 : }
766 :
767 : /* String constants are read-only, ideally we'd have a CONST_DECL
768 : for those. */
769 302868068 : if (TREE_CODE (t) == STRING_CST)
770 : {
771 6274277 : temp.var = string_id;
772 6274277 : temp.type = SCALAR;
773 6274277 : temp.offset = 0;
774 6274277 : results->safe_push (temp);
775 6274277 : return;
776 : }
777 :
778 296593791 : switch (TREE_CODE_CLASS (TREE_CODE (t)))
779 : {
780 27246076 : case tcc_expression:
781 27246076 : {
782 27246076 : switch (TREE_CODE (t))
783 : {
784 27188702 : case ADDR_EXPR:
785 27188702 : get_constraint_for_address_of (TREE_OPERAND (t, 0), results);
786 27188702 : return;
787 : default:;
788 : }
789 : break;
790 : }
791 43743486 : case tcc_reference:
792 43743486 : {
793 43743486 : if (!lhs_p && TREE_THIS_VOLATILE (t))
794 : /* Fall back to anything. */
795 : break;
796 :
797 43636844 : switch (TREE_CODE (t))
798 : {
799 11272829 : case MEM_REF:
800 11272829 : {
801 11272829 : struct constraint_expr cs;
802 11272829 : varinfo_t vi, curr;
803 11272829 : get_constraint_for_ptr_offset (TREE_OPERAND (t, 0),
804 11272829 : TREE_OPERAND (t, 1), results);
805 11272829 : do_deref (results);
806 :
807 : /* If we are not taking the address then make sure to process
808 : all subvariables we might access. */
809 11272829 : if (address_p)
810 : return;
811 :
812 10639483 : cs = results->last ();
813 10639483 : if (cs.type == DEREF
814 10639483 : && type_can_have_subvars (TREE_TYPE (t)))
815 : {
816 : /* For dereferences this means we have to defer it
817 : to solving time. */
818 573401 : results->last ().offset = UNKNOWN_OFFSET;
819 573401 : return;
820 : }
821 10066082 : if (cs.type != SCALAR)
822 : return;
823 :
824 4857810 : vi = get_varinfo (cs.var);
825 4857810 : curr = vi_next (vi);
826 4857810 : if (!vi->is_full_var
827 3845325 : && curr)
828 : {
829 2537102 : unsigned HOST_WIDE_INT size;
830 2537102 : if (tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (t))))
831 2537102 : size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (t)));
832 : else
833 2537102 : size = -1;
834 5097054 : 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 3462951 : if (curr->offset - (vi->offset + vi->size - 1) < size)
840 : {
841 2559952 : cs.var = curr->id;
842 2559952 : results->safe_push (cs);
843 : }
844 : else
845 : break;
846 : }
847 : }
848 : return;
849 : }
850 31542487 : case ARRAY_REF:
851 31542487 : case ARRAY_RANGE_REF:
852 31542487 : case COMPONENT_REF:
853 31542487 : case IMAGPART_EXPR:
854 31542487 : case REALPART_EXPR:
855 31542487 : case BIT_FIELD_REF:
856 31542487 : get_constraint_for_component_ref (t, results, address_p, lhs_p);
857 31542487 : return;
858 821528 : case VIEW_CONVERT_EXPR:
859 821528 : get_constraint_for_1 (TREE_OPERAND (t, 0), results, address_p,
860 : lhs_p);
861 821528 : return;
862 : /* We are missing handling for TARGET_MEM_REF here. */
863 : default:;
864 : }
865 : break;
866 : }
867 154424589 : case tcc_exceptional:
868 154424589 : {
869 154424589 : switch (TREE_CODE (t))
870 : {
871 154375274 : case SSA_NAME:
872 154375274 : {
873 154375274 : get_constraint_for_ssa_var (t, results, address_p);
874 154375274 : return;
875 : }
876 49115 : case CONSTRUCTOR:
877 49115 : {
878 49115 : unsigned int i;
879 49115 : tree val;
880 49115 : auto_vec<ce_s> tmp;
881 282074 : FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (t), i, val)
882 : {
883 232959 : struct constraint_expr *rhsp;
884 232959 : unsigned j;
885 232959 : get_constraint_for_1 (val, &tmp, address_p, lhs_p);
886 466135 : FOR_EACH_VEC_ELT (tmp, j, rhsp)
887 233176 : results->safe_push (*rhsp);
888 232959 : 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 49115 : return;
894 49115 : }
895 : default:;
896 : }
897 : break;
898 : }
899 47704085 : case tcc_declaration:
900 47704085 : {
901 47704085 : if (!lhs_p && VAR_P (t) && TREE_THIS_VOLATILE (t))
902 : /* Fall back to anything. */
903 : break;
904 47015187 : get_constraint_for_ssa_var (t, results, address_p);
905 47015187 : return;
906 : }
907 23475520 : case tcc_constant:
908 23475520 : {
909 : /* We cannot refer to automatic variables through constants. */
910 23475520 : temp.type = ADDRESSOF;
911 23475520 : temp.var = nonlocal_id;
912 23475520 : temp.offset = 0;
913 23475520 : results->safe_push (temp);
914 23475520 : return;
915 : }
916 795540 : default:;
917 : }
918 :
919 : /* The default fallback is a constraint from anything. */
920 853149 : temp.type = ADDRESSOF;
921 853149 : temp.var = anything_id;
922 853149 : temp.offset = 0;
923 853149 : results->safe_push (temp);
924 : }
925 :
926 : /* Given a gimple tree T, return the constraint expression vector for it. */
927 :
928 : static void
929 86567003 : get_constraint_for (tree t, vec<ce_s> *results)
930 : {
931 86567003 : gcc_assert (results->length () == 0);
932 :
933 86567003 : get_constraint_for_1 (t, results, false, true);
934 86567003 : }
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 167374653 : get_constraint_for_rhs (tree t, vec<ce_s> *results)
941 : {
942 167374653 : gcc_assert (results->length () == 0);
943 :
944 167374653 : get_constraint_for_1 (t, results, false, false);
945 167374653 : }
946 :
947 :
948 : /* Efficiently generates constraints from all entries in *RHSC to all
949 : entries in *LHSC. */
950 :
951 : static void
952 93453813 : process_all_all_constraints (const vec<ce_s> &lhsc,
953 : const vec<ce_s> &rhsc)
954 : {
955 93453813 : struct constraint_expr *lhsp, *rhsp;
956 93453813 : unsigned i, j;
957 :
958 95647522 : if (lhsc.length () <= 1 || rhsc.length () <= 1)
959 : {
960 281191725 : FOR_EACH_VEC_ELT (lhsc, i, lhsp)
961 303908115 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
962 115371531 : process_constraint (new_constraint (*lhsp, *rhsp));
963 : }
964 : else
965 : {
966 798672 : struct constraint_expr tmp;
967 798672 : tmp = new_scalar_tmp_constraint_exp ("allalltmp", true);
968 4183872 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
969 2586528 : process_constraint (new_constraint (tmp, *rhsp));
970 3540437 : FOR_EACH_VEC_ELT (lhsc, i, lhsp)
971 1943093 : process_constraint (new_constraint (*lhsp, tmp));
972 : }
973 93453813 : }
974 :
975 : /* Handle aggregate copies by expanding into copies of the respective
976 : fields of the structures. */
977 :
978 : static void
979 2466022 : do_structure_copy (tree lhsop, tree rhsop)
980 : {
981 2466022 : struct constraint_expr *lhsp, *rhsp;
982 2466022 : auto_vec<ce_s> lhsc;
983 2466022 : auto_vec<ce_s> rhsc;
984 2466022 : unsigned j;
985 :
986 2466022 : get_constraint_for (lhsop, &lhsc);
987 2466022 : get_constraint_for_rhs (rhsop, &rhsc);
988 2466022 : lhsp = &lhsc[0];
989 2466022 : rhsp = &rhsc[0];
990 2466022 : if (lhsp->type == DEREF
991 1909587 : || (lhsp->type == ADDRESSOF && lhsp->var == anything_id)
992 1909587 : || rhsp->type == DEREF)
993 : {
994 889529 : if (lhsp->type == DEREF)
995 : {
996 556435 : gcc_assert (lhsc.length () == 1);
997 556435 : lhsp->offset = UNKNOWN_OFFSET;
998 : }
999 889529 : if (rhsp->type == DEREF)
1000 : {
1001 445102 : gcc_assert (rhsc.length () == 1);
1002 445102 : rhsp->offset = UNKNOWN_OFFSET;
1003 : }
1004 889529 : process_all_all_constraints (lhsc, rhsc);
1005 : }
1006 1576493 : else if (lhsp->type == SCALAR
1007 1576493 : && (rhsp->type == SCALAR
1008 450735 : || rhsp->type == ADDRESSOF))
1009 : {
1010 1576493 : HOST_WIDE_INT lhssize, lhsoffset;
1011 1576493 : HOST_WIDE_INT rhssize, rhsoffset;
1012 1576493 : bool reverse;
1013 1576493 : unsigned k = 0;
1014 1576493 : if (!get_ref_base_and_extent_hwi (lhsop, &lhsoffset, &lhssize, &reverse)
1015 1576493 : || !get_ref_base_and_extent_hwi (rhsop, &rhsoffset, &rhssize,
1016 : &reverse))
1017 : {
1018 4311 : process_all_all_constraints (lhsc, rhsc);
1019 4311 : return;
1020 : }
1021 5922474 : for (j = 0; lhsc.iterate (j, &lhsp);)
1022 : {
1023 4424113 : varinfo_t lhsv, rhsv;
1024 4424113 : rhsp = &rhsc[k];
1025 4424113 : lhsv = get_varinfo (lhsp->var);
1026 4424113 : rhsv = get_varinfo (rhsp->var);
1027 4424113 : if (lhsv->may_have_pointers
1028 4424113 : && (lhsv->is_full_var
1029 3882480 : || rhsv->is_full_var
1030 2984366 : || ranges_overlap_p (lhsv->offset + rhsoffset, lhsv->size,
1031 2984366 : rhsv->offset + lhsoffset, rhsv->size)))
1032 3315360 : process_constraint (new_constraint (*lhsp, *rhsp));
1033 4424113 : if (!rhsv->is_full_var
1034 3121214 : && (lhsv->is_full_var
1035 2984366 : || (lhsv->offset + rhsoffset + lhsv->size
1036 2984366 : > rhsv->offset + lhsoffset + rhsv->size)))
1037 : {
1038 1253981 : ++k;
1039 1253981 : if (k >= rhsc.length ())
1040 : break;
1041 : }
1042 : else
1043 3170132 : ++j;
1044 : }
1045 1572182 : }
1046 : else
1047 0 : gcc_unreachable ();
1048 2466022 : }
1049 :
1050 : /* Create constraints ID = { rhsc }. */
1051 :
1052 : static void
1053 55427753 : make_constraints_to (unsigned id, const vec<ce_s> &rhsc)
1054 : {
1055 55427753 : struct constraint_expr *c;
1056 55427753 : struct constraint_expr includes;
1057 55427753 : unsigned int j;
1058 :
1059 55427753 : includes.var = id;
1060 55427753 : includes.offset = 0;
1061 55427753 : includes.type = SCALAR;
1062 :
1063 114120260 : FOR_EACH_VEC_ELT (rhsc, j, c)
1064 58692507 : process_constraint (new_constraint (includes, *c));
1065 55427753 : }
1066 :
1067 : /* Create a constraint ID = OP. */
1068 :
1069 : static void
1070 55282319 : make_constraint_to (unsigned id, tree op)
1071 : {
1072 55282319 : auto_vec<ce_s> rhsc;
1073 55282319 : get_constraint_for_rhs (op, &rhsc);
1074 55282319 : make_constraints_to (id, rhsc);
1075 55282319 : }
1076 :
1077 : /* Create a constraint ID = &FROM. */
1078 :
1079 : static void
1080 11403683 : make_constraint_from (varinfo_t vi, int from)
1081 : {
1082 11403683 : struct constraint_expr lhs, rhs;
1083 :
1084 11403683 : lhs.var = vi->id;
1085 11403683 : lhs.offset = 0;
1086 11403683 : lhs.type = SCALAR;
1087 :
1088 11403683 : rhs.var = from;
1089 11403683 : rhs.offset = 0;
1090 11403683 : rhs.type = ADDRESSOF;
1091 11403683 : process_constraint (new_constraint (lhs, rhs));
1092 11403683 : }
1093 :
1094 : /* Create a constraint ID = FROM. */
1095 :
1096 : static void
1097 76040939 : make_copy_constraint (varinfo_t vi, int from)
1098 : {
1099 76040939 : struct constraint_expr lhs, rhs;
1100 :
1101 76040939 : lhs.var = vi->id;
1102 76040939 : lhs.offset = 0;
1103 76040939 : lhs.type = SCALAR;
1104 :
1105 76040939 : rhs.var = from;
1106 76040939 : rhs.offset = 0;
1107 76040939 : rhs.type = SCALAR;
1108 76040939 : process_constraint (new_constraint (lhs, rhs));
1109 76040939 : }
1110 :
1111 : /* Make constraints necessary to make OP escape. */
1112 :
1113 : static void
1114 22997726 : make_escape_constraint (tree op)
1115 : {
1116 0 : make_constraint_to (escaped_id, op);
1117 22997726 : }
1118 :
1119 : /* Make constraint necessary to make all indirect references
1120 : from VI escape. */
1121 :
1122 : static void
1123 1220113 : make_indirect_escape_constraint (varinfo_t vi)
1124 : {
1125 1220113 : struct constraint_expr lhs, rhs;
1126 : /* escaped = *(VAR + UNKNOWN); */
1127 1220113 : lhs.type = SCALAR;
1128 1220113 : lhs.var = escaped_id;
1129 1220113 : lhs.offset = 0;
1130 1220113 : rhs.type = DEREF;
1131 1220113 : rhs.var = vi->id;
1132 1220113 : rhs.offset = UNKNOWN_OFFSET;
1133 1220113 : process_constraint (new_constraint (lhs, rhs));
1134 1220113 : }
1135 :
1136 : /* Add constraints to that the solution of VI is transitively closed. */
1137 :
1138 : static void
1139 25327009 : make_transitive_closure_constraints (varinfo_t vi)
1140 : {
1141 25327009 : struct constraint_expr lhs, rhs;
1142 :
1143 : /* VAR = *(VAR + UNKNOWN); */
1144 25327009 : lhs.type = SCALAR;
1145 25327009 : lhs.var = vi->id;
1146 25327009 : lhs.offset = 0;
1147 25327009 : rhs.type = DEREF;
1148 25327009 : rhs.var = vi->id;
1149 25327009 : rhs.offset = UNKNOWN_OFFSET;
1150 25327009 : process_constraint (new_constraint (lhs, rhs));
1151 25327009 : }
1152 :
1153 : /* Add constraints to that the solution of VI has all subvariables added. */
1154 :
1155 : static void
1156 30886541 : make_any_offset_constraints (varinfo_t vi)
1157 : {
1158 30886541 : struct constraint_expr lhs, rhs;
1159 :
1160 : /* VAR = VAR + UNKNOWN; */
1161 30886541 : lhs.type = SCALAR;
1162 30886541 : lhs.var = vi->id;
1163 30886541 : lhs.offset = 0;
1164 30886541 : rhs.type = SCALAR;
1165 30886541 : rhs.var = vi->id;
1166 30886541 : rhs.offset = UNKNOWN_OFFSET;
1167 30886541 : process_constraint (new_constraint (lhs, rhs));
1168 30886541 : }
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 1000383 : build_fake_var_decl (tree type)
1177 : {
1178 1000383 : tree decl = (tree) XOBNEW (&fake_var_decl_obstack, struct tree_var_decl);
1179 1000383 : memset (decl, 0, sizeof (struct tree_var_decl));
1180 1000383 : TREE_SET_CODE (decl, VAR_DECL);
1181 1000383 : TREE_TYPE (decl) = type;
1182 1000383 : DECL_UID (decl) = allocate_decl_uid ();
1183 1000383 : SET_DECL_PT_UID (decl, -1);
1184 1000383 : layout_decl (decl, 0);
1185 1000383 : return decl;
1186 : }
1187 :
1188 : /* Create a new artificial heap variable with NAME.
1189 : Return the created variable. */
1190 :
1191 : static varinfo_t
1192 415942 : make_heapvar (const char *name, bool add_id)
1193 : {
1194 415942 : varinfo_t vi;
1195 415942 : tree heapvar;
1196 :
1197 415942 : heapvar = build_fake_var_decl (ptr_type_node);
1198 415942 : DECL_EXTERNAL (heapvar) = 1;
1199 :
1200 415942 : vi = new_var_info (heapvar, name, add_id);
1201 415942 : vi->is_heap_var = true;
1202 415942 : vi->is_unknown_size_var = true;
1203 415942 : vi->offset = 0;
1204 415942 : vi->fullsize = ~0;
1205 415942 : vi->size = ~0;
1206 415942 : vi->is_full_var = true;
1207 415942 : insert_vi_for_tree (heapvar, vi);
1208 :
1209 415942 : 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 12816 : make_constraint_from_restrict (varinfo_t lhs, const char *name, bool add_id)
1218 : {
1219 12816 : varinfo_t vi = make_heapvar (name, add_id);
1220 12816 : vi->is_restrict_var = 1;
1221 12816 : vi->is_global_var = 1;
1222 12816 : vi->may_have_pointers = 1;
1223 12816 : make_constraint_from (lhs, vi->id);
1224 12816 : 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 12816 : make_constraint_from_global_restrict (varinfo_t lhs, const char *name,
1234 : bool add_id)
1235 : {
1236 12816 : varinfo_t vi = make_constraint_from_restrict (lhs, name, add_id);
1237 12816 : make_copy_constraint (vi, nonlocal_id);
1238 12816 : 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 1470116 : get_function_part_constraint (varinfo_t fi, unsigned part)
1246 : {
1247 1470116 : struct constraint_expr c;
1248 :
1249 1470116 : gcc_assert (in_ipa_mode);
1250 :
1251 1470116 : 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 504026 : else if (fi->decl && TREE_CODE (fi->decl) == FUNCTION_DECL)
1259 : {
1260 500643 : varinfo_t ai = first_vi_for_offset (fi, part);
1261 500643 : if (ai)
1262 500643 : c.var = ai->id;
1263 : else
1264 : c.var = anything_id;
1265 : c.offset = 0;
1266 : c.type = SCALAR;
1267 : }
1268 : else
1269 : {
1270 3383 : c.var = fi->id;
1271 3383 : c.offset = part;
1272 3383 : c.type = DEREF;
1273 : }
1274 :
1275 1470116 : 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 29774375 : handle_call_arg (gcall *stmt, tree arg, vec<ce_s> *results, int flags,
1285 : int callescape_id, bool writes_global_memory)
1286 : {
1287 29774375 : int relevant_indirect_flags = EAF_NO_INDIRECT_CLOBBER | EAF_NO_INDIRECT_READ
1288 : | EAF_NO_INDIRECT_ESCAPE;
1289 29774375 : int relevant_flags = relevant_indirect_flags
1290 : | EAF_NO_DIRECT_CLOBBER
1291 : | EAF_NO_DIRECT_READ
1292 : | EAF_NO_DIRECT_ESCAPE;
1293 29774375 : if (gimple_call_lhs (stmt))
1294 : {
1295 11160759 : relevant_flags |= EAF_NOT_RETURNED_DIRECTLY | EAF_NOT_RETURNED_INDIRECTLY;
1296 11160759 : 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 11160759 : if (flags & EAF_NO_DIRECT_READ)
1304 2013930 : 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 29774375 : if ((flags & EAF_UNUSED) || ((flags & relevant_flags) == relevant_flags))
1311 : return;
1312 :
1313 : /* Produce varinfo for direct accesses to ARG. */
1314 28515146 : varinfo_t tem = new_var_info (NULL_TREE, "callarg", true);
1315 28515146 : tem->is_reg_var = true;
1316 28515146 : make_constraint_to (tem->id, arg);
1317 28515146 : make_any_offset_constraints (tem);
1318 :
1319 28515146 : 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 28515146 : if (((flags & EAF_NO_INDIRECT_CLOBBER) != 0)
1325 28515146 : == ((flags & EAF_NO_DIRECT_CLOBBER) != 0)
1326 27140322 : && (((flags & EAF_NO_INDIRECT_READ) != 0)
1327 27140322 : == ((flags & EAF_NO_DIRECT_READ) != 0))
1328 26175228 : && (((flags & EAF_NO_INDIRECT_ESCAPE) != 0)
1329 26175228 : == ((flags & EAF_NO_DIRECT_ESCAPE) != 0))
1330 25624673 : && (((flags & EAF_NOT_RETURNED_INDIRECTLY) != 0)
1331 25624673 : == ((flags & EAF_NOT_RETURNED_DIRECTLY) != 0)))
1332 : {
1333 23747421 : make_transitive_closure_constraints (tem);
1334 23747421 : callarg_transitive = true;
1335 : }
1336 :
1337 : /* If necessary, produce varinfo for indirect accesses to ARG. */
1338 28515146 : varinfo_t indir_tem = NULL;
1339 23747421 : if (!callarg_transitive
1340 4767725 : && (flags & relevant_indirect_flags) != relevant_indirect_flags)
1341 : {
1342 1695997 : struct constraint_expr lhs, rhs;
1343 1695997 : indir_tem = new_var_info (NULL_TREE, "indircallarg", true);
1344 1695997 : indir_tem->is_reg_var = true;
1345 :
1346 : /* indir_term = *tem. */
1347 1695997 : lhs.type = SCALAR;
1348 1695997 : lhs.var = indir_tem->id;
1349 1695997 : lhs.offset = 0;
1350 :
1351 1695997 : rhs.type = DEREF;
1352 1695997 : rhs.var = tem->id;
1353 1695997 : rhs.offset = UNKNOWN_OFFSET;
1354 1695997 : process_constraint (new_constraint (lhs, rhs));
1355 :
1356 1695997 : 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 1695997 : if (!(flags & EAF_NO_INDIRECT_READ))
1361 1579588 : make_transitive_closure_constraints (indir_tem);
1362 1695997 : gcc_checking_assert (!(flags & EAF_NO_DIRECT_READ));
1363 : }
1364 :
1365 28515146 : if (gimple_call_lhs (stmt))
1366 : {
1367 10922394 : if (!(flags & EAF_NOT_RETURNED_DIRECTLY))
1368 : {
1369 9999694 : struct constraint_expr cexpr;
1370 9999694 : cexpr.var = tem->id;
1371 9999694 : cexpr.type = SCALAR;
1372 9999694 : cexpr.offset = 0;
1373 9999694 : results->safe_push (cexpr);
1374 : }
1375 10922394 : if (!callarg_transitive & !(flags & EAF_NOT_RETURNED_INDIRECTLY))
1376 : {
1377 597904 : struct constraint_expr cexpr;
1378 597904 : cexpr.var = indir_tem->id;
1379 597904 : cexpr.type = SCALAR;
1380 597904 : cexpr.offset = 0;
1381 597904 : results->safe_push (cexpr);
1382 : }
1383 : }
1384 :
1385 28515146 : if (!(flags & EAF_NO_DIRECT_READ))
1386 : {
1387 26341411 : varinfo_t uses = get_call_use_vi (stmt);
1388 26341411 : make_copy_constraint (uses, tem->id);
1389 26341411 : if (!callarg_transitive & !(flags & EAF_NO_INDIRECT_READ))
1390 1579588 : make_copy_constraint (uses, indir_tem->id);
1391 : }
1392 : else
1393 : /* To read indirectly we need to read directly. */
1394 2173735 : gcc_checking_assert (flags & EAF_NO_INDIRECT_READ);
1395 :
1396 28515146 : if (!(flags & EAF_NO_DIRECT_CLOBBER))
1397 : {
1398 23549176 : struct constraint_expr lhs, rhs;
1399 :
1400 : /* *arg = callescape. */
1401 23549176 : lhs.type = DEREF;
1402 23549176 : lhs.var = tem->id;
1403 23549176 : lhs.offset = 0;
1404 :
1405 23549176 : rhs.type = SCALAR;
1406 23549176 : rhs.var = callescape_id;
1407 23549176 : rhs.offset = 0;
1408 23549176 : process_constraint (new_constraint (lhs, rhs));
1409 :
1410 : /* callclobbered = arg. */
1411 23549176 : make_copy_constraint (get_call_clobber_vi (stmt), tem->id);
1412 : }
1413 28515146 : if (!callarg_transitive & !(flags & EAF_NO_INDIRECT_CLOBBER))
1414 : {
1415 1398865 : struct constraint_expr lhs, rhs;
1416 :
1417 : /* *indir_arg = callescape. */
1418 1398865 : lhs.type = DEREF;
1419 1398865 : lhs.var = indir_tem->id;
1420 1398865 : lhs.offset = 0;
1421 :
1422 1398865 : rhs.type = SCALAR;
1423 1398865 : rhs.var = callescape_id;
1424 1398865 : rhs.offset = 0;
1425 1398865 : process_constraint (new_constraint (lhs, rhs));
1426 :
1427 : /* callclobbered = indir_arg. */
1428 1398865 : make_copy_constraint (get_call_clobber_vi (stmt), indir_tem->id);
1429 : }
1430 :
1431 28515146 : if (!(flags & (EAF_NO_DIRECT_ESCAPE | EAF_NO_INDIRECT_ESCAPE)))
1432 : {
1433 22012279 : struct constraint_expr lhs, rhs;
1434 :
1435 : /* callescape = arg; */
1436 22012279 : lhs.var = callescape_id;
1437 22012279 : lhs.offset = 0;
1438 22012279 : lhs.type = SCALAR;
1439 :
1440 22012279 : rhs.var = tem->id;
1441 22012279 : rhs.offset = 0;
1442 22012279 : rhs.type = SCALAR;
1443 22012279 : process_constraint (new_constraint (lhs, rhs));
1444 :
1445 22012279 : if (writes_global_memory)
1446 21243072 : make_escape_constraint (arg);
1447 : }
1448 6502867 : else if (!callarg_transitive & !(flags & EAF_NO_INDIRECT_ESCAPE))
1449 : {
1450 1333532 : struct constraint_expr lhs, rhs;
1451 :
1452 : /* callescape = *(indir_arg + UNKNOWN); */
1453 1333532 : lhs.var = callescape_id;
1454 1333532 : lhs.offset = 0;
1455 1333532 : lhs.type = SCALAR;
1456 :
1457 1333532 : rhs.var = indir_tem->id;
1458 1333532 : rhs.offset = 0;
1459 1333532 : rhs.type = SCALAR;
1460 1333532 : process_constraint (new_constraint (lhs, rhs));
1461 :
1462 1333532 : if (writes_global_memory)
1463 1220113 : make_indirect_escape_constraint (tem);
1464 : }
1465 : }
1466 :
1467 : /* For non-IPA mode, generate constraints necessary for a call on the
1468 : RHS and collect return value constraint to RESULTS to be used later in
1469 : handle_lhs_call.
1470 :
1471 : IMPLICIT_EAF_FLAGS are added to each function argument. If
1472 : WRITES_GLOBAL_MEMORY is true function is assumed to possibly write to global
1473 : memory. Similar for READS_GLOBAL_MEMORY. */
1474 :
1475 : static void
1476 15040524 : 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 15040524 : determine_global_memory_access (stmt, &writes_global_memory,
1482 : &reads_global_memory,
1483 : NULL);
1484 :
1485 15040524 : 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 15040524 : struct constraint_expr lhs, rhs;
1491 :
1492 15040524 : lhs.type = SCALAR;
1493 15040524 : lhs.var = callescape->id;
1494 15040524 : lhs.offset = 0;
1495 :
1496 15040524 : rhs.type = reads_global_memory ? SCALAR : ADDRESSOF;
1497 15040524 : rhs.var = nonlocal_id;
1498 15040524 : rhs.offset = 0;
1499 :
1500 15040524 : process_constraint (new_constraint (lhs, rhs));
1501 15040524 : results->safe_push (rhs);
1502 :
1503 15040524 : varinfo_t uses = get_call_use_vi (stmt);
1504 15040524 : make_copy_constraint (uses, callescape->id);
1505 :
1506 44730995 : for (unsigned i = 0; i < gimple_call_num_args (stmt); ++i)
1507 : {
1508 29690471 : tree arg = gimple_call_arg (stmt, i);
1509 29690471 : int flags = gimple_call_arg_flags (stmt, i);
1510 29690471 : handle_call_arg (stmt, arg, results,
1511 : flags | implicit_eaf_flags,
1512 29690471 : callescape->id, writes_global_memory);
1513 : }
1514 :
1515 : /* The static chain escapes as well. */
1516 15040524 : if (gimple_call_chain (stmt))
1517 83904 : handle_call_arg (stmt, gimple_call_chain (stmt), results,
1518 : implicit_eaf_flags
1519 83904 : | gimple_call_static_chain_flags (stmt),
1520 83904 : callescape->id, writes_global_memory);
1521 :
1522 : /* And if we applied NRV the address of the return slot escapes as well. */
1523 15040524 : if (gimple_call_return_slot_opt_p (stmt)
1524 631418 : && gimple_call_lhs (stmt) != NULL_TREE
1525 15643087 : && TREE_ADDRESSABLE (TREE_TYPE (gimple_call_lhs (stmt))))
1526 : {
1527 77520 : int flags = gimple_call_retslot_flags (stmt);
1528 77520 : const int relevant_flags = EAF_NO_DIRECT_ESCAPE
1529 : | EAF_NOT_RETURNED_DIRECTLY;
1530 :
1531 77520 : if (!(flags & EAF_UNUSED) && (flags & relevant_flags) != relevant_flags)
1532 : {
1533 59868 : auto_vec<ce_s> tmpc;
1534 :
1535 59868 : get_constraint_for_address_of (gimple_call_lhs (stmt), &tmpc);
1536 :
1537 59868 : if (!(flags & EAF_NO_DIRECT_ESCAPE))
1538 : {
1539 59866 : make_constraints_to (callescape->id, tmpc);
1540 59866 : if (writes_global_memory)
1541 58668 : make_constraints_to (escaped_id, tmpc);
1542 : }
1543 59868 : if (!(flags & EAF_NOT_RETURNED_DIRECTLY))
1544 : {
1545 : struct constraint_expr *c;
1546 : unsigned i;
1547 177676 : FOR_EACH_VEC_ELT (tmpc, i, c)
1548 58904 : results->safe_push (*c);
1549 : }
1550 59868 : }
1551 : }
1552 15040524 : }
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 5758035 : handle_lhs_call (gcall *stmt, tree lhs, int flags, vec<ce_s> &rhsc,
1560 : tree fndecl)
1561 : {
1562 5758035 : auto_vec<ce_s> lhsc;
1563 :
1564 5758035 : get_constraint_for (lhs, &lhsc);
1565 : /* If the store is to a global decl make sure to
1566 : add proper escape constraints. */
1567 5758035 : lhs = get_base_address (lhs);
1568 5758035 : if (lhs
1569 5758035 : && DECL_P (lhs)
1570 6745862 : && is_global_var (lhs))
1571 : {
1572 3327 : struct constraint_expr tmpc;
1573 3327 : tmpc.var = escaped_id;
1574 3327 : tmpc.offset = 0;
1575 3327 : tmpc.type = SCALAR;
1576 3327 : lhsc.safe_push (tmpc);
1577 : }
1578 :
1579 : /* If the call returns an argument unmodified override the rhs
1580 : constraints. */
1581 5758035 : if (flags & ERF_RETURNS_ARG
1582 5758035 : && (flags & ERF_RETURN_ARG_MASK) < gimple_call_num_args (stmt))
1583 : {
1584 87658 : tree arg;
1585 87658 : rhsc.truncate (0);
1586 87658 : arg = gimple_call_arg (stmt, flags & ERF_RETURN_ARG_MASK);
1587 87658 : get_constraint_for (arg, &rhsc);
1588 87658 : process_all_all_constraints (lhsc, rhsc);
1589 87658 : rhsc.truncate (0);
1590 : }
1591 5670377 : else if (flags & ERF_NOALIAS)
1592 : {
1593 369853 : varinfo_t vi;
1594 369853 : struct constraint_expr tmpc;
1595 369853 : rhsc.truncate (0);
1596 369853 : 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 369853 : DECL_EXTERNAL (vi->decl) = 0;
1600 369853 : 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 369853 : if (!fndecl
1605 369853 : || !fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
1606 216443 : make_constraint_from (vi, nonlocal_id);
1607 369853 : tmpc.var = vi->id;
1608 369853 : tmpc.offset = 0;
1609 369853 : tmpc.type = ADDRESSOF;
1610 369853 : rhsc.safe_push (tmpc);
1611 369853 : process_all_all_constraints (lhsc, rhsc);
1612 369853 : rhsc.truncate (0);
1613 : }
1614 : else
1615 5300524 : process_all_all_constraints (lhsc, rhsc);
1616 5758035 : }
1617 :
1618 :
1619 : /* Create constraints for assigning call argument ARG to the incoming parameter
1620 : INDEX of function FI. */
1621 :
1622 : static void
1623 824418 : find_func_aliases_for_call_arg (varinfo_t fi, unsigned index, tree arg)
1624 : {
1625 824418 : struct constraint_expr lhs;
1626 824418 : lhs = get_function_part_constraint (fi, fi_parm_base + index);
1627 :
1628 824418 : auto_vec<ce_s, 2> rhsc;
1629 824418 : get_constraint_for_rhs (arg, &rhsc);
1630 :
1631 824418 : unsigned j;
1632 824418 : struct constraint_expr *rhsp;
1633 3297673 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
1634 824419 : process_constraint (new_constraint (lhs, *rhsp));
1635 824418 : }
1636 :
1637 : /* Create constraints for the builtin call T. Return true if the call
1638 : was handled, otherwise false. */
1639 :
1640 : static bool
1641 5069972 : find_func_aliases_for_builtin_call (struct function *fn, gcall *t)
1642 : {
1643 5069972 : tree fndecl = gimple_call_fndecl (t);
1644 5069972 : auto_vec<ce_s, 2> lhsc;
1645 5069972 : auto_vec<ce_s, 4> rhsc;
1646 5069972 : varinfo_t fi;
1647 :
1648 5069972 : 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 4606915 : 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 296565 : case BUILT_IN_STRCPY:
1659 296565 : case BUILT_IN_STRNCPY:
1660 296565 : case BUILT_IN_BCOPY:
1661 296565 : case BUILT_IN_MEMCPY:
1662 296565 : case BUILT_IN_MEMMOVE:
1663 296565 : case BUILT_IN_MEMPCPY:
1664 296565 : case BUILT_IN_STPCPY:
1665 296565 : case BUILT_IN_STPNCPY:
1666 296565 : case BUILT_IN_STRCAT:
1667 296565 : case BUILT_IN_STRNCAT:
1668 296565 : case BUILT_IN_STRCPY_CHK:
1669 296565 : case BUILT_IN_STRNCPY_CHK:
1670 296565 : case BUILT_IN_MEMCPY_CHK:
1671 296565 : case BUILT_IN_MEMMOVE_CHK:
1672 296565 : case BUILT_IN_MEMPCPY_CHK:
1673 296565 : case BUILT_IN_STPCPY_CHK:
1674 296565 : case BUILT_IN_STPNCPY_CHK:
1675 296565 : case BUILT_IN_STRCAT_CHK:
1676 296565 : case BUILT_IN_STRNCAT_CHK:
1677 296565 : case BUILT_IN_TM_MEMCPY:
1678 296565 : case BUILT_IN_TM_MEMMOVE:
1679 296565 : {
1680 296565 : tree res = gimple_call_lhs (t);
1681 593130 : tree dest = gimple_call_arg (t, (DECL_FUNCTION_CODE (fndecl)
1682 : == BUILT_IN_BCOPY ? 1 : 0));
1683 593130 : tree src = gimple_call_arg (t, (DECL_FUNCTION_CODE (fndecl)
1684 296565 : == BUILT_IN_BCOPY ? 0 : 1));
1685 296565 : if (res != NULL_TREE)
1686 : {
1687 27717 : get_constraint_for (res, &lhsc);
1688 27717 : if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_MEMPCPY
1689 24658 : || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPCPY
1690 23485 : || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPNCPY
1691 21729 : || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_MEMPCPY_CHK
1692 21400 : || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPCPY_CHK
1693 48844 : || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPNCPY_CHK)
1694 6862 : get_constraint_for_ptr_offset (dest, NULL_TREE, &rhsc);
1695 : else
1696 20855 : get_constraint_for (dest, &rhsc);
1697 27717 : process_all_all_constraints (lhsc, rhsc);
1698 27717 : lhsc.truncate (0);
1699 27717 : rhsc.truncate (0);
1700 : }
1701 296565 : get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
1702 296565 : get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
1703 296565 : do_deref (&lhsc);
1704 296565 : do_deref (&rhsc);
1705 296565 : process_all_all_constraints (lhsc, rhsc);
1706 296565 : return true;
1707 : }
1708 74461 : case BUILT_IN_MEMSET:
1709 74461 : case BUILT_IN_MEMSET_CHK:
1710 74461 : case BUILT_IN_TM_MEMSET:
1711 74461 : {
1712 74461 : tree res = gimple_call_lhs (t);
1713 74461 : tree dest = gimple_call_arg (t, 0);
1714 74461 : unsigned i;
1715 74461 : ce_s *lhsp;
1716 74461 : struct constraint_expr ac;
1717 74461 : if (res != NULL_TREE)
1718 : {
1719 6144 : get_constraint_for (res, &lhsc);
1720 6144 : get_constraint_for (dest, &rhsc);
1721 6144 : process_all_all_constraints (lhsc, rhsc);
1722 6144 : lhsc.truncate (0);
1723 : }
1724 74461 : get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
1725 74461 : do_deref (&lhsc);
1726 74461 : if (flag_delete_null_pointer_checks
1727 148781 : && 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 74461 : ac.offset = 0;
1738 1469627 : FOR_EACH_VEC_ELT (lhsc, i, lhsp)
1739 80659 : process_constraint (new_constraint (*lhsp, ac));
1740 : return true;
1741 : }
1742 : case BUILT_IN_STACK_SAVE:
1743 : case BUILT_IN_STACK_RESTORE:
1744 : /* Nothing interesting happens. */
1745 : return true;
1746 33154 : case BUILT_IN_ALLOCA:
1747 33154 : case BUILT_IN_ALLOCA_WITH_ALIGN:
1748 33154 : case BUILT_IN_ALLOCA_WITH_ALIGN_AND_MAX:
1749 33154 : {
1750 33154 : tree ptr = gimple_call_lhs (t);
1751 33154 : if (ptr == NULL_TREE)
1752 : return true;
1753 33141 : get_constraint_for (ptr, &lhsc);
1754 33141 : 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 33141 : DECL_EXTERNAL (vi->decl) = 0;
1758 33141 : vi->is_global_var = 0;
1759 33141 : vi->is_heap_var = 0;
1760 33141 : struct constraint_expr tmpc;
1761 33141 : tmpc.var = vi->id;
1762 33141 : tmpc.offset = 0;
1763 33141 : tmpc.type = ADDRESSOF;
1764 33141 : rhsc.safe_push (tmpc);
1765 33141 : process_all_all_constraints (lhsc, rhsc);
1766 33141 : 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 1678 : case BUILT_IN_ASSUME_ALIGNED:
1787 1678 : {
1788 1678 : tree res = gimple_call_lhs (t);
1789 1678 : tree dest = gimple_call_arg (t, 0);
1790 1678 : if (res != NULL_TREE)
1791 : {
1792 1678 : get_constraint_for (res, &lhsc);
1793 1678 : get_constraint_for (dest, &rhsc);
1794 1678 : process_all_all_constraints (lhsc, rhsc);
1795 : }
1796 1678 : return true;
1797 : }
1798 : /* All the following functions do not return pointers, do not
1799 : modify the points-to sets of memory reachable from their
1800 : arguments and do not add to the ESCAPED solution. */
1801 : case BUILT_IN_SINCOS:
1802 : case BUILT_IN_SINCOSF:
1803 : case BUILT_IN_SINCOSL:
1804 : case BUILT_IN_FREXP:
1805 : case BUILT_IN_FREXPF:
1806 : case BUILT_IN_FREXPL:
1807 : case BUILT_IN_GAMMA_R:
1808 : case BUILT_IN_GAMMAF_R:
1809 : case BUILT_IN_GAMMAL_R:
1810 : case BUILT_IN_LGAMMA_R:
1811 : case BUILT_IN_LGAMMAF_R:
1812 : case BUILT_IN_LGAMMAL_R:
1813 : case BUILT_IN_MODF:
1814 : case BUILT_IN_MODFF:
1815 : case BUILT_IN_MODFL:
1816 : case BUILT_IN_REMQUO:
1817 : case BUILT_IN_REMQUOF:
1818 : case BUILT_IN_REMQUOL:
1819 : case BUILT_IN_FREE:
1820 : return true;
1821 16763 : case BUILT_IN_STRDUP:
1822 16763 : case BUILT_IN_STRNDUP:
1823 16763 : case BUILT_IN_REALLOC:
1824 16763 : if (gimple_call_lhs (t))
1825 : {
1826 16727 : auto_vec<ce_s> rhsc;
1827 16727 : handle_lhs_call (t, gimple_call_lhs (t),
1828 16727 : gimple_call_return_flags (t) | ERF_NOALIAS,
1829 : rhsc, fndecl);
1830 16727 : get_constraint_for_ptr_offset (gimple_call_lhs (t),
1831 : NULL_TREE, &lhsc);
1832 16727 : get_constraint_for_ptr_offset (gimple_call_arg (t, 0),
1833 : NULL_TREE, &rhsc);
1834 16727 : do_deref (&lhsc);
1835 16727 : do_deref (&rhsc);
1836 16727 : process_all_all_constraints (lhsc, rhsc);
1837 16727 : lhsc.truncate (0);
1838 16727 : 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 16727 : if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_REALLOC)
1843 : {
1844 15079 : get_constraint_for (gimple_call_lhs (t), &lhsc);
1845 15079 : get_constraint_for (gimple_call_arg (t, 0), &rhsc);
1846 15079 : process_all_all_constraints (lhsc, rhsc);
1847 : }
1848 16727 : return true;
1849 16727 : }
1850 : break;
1851 : /* String / character search functions return a pointer into the
1852 : source string or NULL. */
1853 13548 : case BUILT_IN_INDEX:
1854 13548 : case BUILT_IN_STRCHR:
1855 13548 : case BUILT_IN_STRRCHR:
1856 13548 : case BUILT_IN_MEMCHR:
1857 13548 : case BUILT_IN_STRSTR:
1858 13548 : case BUILT_IN_STRPBRK:
1859 13548 : if (gimple_call_lhs (t))
1860 : {
1861 13548 : tree src = gimple_call_arg (t, 0);
1862 13548 : get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
1863 13548 : constraint_expr nul;
1864 13548 : nul.var = nothing_id;
1865 13548 : nul.offset = 0;
1866 13548 : nul.type = ADDRESSOF;
1867 13548 : rhsc.safe_push (nul);
1868 13548 : get_constraint_for (gimple_call_lhs (t), &lhsc);
1869 13548 : process_all_all_constraints (lhsc, rhsc);
1870 : }
1871 13548 : 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 628811 : case BUILT_IN_STRCMP:
1876 628811 : case BUILT_IN_STRCMP_EQ:
1877 628811 : case BUILT_IN_STRNCMP:
1878 628811 : case BUILT_IN_STRNCMP_EQ:
1879 628811 : case BUILT_IN_STRCASECMP:
1880 628811 : case BUILT_IN_STRNCASECMP:
1881 628811 : case BUILT_IN_MEMCMP:
1882 628811 : case BUILT_IN_BCMP:
1883 628811 : case BUILT_IN_STRSPN:
1884 628811 : case BUILT_IN_STRCSPN:
1885 628811 : {
1886 628811 : varinfo_t uses = get_call_use_vi (t);
1887 628811 : make_any_offset_constraints (uses);
1888 628811 : make_constraint_to (uses->id, gimple_call_arg (t, 0));
1889 628811 : make_constraint_to (uses->id, gimple_call_arg (t, 1));
1890 : /* No constraints are necessary for the return value. */
1891 628811 : return true;
1892 : }
1893 46587 : case BUILT_IN_STRLEN:
1894 46587 : {
1895 46587 : varinfo_t uses = get_call_use_vi (t);
1896 46587 : make_any_offset_constraints (uses);
1897 46587 : make_constraint_to (uses->id, gimple_call_arg (t, 0));
1898 : /* No constraints are necessary for the return value. */
1899 46587 : return true;
1900 : }
1901 : case BUILT_IN_OBJECT_SIZE:
1902 : case BUILT_IN_CONSTANT_P:
1903 : {
1904 : /* No constraints are necessary for the return value or the
1905 : arguments. */
1906 : return true;
1907 : }
1908 : /* Trampolines are special - they set up passing the static
1909 : frame. */
1910 480 : case BUILT_IN_INIT_TRAMPOLINE:
1911 480 : {
1912 480 : tree tramp = gimple_call_arg (t, 0);
1913 480 : tree nfunc = gimple_call_arg (t, 1);
1914 480 : tree frame = gimple_call_arg (t, 2);
1915 480 : unsigned i;
1916 480 : struct constraint_expr lhs, *rhsp;
1917 480 : if (in_ipa_mode)
1918 : {
1919 7 : varinfo_t nfi = NULL;
1920 7 : gcc_assert (TREE_CODE (nfunc) == ADDR_EXPR);
1921 7 : nfi = lookup_vi_for_tree (TREE_OPERAND (nfunc, 0));
1922 7 : if (nfi)
1923 : {
1924 7 : lhs = get_function_part_constraint (nfi, fi_static_chain);
1925 7 : get_constraint_for (frame, &rhsc);
1926 21 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
1927 7 : process_constraint (new_constraint (lhs, *rhsp));
1928 7 : rhsc.truncate (0);
1929 :
1930 : /* Make the frame point to the function for
1931 : the trampoline adjustment call. */
1932 7 : get_constraint_for (tramp, &lhsc);
1933 7 : do_deref (&lhsc);
1934 7 : get_constraint_for (nfunc, &rhsc);
1935 7 : process_all_all_constraints (lhsc, rhsc);
1936 :
1937 7 : return true;
1938 : }
1939 : }
1940 : /* Else fallthru to generic handling which will let
1941 : the frame escape. */
1942 473 : break;
1943 : }
1944 517 : case BUILT_IN_ADJUST_TRAMPOLINE:
1945 517 : {
1946 517 : tree tramp = gimple_call_arg (t, 0);
1947 517 : tree res = gimple_call_lhs (t);
1948 517 : if (in_ipa_mode && res)
1949 : {
1950 7 : get_constraint_for (res, &lhsc);
1951 7 : get_constraint_for (tramp, &rhsc);
1952 7 : do_deref (&rhsc);
1953 7 : process_all_all_constraints (lhsc, rhsc);
1954 : }
1955 517 : return true;
1956 : }
1957 4 : CASE_BUILT_IN_TM_STORE (1):
1958 4 : CASE_BUILT_IN_TM_STORE (2):
1959 4 : CASE_BUILT_IN_TM_STORE (4):
1960 4 : CASE_BUILT_IN_TM_STORE (8):
1961 4 : CASE_BUILT_IN_TM_STORE (FLOAT):
1962 4 : CASE_BUILT_IN_TM_STORE (DOUBLE):
1963 4 : CASE_BUILT_IN_TM_STORE (LDOUBLE):
1964 4 : CASE_BUILT_IN_TM_STORE (M64):
1965 4 : CASE_BUILT_IN_TM_STORE (M128):
1966 4 : CASE_BUILT_IN_TM_STORE (M256):
1967 4 : {
1968 4 : tree addr = gimple_call_arg (t, 0);
1969 4 : tree src = gimple_call_arg (t, 1);
1970 :
1971 4 : get_constraint_for (addr, &lhsc);
1972 4 : do_deref (&lhsc);
1973 4 : get_constraint_for (src, &rhsc);
1974 4 : process_all_all_constraints (lhsc, rhsc);
1975 4 : return true;
1976 : }
1977 10 : CASE_BUILT_IN_TM_LOAD (1):
1978 10 : CASE_BUILT_IN_TM_LOAD (2):
1979 10 : CASE_BUILT_IN_TM_LOAD (4):
1980 10 : CASE_BUILT_IN_TM_LOAD (8):
1981 10 : CASE_BUILT_IN_TM_LOAD (FLOAT):
1982 10 : CASE_BUILT_IN_TM_LOAD (DOUBLE):
1983 10 : CASE_BUILT_IN_TM_LOAD (LDOUBLE):
1984 10 : CASE_BUILT_IN_TM_LOAD (M64):
1985 10 : CASE_BUILT_IN_TM_LOAD (M128):
1986 10 : CASE_BUILT_IN_TM_LOAD (M256):
1987 10 : {
1988 10 : tree dest = gimple_call_lhs (t);
1989 10 : tree addr = gimple_call_arg (t, 0);
1990 :
1991 10 : get_constraint_for (dest, &lhsc);
1992 10 : get_constraint_for (addr, &rhsc);
1993 10 : do_deref (&rhsc);
1994 10 : process_all_all_constraints (lhsc, rhsc);
1995 10 : return true;
1996 : }
1997 : /* Variadic argument handling needs to be handled in IPA
1998 : mode as well. */
1999 20040 : case BUILT_IN_VA_START:
2000 20040 : {
2001 20040 : tree valist = gimple_call_arg (t, 0);
2002 20040 : struct constraint_expr rhs, *lhsp;
2003 20040 : unsigned i;
2004 20040 : get_constraint_for_ptr_offset (valist, NULL_TREE, &lhsc);
2005 20040 : 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 20040 : if (in_ipa_mode)
2010 : {
2011 7 : fi = lookup_vi_for_tree (fn->decl);
2012 7 : rhs = get_function_part_constraint (fi, ~0);
2013 7 : rhs.type = ADDRESSOF;
2014 : }
2015 : else
2016 : {
2017 : rhs.var = nonlocal_id;
2018 : rhs.type = ADDRESSOF;
2019 : rhs.offset = 0;
2020 : }
2021 40251 : FOR_EACH_VEC_ELT (lhsc, i, lhsp)
2022 20211 : process_constraint (new_constraint (*lhsp, rhs));
2023 : /* va_list is clobbered. */
2024 20040 : make_constraint_to (get_call_clobber_vi (t)->id, valist);
2025 20040 : return true;
2026 : }
2027 : /* va_end doesn't have any effect that matters. */
2028 : case BUILT_IN_VA_END:
2029 : return true;
2030 : /* Alternate return. Simply give up for now. */
2031 940 : case BUILT_IN_RETURN:
2032 940 : {
2033 940 : fi = NULL;
2034 940 : if (!in_ipa_mode
2035 940 : || !(fi = get_vi_for_tree (fn->decl)))
2036 940 : make_constraint_from (get_varinfo (escaped_id), anything_id);
2037 0 : else if (in_ipa_mode
2038 : && fi != NULL)
2039 : {
2040 0 : struct constraint_expr lhs, rhs;
2041 0 : lhs = get_function_part_constraint (fi, fi_result);
2042 0 : rhs.var = anything_id;
2043 0 : rhs.offset = 0;
2044 0 : rhs.type = SCALAR;
2045 0 : process_constraint (new_constraint (lhs, rhs));
2046 : }
2047 940 : return true;
2048 : }
2049 55218 : case BUILT_IN_GOMP_PARALLEL:
2050 55218 : case BUILT_IN_GOACC_PARALLEL:
2051 55218 : {
2052 55218 : if (in_ipa_mode)
2053 : {
2054 14084 : unsigned int fnpos, argpos;
2055 14084 : 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 14071 : case BUILT_IN_GOACC_PARALLEL:
2063 : /* __builtin_GOACC_parallel (flags_m, fn, mapnum, hostaddrs,
2064 : sizes, kinds, ...). */
2065 14071 : fnpos = 1;
2066 14071 : argpos = 3;
2067 14071 : break;
2068 0 : default:
2069 0 : gcc_unreachable ();
2070 : }
2071 :
2072 14084 : tree fnarg = gimple_call_arg (t, fnpos);
2073 14084 : gcc_assert (TREE_CODE (fnarg) == ADDR_EXPR);
2074 14084 : tree fndecl = TREE_OPERAND (fnarg, 0);
2075 14084 : if (fndecl_maybe_in_other_partition (fndecl))
2076 : /* Fallthru to general call handling. */
2077 : break;
2078 :
2079 14041 : tree arg = gimple_call_arg (t, argpos);
2080 :
2081 14041 : varinfo_t fi = get_vi_for_tree (fndecl);
2082 14041 : find_func_aliases_for_call_arg (fi, 0, arg);
2083 14041 : 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 5069972 : }
2097 :
2098 : /* Create constraints for the call T. */
2099 :
2100 : static void
2101 17704846 : find_func_aliases_for_call (struct function *fn, gcall *t)
2102 : {
2103 17704846 : tree fndecl = gimple_call_fndecl (t);
2104 17704846 : varinfo_t fi;
2105 :
2106 17704846 : if (fndecl != NULL_TREE
2107 16483919 : && fndecl_built_in_p (fndecl)
2108 22774818 : && find_func_aliases_for_builtin_call (fn, t))
2109 : return;
2110 :
2111 16390339 : if (gimple_call_internal_p (t, IFN_DEFERRED_INIT))
2112 : return;
2113 :
2114 16234980 : fi = get_fi_for_callee (t);
2115 16234980 : if (!in_ipa_mode
2116 242517 : || (fi->decl && fndecl && !fi->is_fn_info))
2117 : {
2118 16047782 : auto_vec<ce_s, 16> rhsc;
2119 16047782 : int flags = gimple_call_flags (t);
2120 :
2121 : /* Const functions can return their arguments and addresses
2122 : of global memory but not of escaped memory. */
2123 16047782 : if (flags & (ECF_CONST|ECF_NOVOPS))
2124 : {
2125 1581391 : if (gimple_call_lhs (t))
2126 931426 : handle_rhs_call (t, &rhsc, implicit_const_eaf_flags, false, false);
2127 : }
2128 : /* Pure functions can return addresses in and of memory
2129 : reachable from their arguments, but they are not an escape
2130 : point for reachable memory of their arguments. */
2131 14466391 : else if (flags & (ECF_PURE|ECF_LOOPING_CONST_OR_PURE))
2132 541263 : handle_rhs_call (t, &rhsc, implicit_pure_eaf_flags, false, true);
2133 : /* If the call is to a replaceable operator delete and results
2134 : from a delete expression as opposed to a direct call to
2135 : such operator, then the effects for PTA (in particular
2136 : the escaping of the pointer) can be ignored. */
2137 13925128 : else if (fndecl
2138 13305830 : && DECL_IS_OPERATOR_DELETE_P (fndecl)
2139 14286188 : && gimple_call_from_new_or_delete (t))
2140 : ;
2141 : else
2142 13567835 : handle_rhs_call (t, &rhsc, 0, true, true);
2143 16047782 : if (gimple_call_lhs (t))
2144 5741308 : handle_lhs_call (t, gimple_call_lhs (t),
2145 : gimple_call_return_flags (t), rhsc, fndecl);
2146 16047782 : }
2147 : else
2148 : {
2149 187198 : auto_vec<ce_s, 2> rhsc;
2150 187198 : tree lhsop;
2151 187198 : unsigned j;
2152 :
2153 : /* Assign all the passed arguments to the appropriate incoming
2154 : parameters of the function. */
2155 997575 : for (j = 0; j < gimple_call_num_args (t); j++)
2156 : {
2157 810377 : tree arg = gimple_call_arg (t, j);
2158 810377 : find_func_aliases_for_call_arg (fi, j, arg);
2159 : }
2160 :
2161 : /* If we are returning a value, assign it to the result. */
2162 187198 : lhsop = gimple_call_lhs (t);
2163 187198 : if (lhsop)
2164 : {
2165 166813 : auto_vec<ce_s, 2> lhsc;
2166 166813 : struct constraint_expr rhs;
2167 166813 : struct constraint_expr *lhsp;
2168 167665 : bool aggr_p = aggregate_value_p (lhsop, gimple_call_fntype (t));
2169 :
2170 166813 : get_constraint_for (lhsop, &lhsc);
2171 166813 : rhs = get_function_part_constraint (fi, fi_result);
2172 166813 : if (aggr_p)
2173 : {
2174 10 : auto_vec<ce_s, 2> tem;
2175 10 : tem.quick_push (rhs);
2176 10 : do_deref (&tem);
2177 10 : gcc_checking_assert (tem.length () == 1);
2178 10 : rhs = tem[0];
2179 10 : }
2180 333629 : FOR_EACH_VEC_ELT (lhsc, j, lhsp)
2181 166816 : process_constraint (new_constraint (*lhsp, rhs));
2182 :
2183 : /* If we pass the result decl by reference, honor that. */
2184 166813 : if (aggr_p)
2185 : {
2186 10 : struct constraint_expr lhs;
2187 10 : struct constraint_expr *rhsp;
2188 :
2189 10 : get_constraint_for_address_of (lhsop, &rhsc);
2190 10 : lhs = get_function_part_constraint (fi, fi_result);
2191 30 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
2192 10 : process_constraint (new_constraint (lhs, *rhsp));
2193 10 : rhsc.truncate (0);
2194 : }
2195 166813 : }
2196 :
2197 : /* If we use a static chain, pass it along. */
2198 187198 : if (gimple_call_chain (t))
2199 : {
2200 278 : struct constraint_expr lhs;
2201 278 : struct constraint_expr *rhsp;
2202 :
2203 278 : get_constraint_for (gimple_call_chain (t), &rhsc);
2204 278 : lhs = get_function_part_constraint (fi, fi_static_chain);
2205 1112 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
2206 278 : process_constraint (new_constraint (lhs, *rhsp));
2207 : }
2208 187198 : }
2209 : }
2210 :
2211 : /* Walk statement T setting up aliasing constraints according to the
2212 : references found in T. This function is the main part of the
2213 : constraint builder. AI points to auxiliary alias information used
2214 : when building alias sets and computing alias grouping heuristics. */
2215 :
2216 : static void
2217 254500423 : find_func_aliases (struct function *fn, gimple *origt)
2218 : {
2219 254500423 : gimple *t = origt;
2220 254500423 : auto_vec<ce_s, 16> lhsc;
2221 254500423 : auto_vec<ce_s, 16> rhsc;
2222 254500423 : varinfo_t fi;
2223 :
2224 : /* Now build constraints expressions. */
2225 254500423 : if (gimple_code (t) == GIMPLE_PHI)
2226 : {
2227 : /* For a phi node, assign all the arguments to
2228 : the result. */
2229 6188308 : get_constraint_for (gimple_phi_result (t), &lhsc);
2230 21135874 : for (unsigned i = 0; i < gimple_phi_num_args (t); i++)
2231 : {
2232 14947566 : get_constraint_for_rhs (gimple_phi_arg_def (t, i), &rhsc);
2233 14947566 : process_all_all_constraints (lhsc, rhsc);
2234 14947566 : rhsc.truncate (0);
2235 : }
2236 : }
2237 : /* In IPA mode, we need to generate constraints to pass call
2238 : arguments through their calls. There are two cases,
2239 : either a GIMPLE_CALL returning a value, or just a plain
2240 : GIMPLE_CALL when we are not.
2241 :
2242 : In non-ipa mode, we need to generate constraints for each
2243 : pointer passed by address. */
2244 248312115 : else if (is_gimple_call (t))
2245 17704846 : find_func_aliases_for_call (fn, as_a <gcall *> (t));
2246 :
2247 : /* Otherwise, just a regular assignment statement. Only care about
2248 : operations with pointer result, others are dealt with as escape
2249 : points if they have pointer operands. */
2250 230607269 : else if (is_gimple_assign (t))
2251 : {
2252 : /* Otherwise, just a regular assignment statement. */
2253 78870532 : tree lhsop = gimple_assign_lhs (t);
2254 78870532 : tree rhsop = (gimple_num_ops (t) == 2) ? gimple_assign_rhs1 (t) : NULL;
2255 :
2256 61373529 : if (rhsop && TREE_CLOBBER_P (rhsop))
2257 : /* Ignore clobbers, they don't actually store anything into
2258 : the LHS. */
2259 : ;
2260 56412632 : else if (rhsop && AGGREGATE_TYPE_P (TREE_TYPE (lhsop)))
2261 2466022 : do_structure_copy (lhsop, rhsop);
2262 : else
2263 : {
2264 71443613 : enum tree_code code = gimple_assign_rhs_code (t);
2265 :
2266 71443613 : get_constraint_for (lhsop, &lhsc);
2267 :
2268 71443613 : if (code == POINTER_PLUS_EXPR)
2269 2656423 : get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
2270 : gimple_assign_rhs2 (t), &rhsc);
2271 68787190 : else if (code == POINTER_DIFF_EXPR)
2272 : /* The result is not a pointer (part). */
2273 : ;
2274 68449496 : else if (code == BIT_AND_EXPR
2275 68449496 : && TREE_CODE (gimple_assign_rhs2 (t)) == INTEGER_CST)
2276 : {
2277 : /* Aligning a pointer via a BIT_AND_EXPR is offsetting
2278 : the pointer. Handle it by offsetting it by UNKNOWN. */
2279 593356 : get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
2280 : NULL_TREE, &rhsc);
2281 : }
2282 67856140 : else if (code == TRUNC_DIV_EXPR
2283 : || code == CEIL_DIV_EXPR
2284 : || code == FLOOR_DIV_EXPR
2285 67856140 : || code == ROUND_DIV_EXPR
2286 67856140 : || code == EXACT_DIV_EXPR
2287 : || code == TRUNC_MOD_EXPR
2288 67490619 : || code == CEIL_MOD_EXPR
2289 : || code == FLOOR_MOD_EXPR
2290 67325566 : || code == ROUND_MOD_EXPR)
2291 : /* Division and modulo transfer the pointer from the LHS. */
2292 532133 : get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
2293 : NULL_TREE, &rhsc);
2294 67324007 : else if (CONVERT_EXPR_CODE_P (code)
2295 67324007 : || gimple_assign_single_p (t))
2296 : /* See through conversions, single RHS are handled by
2297 : get_constraint_for_rhs. */
2298 53257277 : get_constraint_for_rhs (rhsop, &rhsc);
2299 14066730 : else if (code == COND_EXPR)
2300 : {
2301 : /* The result is a merge of both COND_EXPR arms. */
2302 10820 : auto_vec<ce_s, 2> tmp;
2303 10820 : struct constraint_expr *rhsp;
2304 10820 : unsigned i;
2305 10820 : get_constraint_for_rhs (gimple_assign_rhs2 (t), &rhsc);
2306 10820 : get_constraint_for_rhs (gimple_assign_rhs3 (t), &tmp);
2307 43280 : FOR_EACH_VEC_ELT (tmp, i, rhsp)
2308 10820 : rhsc.safe_push (*rhsp);
2309 10820 : }
2310 14055910 : else if (truth_value_p (code))
2311 : /* Truth value results are not pointer (parts). Or at least
2312 : very unreasonable obfuscation of a part. */
2313 : ;
2314 : else
2315 : {
2316 : /* All other operations are possibly offsetting merges. */
2317 12687331 : auto_vec<ce_s, 4> tmp;
2318 12687331 : struct constraint_expr *rhsp;
2319 12687331 : unsigned i, j;
2320 12687331 : get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
2321 : NULL_TREE, &rhsc);
2322 37460942 : for (i = 2; i < gimple_num_ops (t); ++i)
2323 : {
2324 12086280 : get_constraint_for_ptr_offset (gimple_op (t, i),
2325 : NULL_TREE, &tmp);
2326 36258840 : FOR_EACH_VEC_ELT (tmp, j, rhsp)
2327 12086280 : rhsc.safe_push (*rhsp);
2328 12086280 : tmp.truncate (0);
2329 : }
2330 12687331 : }
2331 71443613 : process_all_all_constraints (lhsc, rhsc);
2332 : }
2333 : /* If there is a store to a global variable the rhs escapes. */
2334 78870532 : if ((lhsop = get_base_address (lhsop)) != NULL_TREE
2335 78870532 : && DECL_P (lhsop))
2336 : {
2337 21671738 : varinfo_t vi = get_vi_for_tree (lhsop);
2338 21671738 : if ((! in_ipa_mode && vi->is_global_var)
2339 20053933 : || vi->is_ipa_escape_point)
2340 1620371 : make_escape_constraint (rhsop);
2341 : }
2342 : }
2343 : /* Handle escapes through return. */
2344 151736737 : else if (gimple_code (t) == GIMPLE_RETURN
2345 151736737 : && gimple_return_retval (as_a <greturn *> (t)) != NULL_TREE)
2346 : {
2347 2449456 : greturn *return_stmt = as_a <greturn *> (t);
2348 2449456 : tree retval = gimple_return_retval (return_stmt);
2349 2449456 : if (!in_ipa_mode)
2350 2445198 : make_constraint_to (escaped_return_id, retval);
2351 : else
2352 : {
2353 4258 : struct constraint_expr lhs ;
2354 4258 : struct constraint_expr *rhsp;
2355 4258 : unsigned i;
2356 :
2357 4258 : fi = lookup_vi_for_tree (fn->decl);
2358 4258 : lhs = get_function_part_constraint (fi, fi_result);
2359 4258 : get_constraint_for_rhs (retval, &rhsc);
2360 17032 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
2361 4258 : process_constraint (new_constraint (lhs, *rhsp));
2362 : }
2363 : }
2364 : /* Handle asms conservatively by adding escape constraints to everything. */
2365 254743151 : else if (gasm *asm_stmt = dyn_cast <gasm *> (t))
2366 : {
2367 242728 : unsigned i, noutputs;
2368 242728 : const char **oconstraints;
2369 242728 : const char *constraint;
2370 242728 : bool allows_mem, allows_reg, is_inout;
2371 :
2372 242728 : noutputs = gimple_asm_noutputs (asm_stmt);
2373 242728 : oconstraints = XALLOCAVEC (const char *, noutputs);
2374 :
2375 479837 : for (i = 0; i < noutputs; ++i)
2376 : {
2377 237109 : tree link = gimple_asm_output_op (asm_stmt, i);
2378 237109 : tree op = TREE_VALUE (link);
2379 :
2380 237109 : constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
2381 237109 : oconstraints[i] = constraint;
2382 237109 : parse_output_constraint (&constraint, i, 0, 0, &allows_mem,
2383 : &allows_reg, &is_inout, nullptr);
2384 :
2385 : /* A memory constraint makes the address of the operand escape. */
2386 237109 : if (!allows_reg && allows_mem)
2387 : {
2388 12887 : auto_vec<ce_s> tmpc;
2389 12887 : get_constraint_for_address_of (op, &tmpc);
2390 12887 : make_constraints_to (escaped_id, tmpc);
2391 12887 : }
2392 :
2393 : /* The asm may read global memory, so outputs may point to
2394 : any global memory. */
2395 237109 : if (op)
2396 : {
2397 237109 : auto_vec<ce_s, 2> lhsc;
2398 237109 : struct constraint_expr rhsc, *lhsp;
2399 237109 : unsigned j;
2400 237109 : get_constraint_for (op, &lhsc);
2401 237109 : rhsc.var = nonlocal_id;
2402 237109 : rhsc.offset = 0;
2403 237109 : rhsc.type = SCALAR;
2404 948439 : FOR_EACH_VEC_ELT (lhsc, j, lhsp)
2405 237112 : process_constraint (new_constraint (*lhsp, rhsc));
2406 237109 : }
2407 : }
2408 391024 : for (i = 0; i < gimple_asm_ninputs (asm_stmt); ++i)
2409 : {
2410 148296 : tree link = gimple_asm_input_op (asm_stmt, i);
2411 148296 : tree op = TREE_VALUE (link);
2412 :
2413 148296 : constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
2414 :
2415 148296 : parse_input_constraint (&constraint, 0, 0, noutputs, 0, oconstraints,
2416 : &allows_mem, &allows_reg, nullptr);
2417 :
2418 : /* A memory constraint makes the address of the operand escape. */
2419 148296 : if (!allows_reg && allows_mem)
2420 : {
2421 14013 : auto_vec<ce_s> tmpc;
2422 14013 : get_constraint_for_address_of (op, &tmpc);
2423 14013 : make_constraints_to (escaped_id, tmpc);
2424 14013 : }
2425 : /* Strictly we'd only need the constraint to ESCAPED if
2426 : the asm clobbers memory, otherwise using something
2427 : along the lines of per-call clobbers/uses would be enough. */
2428 134283 : else if (op)
2429 134283 : make_escape_constraint (op);
2430 : }
2431 : }
2432 254500423 : }
2433 :
2434 :
2435 : /* Create a constraint adding to the clobber set of FI the memory
2436 : pointed to by PTR. */
2437 :
2438 : static void
2439 0 : process_ipa_clobber (varinfo_t fi, tree ptr)
2440 : {
2441 0 : vec<ce_s> ptrc = vNULL;
2442 0 : struct constraint_expr *c, lhs;
2443 0 : unsigned i;
2444 0 : get_constraint_for_rhs (ptr, &ptrc);
2445 0 : lhs = get_function_part_constraint (fi, fi_clobbers);
2446 0 : FOR_EACH_VEC_ELT (ptrc, i, c)
2447 0 : process_constraint (new_constraint (lhs, *c));
2448 0 : ptrc.release ();
2449 0 : }
2450 :
2451 : /* Walk statement T setting up clobber and use constraints according to the
2452 : references found in T. This function is a main part of the
2453 : IPA constraint builder. */
2454 :
2455 : static void
2456 974312 : find_func_clobbers (struct function *fn, gimple *origt)
2457 : {
2458 974312 : gimple *t = origt;
2459 974312 : auto_vec<ce_s, 16> lhsc;
2460 974312 : auto_vec<ce_s, 16> rhsc;
2461 974312 : varinfo_t fi;
2462 :
2463 : /* Add constraints for clobbered/used in IPA mode.
2464 : We are not interested in what automatic variables are clobbered
2465 : or used as we only use the information in the caller to which
2466 : they do not escape. */
2467 974312 : gcc_assert (in_ipa_mode);
2468 :
2469 : /* If the stmt refers to memory in any way it better had a VUSE. */
2470 2081282 : if (gimple_vuse (t) == NULL_TREE)
2471 : return;
2472 :
2473 : /* We'd better have function information for the current function. */
2474 640776 : fi = lookup_vi_for_tree (fn->decl);
2475 640776 : gcc_assert (fi != NULL);
2476 :
2477 : /* Account for stores in assignments and calls. */
2478 640776 : if (gimple_vdef (t) != NULL_TREE
2479 1181949 : && gimple_has_lhs (t))
2480 : {
2481 339161 : tree lhs = gimple_get_lhs (t);
2482 339161 : tree tem = lhs;
2483 856378 : while (handled_component_p (tem))
2484 178056 : tem = TREE_OPERAND (tem, 0);
2485 339161 : if ((DECL_P (tem)
2486 193374 : && !auto_var_in_fn_p (tem, fn->decl))
2487 333992 : || INDIRECT_REF_P (tem)
2488 673153 : || (TREE_CODE (tem) == MEM_REF
2489 30033 : && !(TREE_CODE (TREE_OPERAND (tem, 0)) == ADDR_EXPR
2490 : && auto_var_in_fn_p
2491 4170 : (TREE_OPERAND (TREE_OPERAND (tem, 0), 0), fn->decl))))
2492 : {
2493 27756 : struct constraint_expr lhsc, *rhsp;
2494 27756 : unsigned i;
2495 27756 : lhsc = get_function_part_constraint (fi, fi_clobbers);
2496 27756 : get_constraint_for_address_of (lhs, &rhsc);
2497 83268 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
2498 27756 : process_constraint (new_constraint (lhsc, *rhsp));
2499 27756 : rhsc.truncate (0);
2500 : }
2501 : }
2502 :
2503 : /* Account for uses in assigments and returns. */
2504 640776 : if (gimple_assign_single_p (t)
2505 640776 : || (gimple_code (t) == GIMPLE_RETURN
2506 23320 : && gimple_return_retval (as_a <greturn *> (t)) != NULL_TREE))
2507 : {
2508 365387 : tree rhs = (gimple_assign_single_p (t)
2509 365387 : ? gimple_assign_rhs1 (t)
2510 4258 : : gimple_return_retval (as_a <greturn *> (t)));
2511 365387 : tree tem = rhs;
2512 521288 : while (handled_component_p (tem))
2513 155901 : tem = TREE_OPERAND (tem, 0);
2514 365387 : if ((DECL_P (tem)
2515 53635 : && !auto_var_in_fn_p (tem, fn->decl))
2516 356644 : || INDIRECT_REF_P (tem)
2517 722031 : || (TREE_CODE (tem) == MEM_REF
2518 90067 : && !(TREE_CODE (TREE_OPERAND (tem, 0)) == ADDR_EXPR
2519 : && auto_var_in_fn_p
2520 1224 : (TREE_OPERAND (TREE_OPERAND (tem, 0), 0), fn->decl))))
2521 : {
2522 96954 : struct constraint_expr lhs, *rhsp;
2523 96954 : unsigned i;
2524 96954 : lhs = get_function_part_constraint (fi, fi_uses);
2525 96954 : get_constraint_for_address_of (rhs, &rhsc);
2526 290862 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
2527 96954 : process_constraint (new_constraint (lhs, *rhsp));
2528 96954 : rhsc.truncate (0);
2529 : }
2530 : }
2531 :
2532 640776 : if (gcall *call_stmt = dyn_cast <gcall *> (t))
2533 : {
2534 256285 : varinfo_t cfi = NULL;
2535 256285 : tree decl = gimple_call_fndecl (t);
2536 256285 : struct constraint_expr lhs, rhs;
2537 256285 : unsigned i, j;
2538 :
2539 : /* For builtins we do not have separate function info. For those
2540 : we do not generate escapes for we have to generate clobbers/uses. */
2541 256285 : if (gimple_call_builtin_p (t, BUILT_IN_NORMAL))
2542 37762 : switch (DECL_FUNCTION_CODE (decl))
2543 : {
2544 : /* The following functions use and clobber memory pointed to
2545 : by their arguments. */
2546 162 : case BUILT_IN_STRCPY:
2547 162 : case BUILT_IN_STRNCPY:
2548 162 : case BUILT_IN_BCOPY:
2549 162 : case BUILT_IN_MEMCPY:
2550 162 : case BUILT_IN_MEMMOVE:
2551 162 : case BUILT_IN_MEMPCPY:
2552 162 : case BUILT_IN_STPCPY:
2553 162 : case BUILT_IN_STPNCPY:
2554 162 : case BUILT_IN_STRCAT:
2555 162 : case BUILT_IN_STRNCAT:
2556 162 : case BUILT_IN_STRCPY_CHK:
2557 162 : case BUILT_IN_STRNCPY_CHK:
2558 162 : case BUILT_IN_MEMCPY_CHK:
2559 162 : case BUILT_IN_MEMMOVE_CHK:
2560 162 : case BUILT_IN_MEMPCPY_CHK:
2561 162 : case BUILT_IN_STPCPY_CHK:
2562 162 : case BUILT_IN_STPNCPY_CHK:
2563 162 : case BUILT_IN_STRCAT_CHK:
2564 162 : case BUILT_IN_STRNCAT_CHK:
2565 162 : {
2566 324 : tree dest = gimple_call_arg (t, (DECL_FUNCTION_CODE (decl)
2567 : == BUILT_IN_BCOPY ? 1 : 0));
2568 324 : tree src = gimple_call_arg (t, (DECL_FUNCTION_CODE (decl)
2569 162 : == BUILT_IN_BCOPY ? 0 : 1));
2570 162 : unsigned i;
2571 162 : struct constraint_expr *rhsp, *lhsp;
2572 162 : get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
2573 162 : lhs = get_function_part_constraint (fi, fi_clobbers);
2574 486 : FOR_EACH_VEC_ELT (lhsc, i, lhsp)
2575 162 : process_constraint (new_constraint (lhs, *lhsp));
2576 162 : get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
2577 162 : lhs = get_function_part_constraint (fi, fi_uses);
2578 486 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
2579 162 : process_constraint (new_constraint (lhs, *rhsp));
2580 : return;
2581 : }
2582 : /* The following function clobbers memory pointed to by
2583 : its argument. */
2584 890 : case BUILT_IN_MEMSET:
2585 890 : case BUILT_IN_MEMSET_CHK:
2586 890 : case BUILT_IN_POSIX_MEMALIGN:
2587 890 : {
2588 890 : tree dest = gimple_call_arg (t, 0);
2589 890 : unsigned i;
2590 890 : ce_s *lhsp;
2591 890 : get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
2592 890 : lhs = get_function_part_constraint (fi, fi_clobbers);
2593 2670 : FOR_EACH_VEC_ELT (lhsc, i, lhsp)
2594 890 : process_constraint (new_constraint (lhs, *lhsp));
2595 : return;
2596 : }
2597 : /* The following functions clobber their second and third
2598 : arguments. */
2599 0 : case BUILT_IN_SINCOS:
2600 0 : case BUILT_IN_SINCOSF:
2601 0 : case BUILT_IN_SINCOSL:
2602 0 : {
2603 0 : process_ipa_clobber (fi, gimple_call_arg (t, 1));
2604 0 : process_ipa_clobber (fi, gimple_call_arg (t, 2));
2605 0 : return;
2606 : }
2607 : /* The following functions clobber their second argument. */
2608 0 : case BUILT_IN_FREXP:
2609 0 : case BUILT_IN_FREXPF:
2610 0 : case BUILT_IN_FREXPL:
2611 0 : case BUILT_IN_LGAMMA_R:
2612 0 : case BUILT_IN_LGAMMAF_R:
2613 0 : case BUILT_IN_LGAMMAL_R:
2614 0 : case BUILT_IN_GAMMA_R:
2615 0 : case BUILT_IN_GAMMAF_R:
2616 0 : case BUILT_IN_GAMMAL_R:
2617 0 : case BUILT_IN_MODF:
2618 0 : case BUILT_IN_MODFF:
2619 0 : case BUILT_IN_MODFL:
2620 0 : {
2621 0 : process_ipa_clobber (fi, gimple_call_arg (t, 1));
2622 0 : return;
2623 : }
2624 : /* The following functions clobber their third argument. */
2625 0 : case BUILT_IN_REMQUO:
2626 0 : case BUILT_IN_REMQUOF:
2627 0 : case BUILT_IN_REMQUOL:
2628 0 : {
2629 0 : process_ipa_clobber (fi, gimple_call_arg (t, 2));
2630 0 : return;
2631 : }
2632 : /* The following functions use what their first argument
2633 : points to. */
2634 60 : case BUILT_IN_STRDUP:
2635 60 : case BUILT_IN_STRNDUP:
2636 60 : case BUILT_IN_REALLOC:
2637 60 : case BUILT_IN_INDEX:
2638 60 : case BUILT_IN_STRCHR:
2639 60 : case BUILT_IN_STRRCHR:
2640 60 : case BUILT_IN_MEMCHR:
2641 60 : {
2642 60 : tree src = gimple_call_arg (t, 0);
2643 60 : get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
2644 60 : lhs = get_function_part_constraint (fi, fi_uses);
2645 60 : struct constraint_expr *rhsp;
2646 180 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
2647 60 : process_constraint (new_constraint (lhs, *rhsp));
2648 : return;
2649 : }
2650 : /* The following functions use what their first and second argument
2651 : point to. */
2652 16 : case BUILT_IN_STRSTR:
2653 16 : case BUILT_IN_STRPBRK:
2654 16 : {
2655 16 : tree src = gimple_call_arg (t, 0);
2656 16 : get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
2657 16 : lhs = get_function_part_constraint (fi, fi_uses);
2658 16 : struct constraint_expr *rhsp;
2659 48 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
2660 16 : process_constraint (new_constraint (lhs, *rhsp));
2661 16 : rhsc.truncate (0);
2662 16 : src = gimple_call_arg (t, 1);
2663 16 : get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
2664 249603 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
2665 16 : process_constraint (new_constraint (lhs, *rhsp));
2666 : return;
2667 : }
2668 : /* The following functions neither read nor clobber memory. */
2669 : case BUILT_IN_ASSUME_ALIGNED:
2670 : case BUILT_IN_FREE:
2671 : return;
2672 : /* Trampolines are of no interest to us. */
2673 : case BUILT_IN_INIT_TRAMPOLINE:
2674 : case BUILT_IN_ADJUST_TRAMPOLINE:
2675 : return;
2676 : case BUILT_IN_VA_START:
2677 : case BUILT_IN_VA_END:
2678 : return;
2679 14084 : case BUILT_IN_GOMP_PARALLEL:
2680 14084 : case BUILT_IN_GOACC_PARALLEL:
2681 14084 : {
2682 14084 : unsigned int fnpos, argpos;
2683 14084 : unsigned int implicit_use_args[2];
2684 14084 : unsigned int num_implicit_use_args = 0;
2685 14084 : switch (DECL_FUNCTION_CODE (decl))
2686 : {
2687 : case BUILT_IN_GOMP_PARALLEL:
2688 : /* __builtin_GOMP_parallel (fn, data, num_threads, flags). */
2689 : fnpos = 0;
2690 : argpos = 1;
2691 : break;
2692 14071 : case BUILT_IN_GOACC_PARALLEL:
2693 : /* __builtin_GOACC_parallel (flags_m, fn, mapnum, hostaddrs,
2694 : sizes, kinds, ...). */
2695 14071 : fnpos = 1;
2696 14071 : argpos = 3;
2697 14071 : implicit_use_args[num_implicit_use_args++] = 4;
2698 14071 : implicit_use_args[num_implicit_use_args++] = 5;
2699 14071 : break;
2700 0 : default:
2701 0 : gcc_unreachable ();
2702 : }
2703 :
2704 14084 : tree fnarg = gimple_call_arg (t, fnpos);
2705 14084 : gcc_assert (TREE_CODE (fnarg) == ADDR_EXPR);
2706 14084 : tree fndecl = TREE_OPERAND (fnarg, 0);
2707 14084 : if (fndecl_maybe_in_other_partition (fndecl))
2708 : /* Fallthru to general call handling. */
2709 : break;
2710 :
2711 14041 : varinfo_t cfi = get_vi_for_tree (fndecl);
2712 :
2713 14041 : tree arg = gimple_call_arg (t, argpos);
2714 :
2715 : /* Parameter passed by value is used. */
2716 14041 : lhs = get_function_part_constraint (fi, fi_uses);
2717 14041 : struct constraint_expr *rhsp;
2718 14041 : get_constraint_for (arg, &rhsc);
2719 42123 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
2720 14041 : process_constraint (new_constraint (lhs, *rhsp));
2721 14041 : rhsc.truncate (0);
2722 :
2723 : /* Handle parameters used by the call, but not used in cfi, as
2724 : implicitly used by cfi. */
2725 14041 : lhs = get_function_part_constraint (cfi, fi_uses);
2726 42103 : for (unsigned i = 0; i < num_implicit_use_args; ++i)
2727 : {
2728 28062 : tree arg = gimple_call_arg (t, implicit_use_args[i]);
2729 28062 : get_constraint_for (arg, &rhsc);
2730 84186 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
2731 28062 : process_constraint (new_constraint (lhs, *rhsp));
2732 28062 : rhsc.truncate (0);
2733 : }
2734 :
2735 : /* The caller clobbers what the callee does. */
2736 14041 : lhs = get_function_part_constraint (fi, fi_clobbers);
2737 14041 : rhs = get_function_part_constraint (cfi, fi_clobbers);
2738 14041 : process_constraint (new_constraint (lhs, rhs));
2739 :
2740 : /* The caller uses what the callee does. */
2741 14041 : lhs = get_function_part_constraint (fi, fi_uses);
2742 14041 : rhs = get_function_part_constraint (cfi, fi_uses);
2743 14041 : process_constraint (new_constraint (lhs, rhs));
2744 :
2745 14041 : return;
2746 : }
2747 : /* printf-style functions may have hooks to set pointers to
2748 : point to somewhere into the generated string. Leave them
2749 : for a later exercise... */
2750 : default:
2751 : /* Fallthru to general call handling. */;
2752 : }
2753 :
2754 : /* Parameters passed by value are used. */
2755 239186 : lhs = get_function_part_constraint (fi, fi_uses);
2756 1172205 : for (i = 0; i < gimple_call_num_args (t); i++)
2757 : {
2758 933019 : struct constraint_expr *rhsp;
2759 933019 : tree arg = gimple_call_arg (t, i);
2760 :
2761 1845014 : if (TREE_CODE (arg) == SSA_NAME
2762 933019 : || is_gimple_min_invariant (arg))
2763 911995 : continue;
2764 :
2765 21024 : get_constraint_for_address_of (arg, &rhsc);
2766 63073 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
2767 21025 : process_constraint (new_constraint (lhs, *rhsp));
2768 21024 : rhsc.truncate (0);
2769 : }
2770 :
2771 : /* Build constraints for propagating clobbers/uses along the
2772 : callgraph edges. */
2773 239186 : cfi = get_fi_for_callee (call_stmt);
2774 239186 : if (cfi->id == anything_id)
2775 : {
2776 356584 : if (gimple_vdef (t))
2777 125192 : make_constraint_from (first_vi_for_offset (fi, fi_clobbers),
2778 : anything_id);
2779 178292 : make_constraint_from (first_vi_for_offset (fi, fi_uses),
2780 : anything_id);
2781 178292 : return;
2782 : }
2783 :
2784 : /* For callees without function info (that's external functions),
2785 : ESCAPED is clobbered and used. */
2786 60894 : if (cfi->decl
2787 60893 : && TREE_CODE (cfi->decl) == FUNCTION_DECL
2788 60215 : && !cfi->is_fn_info)
2789 : {
2790 54164 : varinfo_t vi;
2791 :
2792 108328 : if (gimple_vdef (t))
2793 53979 : make_copy_constraint (first_vi_for_offset (fi, fi_clobbers),
2794 : escaped_id);
2795 54164 : make_copy_constraint (first_vi_for_offset (fi, fi_uses), escaped_id);
2796 :
2797 : /* Also honor the call statement use/clobber info. */
2798 54164 : if ((vi = lookup_call_clobber_vi (call_stmt)) != NULL)
2799 53880 : make_copy_constraint (first_vi_for_offset (fi, fi_clobbers),
2800 53880 : vi->id);
2801 54164 : if ((vi = lookup_call_use_vi (call_stmt)) != NULL)
2802 53880 : make_copy_constraint (first_vi_for_offset (fi, fi_uses),
2803 53880 : vi->id);
2804 54164 : return;
2805 : }
2806 :
2807 : /* Otherwise the caller clobbers and uses what the callee does.
2808 : ??? This should use a new complex constraint that filters
2809 : local variables of the callee. */
2810 13460 : if (gimple_vdef (t))
2811 : {
2812 5716 : lhs = get_function_part_constraint (fi, fi_clobbers);
2813 5716 : rhs = get_function_part_constraint (cfi, fi_clobbers);
2814 5716 : process_constraint (new_constraint (lhs, rhs));
2815 : }
2816 6730 : lhs = get_function_part_constraint (fi, fi_uses);
2817 6730 : rhs = get_function_part_constraint (cfi, fi_uses);
2818 6730 : process_constraint (new_constraint (lhs, rhs));
2819 : }
2820 384491 : else if (gimple_code (t) == GIMPLE_ASM)
2821 : {
2822 : /* ??? Ick. We can do better. */
2823 42 : if (gimple_vdef (t))
2824 42 : make_constraint_from (first_vi_for_offset (fi, fi_clobbers),
2825 : anything_id);
2826 42 : make_constraint_from (first_vi_for_offset (fi, fi_uses),
2827 : anything_id);
2828 : }
2829 974312 : }
2830 :
2831 :
2832 : /* This structure is used during pushing fields onto the fieldstack
2833 : to track the offset of the field, since bitpos_of_field gives it
2834 : relative to its immediate containing type, and we want it relative
2835 : to the ultimate containing object. */
2836 :
2837 : struct fieldoff
2838 : {
2839 : /* Offset from the base of the base containing object to this field. */
2840 : HOST_WIDE_INT offset;
2841 :
2842 : /* Size, in bits, of the field. */
2843 : unsigned HOST_WIDE_INT size;
2844 :
2845 : unsigned has_unknown_size : 1;
2846 :
2847 : unsigned must_have_pointers : 1;
2848 :
2849 : unsigned may_have_pointers : 1;
2850 :
2851 : unsigned only_restrict_pointers : 1;
2852 :
2853 : tree restrict_pointed_type;
2854 : };
2855 : typedef struct fieldoff fieldoff_s;
2856 :
2857 :
2858 : /* qsort comparison function for two fieldoff's PA and PB. */
2859 :
2860 : static int
2861 185115398 : fieldoff_compare (const void *pa, const void *pb)
2862 : {
2863 185115398 : const fieldoff_s *foa = (const fieldoff_s *)pa;
2864 185115398 : const fieldoff_s *fob = (const fieldoff_s *)pb;
2865 185115398 : unsigned HOST_WIDE_INT foasize, fobsize;
2866 :
2867 185115398 : if (foa->offset < fob->offset)
2868 : return -1;
2869 96475570 : else if (foa->offset > fob->offset)
2870 : return 1;
2871 :
2872 1192842 : foasize = foa->size;
2873 1192842 : fobsize = fob->size;
2874 1192842 : if (foasize < fobsize)
2875 : return -1;
2876 1002963 : else if (foasize > fobsize)
2877 112336 : return 1;
2878 : return 0;
2879 : }
2880 :
2881 : /* Sort a fieldstack according to the field offset and sizes. */
2882 : static void
2883 7326074 : sort_fieldstack (vec<fieldoff_s> &fieldstack)
2884 : {
2885 7326074 : fieldstack.qsort (fieldoff_compare);
2886 7326074 : }
2887 :
2888 : /* Return true if T is a type that can have subvars. */
2889 :
2890 : static inline bool
2891 64577963 : type_can_have_subvars (const_tree t)
2892 : {
2893 : /* Aggregates without overlapping fields can have subvars. */
2894 5781673 : return TREE_CODE (t) == RECORD_TYPE;
2895 : }
2896 :
2897 : /* Return true if V is a tree that we can have subvars for.
2898 : Normally, this is any aggregate type. Also complex
2899 : types which are not gimple registers can have subvars. */
2900 :
2901 : static inline bool
2902 118695216 : var_can_have_subvars (const_tree v)
2903 : {
2904 : /* Volatile variables should never have subvars. */
2905 118695216 : if (TREE_THIS_VOLATILE (v))
2906 : return false;
2907 :
2908 : /* Non decls or memory tags can never have subvars. */
2909 118400991 : if (!DECL_P (v))
2910 : return false;
2911 :
2912 58796290 : return type_can_have_subvars (TREE_TYPE (v));
2913 : }
2914 :
2915 : /* Return true if T is a type that does contain pointers. */
2916 :
2917 : static bool
2918 33112357 : type_must_have_pointers (tree type)
2919 : {
2920 33857057 : if (POINTER_TYPE_P (type))
2921 : return true;
2922 :
2923 19011957 : if (TREE_CODE (type) == ARRAY_TYPE)
2924 744700 : return type_must_have_pointers (TREE_TYPE (type));
2925 :
2926 : /* A function or method can have pointers as arguments, so track
2927 : those separately. */
2928 18267257 : if (FUNC_OR_METHOD_TYPE_P (type))
2929 0 : return true;
2930 :
2931 : return false;
2932 : }
2933 :
2934 : static bool
2935 33112357 : field_must_have_pointers (tree t)
2936 : {
2937 33112357 : return type_must_have_pointers (TREE_TYPE (t));
2938 : }
2939 :
2940 : /* Given a TYPE, and a vector of field offsets FIELDSTACK, push all
2941 : the fields of TYPE onto fieldstack, recording their offsets along
2942 : the way.
2943 :
2944 : OFFSET is used to keep track of the offset in this entire
2945 : structure, rather than just the immediately containing structure.
2946 : Returns false if the caller is supposed to handle the field we
2947 : recursed for. */
2948 :
2949 : static bool
2950 13639852 : push_fields_onto_fieldstack (tree type, vec<fieldoff_s> *fieldstack,
2951 : unsigned HOST_WIDE_INT offset)
2952 : {
2953 13639852 : tree field;
2954 13639852 : bool empty_p = true;
2955 :
2956 13639852 : if (TREE_CODE (type) != RECORD_TYPE)
2957 : return false;
2958 :
2959 : /* If the vector of fields is growing too big, bail out early.
2960 : Callers check for vec::length <= param_max_fields_for_field_sensitive, make
2961 : sure this fails. */
2962 13639852 : if (fieldstack->length () > (unsigned)param_max_fields_for_field_sensitive)
2963 : return false;
2964 :
2965 300538346 : for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
2966 287086447 : if (TREE_CODE (field) == FIELD_DECL)
2967 : {
2968 39187803 : bool push = false;
2969 39187803 : unsigned HOST_WIDE_INT foff = bitpos_of_field (field);
2970 39187803 : tree field_type = TREE_TYPE (field);
2971 :
2972 39187803 : if (!var_can_have_subvars (field)
2973 6282704 : || TREE_CODE (field_type) == QUAL_UNION_TYPE
2974 45470507 : || TREE_CODE (field_type) == UNION_TYPE)
2975 : push = true;
2976 6282704 : else if (!push_fields_onto_fieldstack
2977 6282704 : (field_type, fieldstack, offset + foff)
2978 6282704 : && (DECL_SIZE (field)
2979 1091115 : && !integer_zerop (DECL_SIZE (field))))
2980 : /* Empty structures may have actual size, like in C++. So
2981 : see if we didn't push any subfields and the size is
2982 : nonzero, push the field onto the stack. */
2983 : push = true;
2984 :
2985 : if (push)
2986 : {
2987 33112357 : fieldoff_s *pair = NULL;
2988 33112357 : bool has_unknown_size = false;
2989 33112357 : bool must_have_pointers_p;
2990 :
2991 33112357 : if (!fieldstack->is_empty ())
2992 26008452 : pair = &fieldstack->last ();
2993 :
2994 : /* If there isn't anything at offset zero, create sth. */
2995 26008452 : if (!pair
2996 7103905 : && offset + foff != 0)
2997 : {
2998 8388 : fieldoff_s e
2999 8388 : = {0, offset + foff, false, false, true, false, NULL_TREE};
3000 8388 : pair = fieldstack->safe_push (e);
3001 : }
3002 :
3003 33112357 : if (!DECL_SIZE (field)
3004 33112357 : || !tree_fits_uhwi_p (DECL_SIZE (field)))
3005 : has_unknown_size = true;
3006 :
3007 : /* If adjacent fields do not contain pointers merge them. */
3008 33112357 : must_have_pointers_p = field_must_have_pointers (field);
3009 33112357 : if (pair
3010 33112357 : && !has_unknown_size
3011 25985818 : && !must_have_pointers_p
3012 16188088 : && !pair->must_have_pointers
3013 11563356 : && !pair->has_unknown_size
3014 11563353 : && pair->offset + pair->size == offset + foff)
3015 : {
3016 11013645 : pair->size += tree_to_uhwi (DECL_SIZE (field));
3017 : }
3018 : else
3019 : {
3020 22098712 : fieldoff_s e;
3021 22098712 : e.offset = offset + foff;
3022 22098712 : e.has_unknown_size = has_unknown_size;
3023 22098712 : if (!has_unknown_size)
3024 22067638 : e.size = tree_to_uhwi (DECL_SIZE (field));
3025 : else
3026 31074 : e.size = -1;
3027 22098712 : e.must_have_pointers = must_have_pointers_p;
3028 22098712 : e.may_have_pointers = true;
3029 22098712 : e.only_restrict_pointers
3030 22098712 : = (!has_unknown_size
3031 22067638 : && POINTER_TYPE_P (field_type)
3032 36935238 : && TYPE_RESTRICT (field_type));
3033 22098712 : if (e.only_restrict_pointers)
3034 112133 : e.restrict_pointed_type = TREE_TYPE (field_type);
3035 22098712 : fieldstack->safe_push (e);
3036 : }
3037 : }
3038 :
3039 : empty_p = false;
3040 : }
3041 :
3042 13451899 : return !empty_p;
3043 : }
3044 :
3045 : /* Count the number of arguments DECL has, and set IS_VARARGS to true
3046 : if it is a varargs function. */
3047 :
3048 : static unsigned int
3049 23722 : count_num_arguments (tree decl, bool *is_varargs)
3050 : {
3051 23722 : unsigned int num = 0;
3052 23722 : tree t;
3053 :
3054 : /* Capture named arguments for K&R functions. They do not
3055 : have a prototype and thus no TYPE_ARG_TYPES. */
3056 49188 : for (t = DECL_ARGUMENTS (decl); t; t = DECL_CHAIN (t))
3057 25466 : ++num;
3058 :
3059 : /* Check if the function has variadic arguments. */
3060 49188 : for (t = TYPE_ARG_TYPES (TREE_TYPE (decl)); t; t = TREE_CHAIN (t))
3061 49181 : if (TREE_VALUE (t) == void_type_node)
3062 : break;
3063 23722 : if (!t)
3064 7 : *is_varargs = true;
3065 :
3066 23722 : return num;
3067 : }
3068 :
3069 : /* Creation function node for DECL, using NAME, and return the index
3070 : of the variable we've created for the function. If NONLOCAL_p, create
3071 : initial constraints. */
3072 :
3073 : static varinfo_t
3074 23722 : create_function_info_for (tree decl, const char *name, bool add_id,
3075 : bool nonlocal_p)
3076 : {
3077 23722 : struct function *fn = DECL_STRUCT_FUNCTION (decl);
3078 23722 : varinfo_t vi, prev_vi;
3079 23722 : tree arg;
3080 23722 : unsigned int i;
3081 23722 : bool is_varargs = false;
3082 23722 : unsigned int num_args = count_num_arguments (decl, &is_varargs);
3083 :
3084 : /* Create the variable info. */
3085 :
3086 23722 : vi = new_var_info (decl, name, add_id);
3087 23722 : vi->offset = 0;
3088 23722 : vi->size = 1;
3089 23722 : vi->fullsize = fi_parm_base + num_args;
3090 23722 : vi->is_fn_info = 1;
3091 23722 : vi->may_have_pointers = false;
3092 23722 : if (is_varargs)
3093 7 : vi->fullsize = ~0;
3094 23722 : insert_vi_for_tree (vi->decl, vi);
3095 :
3096 23722 : prev_vi = vi;
3097 :
3098 : /* Create a variable for things the function clobbers and one for
3099 : things the function uses. */
3100 23722 : {
3101 23722 : varinfo_t clobbervi, usevi;
3102 23722 : const char *newname;
3103 23722 : char *tempname;
3104 :
3105 23722 : tempname = xasprintf ("%s.clobber", name);
3106 23722 : newname = ggc_strdup (tempname);
3107 23722 : free (tempname);
3108 :
3109 23722 : clobbervi = new_var_info (NULL, newname, false);
3110 23722 : clobbervi->offset = fi_clobbers;
3111 23722 : clobbervi->size = 1;
3112 23722 : clobbervi->fullsize = vi->fullsize;
3113 23722 : clobbervi->is_full_var = true;
3114 23722 : clobbervi->is_global_var = false;
3115 23722 : clobbervi->is_reg_var = true;
3116 :
3117 23722 : gcc_assert (prev_vi->offset < clobbervi->offset);
3118 23722 : prev_vi->next = clobbervi->id;
3119 23722 : prev_vi = clobbervi;
3120 :
3121 23722 : tempname = xasprintf ("%s.use", name);
3122 23722 : newname = ggc_strdup (tempname);
3123 23722 : free (tempname);
3124 :
3125 23722 : usevi = new_var_info (NULL, newname, false);
3126 23722 : usevi->offset = fi_uses;
3127 23722 : usevi->size = 1;
3128 23722 : usevi->fullsize = vi->fullsize;
3129 23722 : usevi->is_full_var = true;
3130 23722 : usevi->is_global_var = false;
3131 23722 : usevi->is_reg_var = true;
3132 :
3133 23722 : gcc_assert (prev_vi->offset < usevi->offset);
3134 23722 : prev_vi->next = usevi->id;
3135 23722 : prev_vi = usevi;
3136 : }
3137 :
3138 : /* And one for the static chain. */
3139 23722 : if (fn->static_chain_decl != NULL_TREE)
3140 : {
3141 139 : varinfo_t chainvi;
3142 139 : const char *newname;
3143 139 : char *tempname;
3144 :
3145 139 : tempname = xasprintf ("%s.chain", name);
3146 139 : newname = ggc_strdup (tempname);
3147 139 : free (tempname);
3148 :
3149 139 : chainvi = new_var_info (fn->static_chain_decl, newname, false);
3150 139 : chainvi->offset = fi_static_chain;
3151 139 : chainvi->size = 1;
3152 139 : chainvi->fullsize = vi->fullsize;
3153 139 : chainvi->is_full_var = true;
3154 139 : chainvi->is_global_var = false;
3155 :
3156 139 : insert_vi_for_tree (fn->static_chain_decl, chainvi);
3157 :
3158 139 : if (nonlocal_p
3159 0 : && chainvi->may_have_pointers)
3160 0 : make_constraint_from (chainvi, nonlocal_id);
3161 :
3162 139 : gcc_assert (prev_vi->offset < chainvi->offset);
3163 139 : prev_vi->next = chainvi->id;
3164 139 : prev_vi = chainvi;
3165 : }
3166 :
3167 : /* Create a variable for the return var. */
3168 23722 : if (DECL_RESULT (decl) != NULL
3169 23722 : || !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
3170 : {
3171 23722 : varinfo_t resultvi;
3172 23722 : const char *newname;
3173 23722 : char *tempname;
3174 23722 : tree resultdecl = decl;
3175 :
3176 23722 : if (DECL_RESULT (decl))
3177 23722 : resultdecl = DECL_RESULT (decl);
3178 :
3179 23722 : tempname = xasprintf ("%s.result", name);
3180 23722 : newname = ggc_strdup (tempname);
3181 23722 : free (tempname);
3182 :
3183 23722 : resultvi = new_var_info (resultdecl, newname, false);
3184 23722 : resultvi->offset = fi_result;
3185 23722 : resultvi->size = 1;
3186 23722 : resultvi->fullsize = vi->fullsize;
3187 23722 : resultvi->is_full_var = true;
3188 23722 : if (DECL_RESULT (decl))
3189 23722 : resultvi->may_have_pointers = true;
3190 :
3191 23722 : if (DECL_RESULT (decl))
3192 23722 : insert_vi_for_tree (DECL_RESULT (decl), resultvi);
3193 :
3194 23722 : if (nonlocal_p
3195 6977 : && DECL_RESULT (decl)
3196 30699 : && DECL_BY_REFERENCE (DECL_RESULT (decl)))
3197 6 : make_constraint_from (resultvi, nonlocal_id);
3198 :
3199 23722 : gcc_assert (prev_vi->offset < resultvi->offset);
3200 23722 : prev_vi->next = resultvi->id;
3201 23722 : prev_vi = resultvi;
3202 : }
3203 :
3204 : /* We also need to make function return values escape. Nothing
3205 : escapes by returning from main though. */
3206 23722 : if (nonlocal_p
3207 23722 : && !MAIN_NAME_P (DECL_NAME (decl)))
3208 : {
3209 3466 : varinfo_t fi, rvi;
3210 3466 : fi = lookup_vi_for_tree (decl);
3211 3466 : rvi = first_vi_for_offset (fi, fi_result);
3212 3466 : if (rvi && rvi->offset == fi_result)
3213 3466 : make_copy_constraint (get_varinfo (escaped_id), rvi->id);
3214 : }
3215 :
3216 : /* Set up variables for each argument. */
3217 23722 : arg = DECL_ARGUMENTS (decl);
3218 49188 : for (i = 0; i < num_args; i++)
3219 : {
3220 25466 : varinfo_t argvi;
3221 25466 : const char *newname;
3222 25466 : char *tempname;
3223 25466 : tree argdecl = decl;
3224 :
3225 25466 : if (arg)
3226 25466 : argdecl = arg;
3227 :
3228 25466 : tempname = xasprintf ("%s.arg%d", name, i);
3229 25466 : newname = ggc_strdup (tempname);
3230 25466 : free (tempname);
3231 :
3232 25466 : argvi = new_var_info (argdecl, newname, false);
3233 25466 : argvi->offset = fi_parm_base + i;
3234 25466 : argvi->size = 1;
3235 25466 : argvi->is_full_var = true;
3236 25466 : argvi->fullsize = vi->fullsize;
3237 25466 : if (arg)
3238 25466 : argvi->may_have_pointers = true;
3239 :
3240 25466 : if (arg)
3241 25466 : insert_vi_for_tree (arg, argvi);
3242 :
3243 25466 : if (nonlocal_p
3244 9142 : && argvi->may_have_pointers)
3245 9142 : make_constraint_from (argvi, nonlocal_id);
3246 :
3247 25466 : gcc_assert (prev_vi->offset < argvi->offset);
3248 25466 : prev_vi->next = argvi->id;
3249 25466 : prev_vi = argvi;
3250 25466 : if (arg)
3251 25466 : arg = DECL_CHAIN (arg);
3252 : }
3253 :
3254 : /* Add one representative for all further args. */
3255 23722 : if (is_varargs)
3256 : {
3257 7 : varinfo_t argvi;
3258 7 : const char *newname;
3259 7 : char *tempname;
3260 7 : tree decl;
3261 :
3262 7 : tempname = xasprintf ("%s.varargs", name);
3263 7 : newname = ggc_strdup (tempname);
3264 7 : free (tempname);
3265 :
3266 : /* We need sth that can be pointed to for va_start. */
3267 7 : decl = build_fake_var_decl (ptr_type_node);
3268 :
3269 7 : argvi = new_var_info (decl, newname, false);
3270 7 : argvi->offset = fi_parm_base + num_args;
3271 7 : argvi->size = ~0;
3272 7 : argvi->is_full_var = true;
3273 7 : argvi->is_heap_var = true;
3274 7 : argvi->fullsize = vi->fullsize;
3275 :
3276 7 : if (nonlocal_p
3277 6 : && argvi->may_have_pointers)
3278 6 : make_constraint_from (argvi, nonlocal_id);
3279 :
3280 7 : gcc_assert (prev_vi->offset < argvi->offset);
3281 7 : prev_vi->next = argvi->id;
3282 : }
3283 :
3284 23722 : return vi;
3285 : }
3286 :
3287 :
3288 : /* Return true if FIELDSTACK contains fields that overlap.
3289 : FIELDSTACK is assumed to be sorted by offset. */
3290 :
3291 : static bool
3292 7326074 : check_for_overlaps (const vec<fieldoff_s> &fieldstack)
3293 : {
3294 7326074 : fieldoff_s *fo = NULL;
3295 7326074 : unsigned int i;
3296 7326074 : HOST_WIDE_INT lastoffset = -1;
3297 :
3298 28725066 : FOR_EACH_VEC_ELT (fieldstack, i, fo)
3299 : {
3300 21415440 : if (fo->offset == lastoffset)
3301 : return true;
3302 21398992 : lastoffset = fo->offset;
3303 : }
3304 : return false;
3305 : }
3306 :
3307 : /* Create a varinfo structure for NAME and DECL, and add it to VARMAP.
3308 : This will also create any varinfo structures necessary for fields
3309 : of DECL. DECL is a function parameter if HANDLE_PARAM is set.
3310 : HANDLED_STRUCT_TYPE is used to register struct types reached by following
3311 : restrict pointers. This is needed to prevent infinite recursion.
3312 : If ADD_RESTRICT, pretend that the pointer NAME is restrict even if DECL
3313 : does not advertise it. */
3314 :
3315 : static varinfo_t
3316 90607084 : create_variable_info_for_1 (tree decl, const char *name, bool add_id,
3317 : bool handle_param, bitmap handled_struct_type,
3318 : bool add_restrict = false)
3319 : {
3320 90607084 : varinfo_t vi, newvi;
3321 90607084 : tree decl_type = TREE_TYPE (decl);
3322 90607084 : tree declsize = DECL_P (decl) ? DECL_SIZE (decl) : TYPE_SIZE (decl_type);
3323 90607084 : auto_vec<fieldoff_s> fieldstack;
3324 90607084 : fieldoff_s *fo;
3325 90607084 : unsigned int i;
3326 :
3327 90607084 : if (!declsize
3328 82364627 : || !tree_fits_uhwi_p (declsize))
3329 : {
3330 8256535 : vi = new_var_info (decl, name, add_id);
3331 8256535 : vi->offset = 0;
3332 8256535 : vi->size = ~0;
3333 8256535 : vi->fullsize = ~0;
3334 8256535 : vi->is_unknown_size_var = true;
3335 8256535 : vi->is_full_var = true;
3336 8256535 : vi->may_have_pointers = true;
3337 8256535 : return vi;
3338 : }
3339 :
3340 : /* Collect field information. */
3341 82350549 : if (use_field_sensitive
3342 78338545 : && var_can_have_subvars (decl)
3343 : /* ??? Force us to not use subfields for globals in IPA mode.
3344 : Else we'd have to parse arbitrary initializers. */
3345 89728452 : && !(in_ipa_mode
3346 20292 : && is_global_var (decl)))
3347 : {
3348 7357148 : fieldoff_s *fo = NULL;
3349 7357148 : bool notokay = false;
3350 7357148 : unsigned int i;
3351 :
3352 7357148 : push_fields_onto_fieldstack (decl_type, &fieldstack, 0);
3353 :
3354 36790319 : for (i = 0; !notokay && fieldstack.iterate (i, &fo); i++)
3355 22107097 : if (fo->has_unknown_size
3356 22076023 : || fo->offset < 0)
3357 : {
3358 : notokay = true;
3359 : break;
3360 : }
3361 :
3362 : /* We can't sort them if we have a field with a variable sized type,
3363 : which will make notokay = true. In that case, we are going to return
3364 : without creating varinfos for the fields anyway, so sorting them is a
3365 : waste to boot. */
3366 7357148 : if (!notokay)
3367 : {
3368 7326074 : sort_fieldstack (fieldstack);
3369 : /* Due to some C++ FE issues, like PR 22488, we might end up
3370 : what appear to be overlapping fields even though they,
3371 : in reality, do not overlap. Until the C++ FE is fixed,
3372 : we will simply disable field-sensitivity for these cases. */
3373 7326074 : notokay = check_for_overlaps (fieldstack);
3374 : }
3375 :
3376 7326074 : if (notokay)
3377 47522 : fieldstack.release ();
3378 : }
3379 :
3380 : /* If we didn't end up collecting sub-variables create a full
3381 : variable for the decl. */
3382 82350549 : if (fieldstack.length () == 0
3383 7056383 : || fieldstack.length () > (unsigned)param_max_fields_for_field_sensitive)
3384 : {
3385 75294584 : vi = new_var_info (decl, name, add_id);
3386 75294584 : vi->offset = 0;
3387 75294584 : vi->may_have_pointers = true;
3388 75294584 : vi->fullsize = tree_to_uhwi (declsize);
3389 75294584 : vi->size = vi->fullsize;
3390 75294584 : vi->is_full_var = true;
3391 75294584 : if (POINTER_TYPE_P (decl_type)
3392 75294584 : && (TYPE_RESTRICT (decl_type) || add_restrict))
3393 846978 : vi->only_restrict_pointers = 1;
3394 75294584 : if (vi->only_restrict_pointers
3395 846978 : && !type_contains_placeholder_p (TREE_TYPE (decl_type))
3396 846978 : && handle_param
3397 75851040 : && !bitmap_bit_p (handled_struct_type,
3398 556456 : TYPE_UID (TREE_TYPE (decl_type))))
3399 : {
3400 556456 : varinfo_t rvi;
3401 556456 : tree heapvar = build_fake_var_decl (TREE_TYPE (decl_type));
3402 556456 : DECL_EXTERNAL (heapvar) = 1;
3403 556456 : if (var_can_have_subvars (heapvar))
3404 854204 : bitmap_set_bit (handled_struct_type,
3405 427102 : TYPE_UID (TREE_TYPE (decl_type)));
3406 556456 : rvi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS", true,
3407 : true, handled_struct_type);
3408 556456 : if (var_can_have_subvars (heapvar))
3409 854204 : bitmap_clear_bit (handled_struct_type,
3410 427102 : TYPE_UID (TREE_TYPE (decl_type)));
3411 556456 : rvi->is_restrict_var = 1;
3412 556456 : insert_vi_for_tree (heapvar, rvi);
3413 556456 : make_constraint_from (vi, rvi->id);
3414 556456 : make_param_constraints (rvi);
3415 : }
3416 75294584 : fieldstack.release ();
3417 75294584 : return vi;
3418 : }
3419 :
3420 7055965 : vi = new_var_info (decl, name, add_id);
3421 7055965 : vi->fullsize = tree_to_uhwi (declsize);
3422 7055965 : if (fieldstack.length () == 1)
3423 1473781 : vi->is_full_var = true;
3424 : for (i = 0, newvi = vi;
3425 118978215 : fieldstack.iterate (i, &fo);
3426 21315166 : ++i, newvi = vi_next (newvi))
3427 : {
3428 21315166 : const char *newname = NULL;
3429 21315166 : char *tempname;
3430 :
3431 21315166 : if (dump_file)
3432 : {
3433 340 : if (fieldstack.length () != 1)
3434 : {
3435 310 : tempname
3436 310 : = xasprintf ("%s." HOST_WIDE_INT_PRINT_DEC
3437 : "+" HOST_WIDE_INT_PRINT_DEC, name,
3438 : fo->offset, fo->size);
3439 310 : newname = ggc_strdup (tempname);
3440 310 : free (tempname);
3441 : }
3442 : }
3443 : else
3444 : newname = "NULL";
3445 :
3446 310 : if (newname)
3447 21315136 : newvi->name = newname;
3448 21315166 : newvi->offset = fo->offset;
3449 21315166 : newvi->size = fo->size;
3450 21315166 : newvi->fullsize = vi->fullsize;
3451 21315166 : newvi->may_have_pointers = fo->may_have_pointers;
3452 21315166 : newvi->only_restrict_pointers = fo->only_restrict_pointers;
3453 21315166 : if (handle_param
3454 1632142 : && newvi->only_restrict_pointers
3455 27981 : && !type_contains_placeholder_p (fo->restrict_pointed_type)
3456 21343147 : && !bitmap_bit_p (handled_struct_type,
3457 27981 : TYPE_UID (fo->restrict_pointed_type)))
3458 : {
3459 27978 : varinfo_t rvi;
3460 27978 : tree heapvar = build_fake_var_decl (fo->restrict_pointed_type);
3461 27978 : DECL_EXTERNAL (heapvar) = 1;
3462 27978 : if (var_can_have_subvars (heapvar))
3463 82 : bitmap_set_bit (handled_struct_type,
3464 41 : TYPE_UID (fo->restrict_pointed_type));
3465 27978 : rvi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS", true,
3466 : true, handled_struct_type);
3467 27978 : if (var_can_have_subvars (heapvar))
3468 82 : bitmap_clear_bit (handled_struct_type,
3469 41 : TYPE_UID (fo->restrict_pointed_type));
3470 27978 : rvi->is_restrict_var = 1;
3471 27978 : insert_vi_for_tree (heapvar, rvi);
3472 27978 : make_constraint_from (newvi, rvi->id);
3473 27978 : make_param_constraints (rvi);
3474 : }
3475 35574367 : if (i + 1 < fieldstack.length ())
3476 : {
3477 14259201 : varinfo_t tem = new_var_info (decl, name, false);
3478 14259201 : newvi->next = tem->id;
3479 14259201 : tem->head = vi->id;
3480 : }
3481 : }
3482 :
3483 : return vi;
3484 90607084 : }
3485 :
3486 : static unsigned int
3487 80722907 : create_variable_info_for (tree decl, const char *name, bool add_id)
3488 : {
3489 : /* First see if we are dealing with an ifunc resolver call and
3490 : assiociate that with a call to the resolver function result. */
3491 80722907 : cgraph_node *node;
3492 80722907 : if (in_ipa_mode
3493 703938 : && TREE_CODE (decl) == FUNCTION_DECL
3494 17701 : && (node = cgraph_node::get (decl))
3495 80740607 : && node->ifunc_resolver)
3496 : {
3497 1 : varinfo_t fi = get_vi_for_tree (node->get_alias_target ()->decl);
3498 1 : constraint_expr rhs
3499 1 : = get_function_part_constraint (fi, fi_result);
3500 1 : fi = new_var_info (NULL_TREE, "ifuncres", true);
3501 1 : fi->is_reg_var = true;
3502 1 : constraint_expr lhs;
3503 1 : lhs.type = SCALAR;
3504 1 : lhs.var = fi->id;
3505 1 : lhs.offset = 0;
3506 1 : process_constraint (new_constraint (lhs, rhs));
3507 1 : insert_vi_for_tree (decl, fi);
3508 1 : return fi->id;
3509 : }
3510 :
3511 80722906 : varinfo_t vi = create_variable_info_for_1 (decl, name, add_id, false, NULL);
3512 80722906 : unsigned int id = vi->id;
3513 :
3514 80722906 : insert_vi_for_tree (decl, vi);
3515 :
3516 80722906 : if (!VAR_P (decl))
3517 : return id;
3518 :
3519 : /* Create initial constraints for globals. */
3520 32102247 : for (; vi; vi = vi_next (vi))
3521 : {
3522 22622358 : if (!vi->may_have_pointers
3523 22622358 : || !vi->is_global_var)
3524 14674906 : continue;
3525 :
3526 : /* Mark global restrict qualified pointers. */
3527 15542024 : if ((POINTER_TYPE_P (TREE_TYPE (decl))
3528 353035 : && TYPE_RESTRICT (TREE_TYPE (decl)))
3529 15887512 : || vi->only_restrict_pointers)
3530 : {
3531 12816 : varinfo_t rvi
3532 12816 : = make_constraint_from_global_restrict (vi, "GLOBAL_RESTRICT",
3533 : true);
3534 : /* ??? For now exclude reads from globals as restrict sources
3535 : if those are not (indirectly) from incoming parameters. */
3536 12816 : rvi->is_restrict_var = false;
3537 12816 : continue;
3538 12816 : }
3539 :
3540 : /* In non-IPA mode the initializer from nonlocal is all we need. */
3541 7934636 : if (!in_ipa_mode
3542 7971532 : || DECL_HARD_REGISTER (decl))
3543 7897740 : make_copy_constraint (vi, nonlocal_id);
3544 :
3545 : /* In IPA mode parse the initializer and generate proper constraints
3546 : for it. */
3547 : else
3548 : {
3549 36896 : varpool_node *vnode = varpool_node::get (decl);
3550 :
3551 : /* For escaped variables initialize them from nonlocal. */
3552 36896 : if (!vnode || !vnode->all_refs_explicit_p ())
3553 1450 : make_copy_constraint (vi, nonlocal_id);
3554 :
3555 : /* While we can in theory walk references for the varpool
3556 : node that does not cover zero-initialization or references
3557 : to the constant pool. */
3558 36896 : if (DECL_INITIAL (decl))
3559 : {
3560 35806 : auto_vec<ce_s> rhsc;
3561 35806 : struct constraint_expr lhs, *rhsp;
3562 35806 : unsigned i;
3563 35806 : lhs.var = vi->id;
3564 35806 : lhs.offset = 0;
3565 35806 : lhs.type = SCALAR;
3566 35806 : get_constraint_for (DECL_INITIAL (decl), &rhsc);
3567 183725 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
3568 112113 : process_constraint (new_constraint (lhs, *rhsp));
3569 : /* If this is a variable that escapes from the unit
3570 : the initializer escapes as well. */
3571 35806 : if (!vnode || !vnode->all_refs_explicit_p ())
3572 : {
3573 2191 : lhs.var = escaped_id;
3574 2191 : lhs.offset = 0;
3575 2191 : lhs.type = SCALAR;
3576 37997 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
3577 1578 : process_constraint (new_constraint (lhs, *rhsp));
3578 : }
3579 35806 : }
3580 : }
3581 : }
3582 :
3583 : return id;
3584 : }
3585 :
3586 : /* Register the constraints for function parameter related VI. */
3587 :
3588 : static void
3589 9884178 : make_param_constraints (varinfo_t vi)
3590 : {
3591 11229403 : for (; vi; vi = vi_next (vi))
3592 : {
3593 10758181 : if (vi->only_restrict_pointers)
3594 : ;
3595 10173744 : else if (vi->may_have_pointers)
3596 10173744 : make_constraint_from (vi, nonlocal_id);
3597 :
3598 10758181 : if (vi->is_full_var)
3599 : break;
3600 : }
3601 9884178 : }
3602 :
3603 : /* Create varinfo structures for parameters, return value and the static
3604 : chain of FN. Intended for intraprocedural mode. */
3605 :
3606 : static void
3607 4411506 : intra_create_variable_infos (struct function *fn)
3608 : {
3609 4411506 : tree t;
3610 4411506 : bitmap handled_struct_type = NULL;
3611 4411506 : bool this_parm_in_ctor = DECL_CXX_CONSTRUCTOR_P (fn->decl);
3612 :
3613 : /* For each incoming pointer argument arg, create the constraint ARG
3614 : = NONLOCAL or a dummy variable if it is a restrict qualified
3615 : passed-by-reference argument. */
3616 13711250 : for (t = DECL_ARGUMENTS (fn->decl); t; t = DECL_CHAIN (t))
3617 : {
3618 9299744 : if (handled_struct_type == NULL)
3619 3715209 : handled_struct_type = BITMAP_ALLOC (NULL);
3620 :
3621 9299744 : varinfo_t p
3622 9299744 : = create_variable_info_for_1 (t, alias_get_name (t), false, true,
3623 : handled_struct_type, this_parm_in_ctor);
3624 9299744 : insert_vi_for_tree (t, p);
3625 :
3626 9299744 : make_param_constraints (p);
3627 :
3628 9299744 : this_parm_in_ctor = false;
3629 : }
3630 :
3631 4411506 : if (handled_struct_type != NULL)
3632 3715209 : BITMAP_FREE (handled_struct_type);
3633 :
3634 : /* Add a constraint for a result decl that is passed by reference. */
3635 4411506 : if (DECL_RESULT (fn->decl)
3636 4411506 : && DECL_BY_REFERENCE (DECL_RESULT (fn->decl)))
3637 : {
3638 55295 : varinfo_t p, result_vi = get_vi_for_tree (DECL_RESULT (fn->decl));
3639 :
3640 165885 : for (p = result_vi; p; p = vi_next (p))
3641 55295 : make_constraint_from (p, nonlocal_id);
3642 : }
3643 :
3644 : /* Add a constraint for the incoming static chain parameter. */
3645 4411506 : if (fn->static_chain_decl != NULL_TREE)
3646 : {
3647 47289 : varinfo_t p, chain_vi = get_vi_for_tree (fn->static_chain_decl);
3648 :
3649 141867 : for (p = chain_vi; p; p = vi_next (p))
3650 47289 : make_constraint_from (p, nonlocal_id);
3651 : }
3652 4411506 : }
3653 :
3654 : /* Initialize the always-existing constraint variables for NULL
3655 : ANYTHING, READONLY, and INTEGER. */
3656 :
3657 : static void
3658 4415916 : init_base_vars (void)
3659 : {
3660 4415916 : struct constraint_expr lhs, rhs;
3661 4415916 : varinfo_t var_anything;
3662 4415916 : varinfo_t var_nothing;
3663 4415916 : varinfo_t var_string;
3664 4415916 : varinfo_t var_escaped;
3665 4415916 : varinfo_t var_nonlocal;
3666 4415916 : varinfo_t var_escaped_return;
3667 4415916 : varinfo_t var_storedanything;
3668 4415916 : varinfo_t var_integer;
3669 :
3670 : /* Variable ID zero is reserved and should be NULL. */
3671 4415916 : varmap.safe_push (NULL);
3672 :
3673 : /* Create the NULL variable, used to represent that a variable points
3674 : to NULL. */
3675 4415916 : var_nothing = new_var_info (NULL_TREE, "NULL", false);
3676 4415916 : gcc_assert (var_nothing->id == nothing_id);
3677 4415916 : var_nothing->is_artificial_var = 1;
3678 4415916 : var_nothing->offset = 0;
3679 4415916 : var_nothing->size = ~0;
3680 4415916 : var_nothing->fullsize = ~0;
3681 4415916 : var_nothing->is_special_var = 1;
3682 4415916 : var_nothing->may_have_pointers = 0;
3683 4415916 : var_nothing->is_global_var = 0;
3684 :
3685 : /* Create the ANYTHING variable, used to represent that a variable
3686 : points to some unknown piece of memory. */
3687 4415916 : var_anything = new_var_info (NULL_TREE, "ANYTHING", false);
3688 4415916 : gcc_assert (var_anything->id == anything_id);
3689 4415916 : var_anything->is_artificial_var = 1;
3690 4415916 : var_anything->size = ~0;
3691 4415916 : var_anything->offset = 0;
3692 4415916 : var_anything->fullsize = ~0;
3693 4415916 : var_anything->is_special_var = 1;
3694 :
3695 : /* Anything points to anything. This makes deref constraints just
3696 : work in the presence of linked list and other p = *p type loops,
3697 : by saying that *ANYTHING = ANYTHING. */
3698 4415916 : lhs.type = SCALAR;
3699 4415916 : lhs.var = anything_id;
3700 4415916 : lhs.offset = 0;
3701 4415916 : rhs.type = ADDRESSOF;
3702 4415916 : rhs.var = anything_id;
3703 4415916 : rhs.offset = 0;
3704 :
3705 : /* This specifically does not use process_constraint because
3706 : process_constraint ignores all anything = anything constraints, since all
3707 : but this one are redundant. */
3708 4415916 : constraints.safe_push (new_constraint (lhs, rhs));
3709 :
3710 : /* Create the STRING variable, used to represent that a variable
3711 : points to a string literal. String literals don't contain
3712 : pointers so STRING doesn't point to anything. */
3713 4415916 : var_string = new_var_info (NULL_TREE, "STRING", false);
3714 4415916 : gcc_assert (var_string->id == string_id);
3715 4415916 : var_string->is_artificial_var = 1;
3716 4415916 : var_string->offset = 0;
3717 4415916 : var_string->size = ~0;
3718 4415916 : var_string->fullsize = ~0;
3719 4415916 : var_string->is_special_var = 1;
3720 4415916 : var_string->may_have_pointers = 0;
3721 :
3722 : /* Create the ESCAPED variable, used to represent the set of escaped
3723 : memory. */
3724 4415916 : var_escaped = new_var_info (NULL_TREE, "ESCAPED", false);
3725 4415916 : gcc_assert (var_escaped->id == escaped_id);
3726 4415916 : var_escaped->is_artificial_var = 1;
3727 4415916 : var_escaped->offset = 0;
3728 4415916 : var_escaped->size = ~0;
3729 4415916 : var_escaped->fullsize = ~0;
3730 4415916 : var_escaped->is_special_var = 0;
3731 :
3732 : /* Create the NONLOCAL variable, used to represent the set of nonlocal
3733 : memory. */
3734 4415916 : var_nonlocal = new_var_info (NULL_TREE, "NONLOCAL", false);
3735 4415916 : gcc_assert (var_nonlocal->id == nonlocal_id);
3736 4415916 : var_nonlocal->is_artificial_var = 1;
3737 4415916 : var_nonlocal->offset = 0;
3738 4415916 : var_nonlocal->size = ~0;
3739 4415916 : var_nonlocal->fullsize = ~0;
3740 4415916 : var_nonlocal->is_special_var = 1;
3741 :
3742 : /* Create the ESCAPED_RETURN variable, used to represent the set of escaped
3743 : memory via a regular return stmt. */
3744 4415916 : var_escaped_return = new_var_info (NULL_TREE, "ESCAPED_RETURN", false);
3745 4415916 : gcc_assert (var_escaped_return->id == escaped_return_id);
3746 4415916 : var_escaped_return->is_artificial_var = 1;
3747 4415916 : var_escaped_return->offset = 0;
3748 4415916 : var_escaped_return->size = ~0;
3749 4415916 : var_escaped_return->fullsize = ~0;
3750 4415916 : var_escaped_return->is_special_var = 0;
3751 :
3752 : /* ESCAPED = *ESCAPED, because escaped is may-deref'd at calls, etc. */
3753 4415916 : lhs.type = SCALAR;
3754 4415916 : lhs.var = escaped_id;
3755 4415916 : lhs.offset = 0;
3756 4415916 : rhs.type = DEREF;
3757 4415916 : rhs.var = escaped_id;
3758 4415916 : rhs.offset = 0;
3759 4415916 : process_constraint (new_constraint (lhs, rhs));
3760 :
3761 : /* ESCAPED = ESCAPED + UNKNOWN_OFFSET, because if a sub-field escapes the
3762 : whole variable escapes. */
3763 4415916 : lhs.type = SCALAR;
3764 4415916 : lhs.var = escaped_id;
3765 4415916 : lhs.offset = 0;
3766 4415916 : rhs.type = SCALAR;
3767 4415916 : rhs.var = escaped_id;
3768 4415916 : rhs.offset = UNKNOWN_OFFSET;
3769 4415916 : process_constraint (new_constraint (lhs, rhs));
3770 :
3771 : /* *ESCAPED = NONLOCAL. This is true because we have to assume
3772 : everything pointed to by escaped points to what global memory can
3773 : point to. */
3774 4415916 : lhs.type = DEREF;
3775 4415916 : lhs.var = escaped_id;
3776 4415916 : lhs.offset = 0;
3777 4415916 : rhs.type = SCALAR;
3778 4415916 : rhs.var = nonlocal_id;
3779 4415916 : rhs.offset = 0;
3780 4415916 : process_constraint (new_constraint (lhs, rhs));
3781 :
3782 : /* NONLOCAL = &NONLOCAL, NONLOCAL = &ESCAPED. This is true because
3783 : global memory may point to global memory and escaped memory. */
3784 4415916 : lhs.type = SCALAR;
3785 4415916 : lhs.var = nonlocal_id;
3786 4415916 : lhs.offset = 0;
3787 4415916 : rhs.type = ADDRESSOF;
3788 4415916 : rhs.var = nonlocal_id;
3789 4415916 : rhs.offset = 0;
3790 4415916 : process_constraint (new_constraint (lhs, rhs));
3791 4415916 : rhs.type = ADDRESSOF;
3792 4415916 : rhs.var = escaped_id;
3793 4415916 : rhs.offset = 0;
3794 4415916 : process_constraint (new_constraint (lhs, rhs));
3795 :
3796 : /* Transitively close ESCAPED_RETURN.
3797 : ESCAPED_RETURN = ESCAPED_RETURN + UNKNOWN_OFFSET
3798 : ESCAPED_RETURN = *ESCAPED_RETURN. */
3799 4415916 : lhs.type = SCALAR;
3800 4415916 : lhs.var = escaped_return_id;
3801 4415916 : lhs.offset = 0;
3802 4415916 : rhs.type = SCALAR;
3803 4415916 : rhs.var = escaped_return_id;
3804 4415916 : rhs.offset = UNKNOWN_OFFSET;
3805 4415916 : process_constraint (new_constraint (lhs, rhs));
3806 4415916 : lhs.type = SCALAR;
3807 4415916 : lhs.var = escaped_return_id;
3808 4415916 : lhs.offset = 0;
3809 4415916 : rhs.type = DEREF;
3810 4415916 : rhs.var = escaped_return_id;
3811 4415916 : rhs.offset = 0;
3812 4415916 : process_constraint (new_constraint (lhs, rhs));
3813 :
3814 : /* Create the STOREDANYTHING variable, used to represent the set of
3815 : variables stored to *ANYTHING. */
3816 4415916 : var_storedanything = new_var_info (NULL_TREE, "STOREDANYTHING", false);
3817 4415916 : gcc_assert (var_storedanything->id == storedanything_id);
3818 4415916 : var_storedanything->is_artificial_var = 1;
3819 4415916 : var_storedanything->offset = 0;
3820 4415916 : var_storedanything->size = ~0;
3821 4415916 : var_storedanything->fullsize = ~0;
3822 4415916 : var_storedanything->is_special_var = 0;
3823 :
3824 : /* Create the INTEGER variable, used to represent that a variable points
3825 : to what an INTEGER "points to". */
3826 4415916 : var_integer = new_var_info (NULL_TREE, "INTEGER", false);
3827 4415916 : gcc_assert (var_integer->id == integer_id);
3828 4415916 : var_integer->is_artificial_var = 1;
3829 4415916 : var_integer->size = ~0;
3830 4415916 : var_integer->fullsize = ~0;
3831 4415916 : var_integer->offset = 0;
3832 4415916 : var_integer->is_special_var = 1;
3833 :
3834 : /* INTEGER = ANYTHING, because we don't know where a dereference of
3835 : a random integer will point to. */
3836 4415916 : lhs.type = SCALAR;
3837 4415916 : lhs.var = integer_id;
3838 4415916 : lhs.offset = 0;
3839 4415916 : rhs.type = ADDRESSOF;
3840 4415916 : rhs.var = anything_id;
3841 4415916 : rhs.offset = 0;
3842 4415916 : process_constraint (new_constraint (lhs, rhs));
3843 4415916 : }
3844 :
3845 : /* Associate node with varinfo DATA. Worker for
3846 : cgraph_for_symbol_thunks_and_aliases. */
3847 : static bool
3848 23778 : associate_varinfo_to_alias (struct cgraph_node *node, void *data)
3849 : {
3850 23778 : if ((node->alias
3851 23725 : || (node->thunk
3852 3 : && ! node->inlined_to))
3853 53 : && node->analyzed
3854 53 : && !node->ifunc_resolver)
3855 52 : insert_vi_for_tree (node->decl, (varinfo_t)data);
3856 23778 : return false;
3857 : }
3858 :
3859 : /* Compute whether node is refered to non-locally. Worker for
3860 : cgraph_for_symbol_thunks_and_aliases. */
3861 : static bool
3862 23778 : refered_from_nonlocal_fn (struct cgraph_node *node, void *data)
3863 : {
3864 23778 : bool *nonlocal_p = (bool *)data;
3865 47556 : *nonlocal_p |= (node->used_from_other_partition
3866 23732 : || DECL_EXTERNAL (node->decl)
3867 23727 : || TREE_PUBLIC (node->decl)
3868 16760 : || node->force_output
3869 16750 : || node->ref_by_asm
3870 40528 : || lookup_attribute ("noipa", DECL_ATTRIBUTES (node->decl)));
3871 23778 : return false;
3872 : }
3873 :
3874 : /* Same for varpool nodes. */
3875 : static bool
3876 37099 : refered_from_nonlocal_var (struct varpool_node *node, void *data)
3877 : {
3878 37099 : bool *nonlocal_p = (bool *)data;
3879 74198 : *nonlocal_p |= (node->used_from_other_partition
3880 36998 : || DECL_EXTERNAL (node->decl)
3881 36514 : || TREE_PUBLIC (node->decl)
3882 35466 : || node->ref_by_asm
3883 72565 : || node->force_output);
3884 37099 : return false;
3885 : }
3886 :
3887 : /* Create function infos. */
3888 :
3889 : static void
3890 4410 : ipa_create_function_infos (void)
3891 : {
3892 4410 : struct cgraph_node *node;
3893 4410 : unsigned int constr_count = constraints.length ();
3894 :
3895 29378 : FOR_EACH_DEFINED_FUNCTION (node)
3896 : {
3897 24968 : varinfo_t vi;
3898 : /* Nodes without a body in this partition are not interesting.
3899 : Especially do not visit clones at this point for now - we
3900 : get duplicate decls there for inline clones at least. */
3901 26214 : if (!node->has_gimple_body_p ()
3902 24867 : || node->in_other_partition
3903 49835 : || node->inlined_to)
3904 1246 : continue;
3905 23722 : node->get_body ();
3906 :
3907 23722 : gcc_assert (!node->clone_of);
3908 :
3909 : /* For externally visible or attribute used annotated functions use
3910 : local constraints for their arguments.
3911 : For local functions we see all callers and thus do not need initial
3912 : constraints for parameters. */
3913 23722 : bool nonlocal_p = (node->used_from_other_partition
3914 23676 : || DECL_EXTERNAL (node->decl)
3915 23672 : || TREE_PUBLIC (node->decl)
3916 16756 : || node->force_output
3917 40468 : || lookup_attribute ("noipa",
3918 16746 : DECL_ATTRIBUTES (node->decl)));
3919 23722 : node->call_for_symbol_thunks_and_aliases (refered_from_nonlocal_fn,
3920 : &nonlocal_p, true);
3921 :
3922 23722 : vi = create_function_info_for (node->decl,
3923 : alias_get_name (node->decl), false,
3924 : nonlocal_p);
3925 54 : if (dump_file && (dump_flags & TDF_DETAILS)
3926 23774 : && constr_count != constraints.length ())
3927 : {
3928 22 : fprintf (dump_file,
3929 : "Generating initial constraints for %s",
3930 : node->dump_name ());
3931 22 : if (DECL_ASSEMBLER_NAME_SET_P (node->decl))
3932 44 : fprintf (dump_file, " (%s)",
3933 22 : IDENTIFIER_POINTER
3934 : (DECL_ASSEMBLER_NAME (node->decl)));
3935 22 : fprintf (dump_file, "\n\n");
3936 22 : dump_constraints (dump_file, constr_count);
3937 22 : fprintf (dump_file, "\n");
3938 :
3939 22 : constr_count = constraints.length ();
3940 : }
3941 :
3942 23722 : node->call_for_symbol_thunks_and_aliases
3943 23722 : (associate_varinfo_to_alias, vi, true);
3944 : }
3945 4410 : }
3946 :
3947 : /* Create constraints for global variables and their initializers. */
3948 :
3949 : static void
3950 4410 : ipa_create_global_variable_infos (void)
3951 : {
3952 4410 : varpool_node *var;
3953 4410 : unsigned int constr_count = constraints.length ();
3954 :
3955 41509 : FOR_EACH_VARIABLE (var)
3956 : {
3957 37099 : if (var->alias && var->analyzed)
3958 17 : continue;
3959 :
3960 37082 : varinfo_t vi = get_vi_for_tree (var->decl);
3961 :
3962 : /* For the purpose of IPA PTA unit-local globals are not
3963 : escape points. */
3964 37082 : bool nonlocal_p = (DECL_EXTERNAL (var->decl)
3965 36598 : || TREE_PUBLIC (var->decl)
3966 35450 : || var->used_from_other_partition
3967 35450 : || var->force_output
3968 72528 : || var->ref_by_asm);
3969 37082 : var->call_for_symbol_and_aliases (refered_from_nonlocal_var,
3970 : &nonlocal_p, true);
3971 37082 : if (nonlocal_p)
3972 1637 : vi->is_ipa_escape_point = true;
3973 : }
3974 :
3975 19 : if (dump_file && (dump_flags & TDF_DETAILS)
3976 4427 : && constr_count != constraints.length ())
3977 : {
3978 11 : fprintf (dump_file,
3979 : "Generating constraints for global initializers\n\n");
3980 11 : dump_constraints (dump_file, constr_count);
3981 11 : fprintf (dump_file, "\n");
3982 11 : constr_count = constraints.length ();
3983 : }
3984 4410 : }
3985 :
3986 :
3987 : namespace pointer_analysis {
3988 :
3989 : /* Find the variable info for tree T in VI_FOR_TREE. If T does not
3990 : exist in the map, return NULL, otherwise, return the varinfo we found. */
3991 :
3992 : varinfo_t
3993 51305251 : lookup_vi_for_tree (tree t)
3994 : {
3995 51305251 : varinfo_t *slot = vi_for_tree->get (t);
3996 51305251 : if (slot == NULL)
3997 : return NULL;
3998 :
3999 49367644 : return *slot;
4000 : }
4001 :
4002 : /* Lookup the variable for the call statement CALL representing
4003 : the uses. Returns NULL if there is nothing special about this call. */
4004 :
4005 : varinfo_t
4006 30391992 : lookup_call_use_vi (gcall *call)
4007 : {
4008 30391992 : varinfo_t *slot_p = call_stmt_vars->get (call);
4009 30391992 : if (slot_p)
4010 28511404 : return *slot_p;
4011 :
4012 : return NULL;
4013 : }
4014 :
4015 : /* Lookup the variable for the call statement CALL representing
4016 : the clobbers. Returns NULL if there is nothing special about this call. */
4017 :
4018 : varinfo_t
4019 14572301 : lookup_call_clobber_vi (gcall *call)
4020 : {
4021 14572301 : varinfo_t uses = lookup_call_use_vi (call);
4022 14572301 : if (!uses)
4023 : return NULL;
4024 :
4025 13641755 : return vi_next (uses);
4026 : }
4027 :
4028 : /* Return the varinfo for the callee of CALL. */
4029 :
4030 : varinfo_t
4031 16655361 : get_fi_for_callee (gcall *call)
4032 : {
4033 16655361 : tree decl, fn = gimple_call_fn (call);
4034 :
4035 16655361 : if (fn && TREE_CODE (fn) == OBJ_TYPE_REF)
4036 141976 : fn = OBJ_TYPE_REF_EXPR (fn);
4037 :
4038 : /* If we can directly resolve the function being called, do so.
4039 : Otherwise, it must be some sort of indirect expression that
4040 : we should still be able to handle. */
4041 16655361 : decl = gimple_call_addr_fndecl (fn);
4042 16655361 : if (decl)
4043 15229629 : return get_vi_for_tree (decl);
4044 :
4045 : /* If the function is anything other than a SSA name pointer we have no
4046 : clue and should be getting ANYFN (well, ANYTHING for now). */
4047 1425732 : if (!fn || TREE_CODE (fn) != SSA_NAME)
4048 946494 : return get_varinfo (anything_id);
4049 :
4050 479238 : if (SSA_NAME_IS_DEFAULT_DEF (fn)
4051 479238 : && (TREE_CODE (SSA_NAME_VAR (fn)) == PARM_DECL
4052 15 : || TREE_CODE (SSA_NAME_VAR (fn)) == RESULT_DECL))
4053 13134 : fn = SSA_NAME_VAR (fn);
4054 :
4055 479238 : return get_vi_for_tree (fn);
4056 : }
4057 :
4058 : /* Initialize constraint builder. */
4059 :
4060 : void
4061 4415916 : init_constraint_builder (void)
4062 : {
4063 4415916 : vi_for_tree = new hash_map<tree, varinfo_t>;
4064 4415916 : call_stmt_vars = new hash_map<gimple *, varinfo_t>;
4065 4415916 : gcc_obstack_init (&fake_var_decl_obstack);
4066 :
4067 4415916 : init_base_vars ();
4068 4415916 : }
4069 :
4070 : /* Deallocate constraint builder globals. */
4071 :
4072 : void
4073 4415916 : delete_constraint_builder (void)
4074 : {
4075 8831832 : delete vi_for_tree;
4076 8831832 : delete call_stmt_vars;
4077 4415916 : constraint_pool.release ();
4078 4415916 : obstack_free (&fake_var_decl_obstack, NULL);
4079 4415916 : }
4080 :
4081 : /* Build constraints for intraprocedural mode. */
4082 :
4083 : void
4084 4411506 : intra_build_constraints (void)
4085 : {
4086 4411506 : basic_block bb;
4087 :
4088 4411506 : intra_create_variable_infos (cfun);
4089 :
4090 : /* Now walk all statements and build the constraint set. */
4091 39263546 : FOR_EACH_BB_FN (bb, cfun)
4092 : {
4093 46481488 : for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
4094 11629448 : gsi_next (&gsi))
4095 : {
4096 11629448 : gphi *phi = gsi.phi ();
4097 :
4098 23258896 : if (! virtual_operand_p (gimple_phi_result (phi)))
4099 6123695 : find_func_aliases (cfun, phi);
4100 : }
4101 :
4102 317041883 : for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
4103 247337803 : gsi_next (&gsi))
4104 : {
4105 247337803 : gimple *stmt = gsi_stmt (gsi);
4106 :
4107 247337803 : find_func_aliases (cfun, stmt);
4108 : }
4109 : }
4110 :
4111 4411506 : if (dump_file && (dump_flags & TDF_DETAILS))
4112 : {
4113 286 : fprintf (dump_file, "Points-to analysis\n\nConstraints:\n\n");
4114 286 : dump_constraints (dump_file, 0);
4115 : }
4116 4411506 : }
4117 :
4118 : /* Build constraints for ipa mode. */
4119 :
4120 : void
4121 4410 : ipa_build_constraints (void)
4122 : {
4123 4410 : struct cgraph_node *node;
4124 :
4125 4410 : ipa_create_function_infos ();
4126 4410 : ipa_create_global_variable_infos ();
4127 :
4128 4410 : unsigned int constr_count = constraints.length ();
4129 :
4130 28185 : FOR_EACH_DEFINED_FUNCTION (node)
4131 : {
4132 23775 : struct function *func;
4133 23775 : basic_block bb;
4134 :
4135 : /* Nodes without a body in this partition are not interesting. */
4136 23828 : if (!node->has_gimple_body_p ()
4137 23722 : || node->in_other_partition
4138 47497 : || node->clone_of)
4139 53 : continue;
4140 :
4141 23722 : if (dump_file && (dump_flags & TDF_DETAILS))
4142 : {
4143 52 : fprintf (dump_file,
4144 : "Generating constraints for %s", node->dump_name ());
4145 52 : if (DECL_ASSEMBLER_NAME_SET_P (node->decl))
4146 104 : fprintf (dump_file, " (%s)",
4147 52 : IDENTIFIER_POINTER
4148 : (DECL_ASSEMBLER_NAME (node->decl)));
4149 52 : fprintf (dump_file, "\n");
4150 : }
4151 :
4152 23722 : func = DECL_STRUCT_FUNCTION (node->decl);
4153 23722 : gcc_assert (cfun == NULL);
4154 :
4155 : /* Build constraints for the function body. */
4156 362380 : FOR_EACH_BB_FN (bb, func)
4157 : {
4158 447557 : for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
4159 108899 : gsi_next (&gsi))
4160 : {
4161 108899 : gphi *phi = gsi.phi ();
4162 :
4163 217798 : if (! virtual_operand_p (gimple_phi_result (phi)))
4164 64613 : find_func_aliases (func, phi);
4165 : }
4166 :
4167 1651628 : for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
4168 974312 : gsi_next (&gsi))
4169 : {
4170 974312 : gimple *stmt = gsi_stmt (gsi);
4171 :
4172 974312 : find_func_aliases (func, stmt);
4173 974312 : find_func_clobbers (func, stmt);
4174 : }
4175 : }
4176 :
4177 23722 : if (dump_file && (dump_flags & TDF_DETAILS))
4178 : {
4179 52 : fprintf (dump_file, "\n");
4180 52 : dump_constraints (dump_file, constr_count);
4181 52 : fprintf (dump_file, "\n");
4182 23827 : constr_count = constraints.length ();
4183 : }
4184 : }
4185 4410 : }
4186 :
4187 : } // namespace pointer_analysis
|