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