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 70326679 : get_call_vi (gcall *call)
70 : {
71 70326679 : varinfo_t vi, vi2;
72 :
73 70326679 : bool existed;
74 70326679 : varinfo_t *slot_p = &call_stmt_vars->get_or_insert (call, &existed);
75 70326679 : if (existed)
76 53864393 : return *slot_p;
77 :
78 16462286 : vi = new_var_info (NULL_TREE, "CALLUSED", true);
79 16462286 : vi->offset = 0;
80 16462286 : vi->size = 1;
81 16462286 : vi->fullsize = 2;
82 16462286 : vi->is_full_var = true;
83 16462286 : vi->is_reg_var = true;
84 :
85 16462286 : vi2 = new_var_info (NULL_TREE, "CALLCLOBBERED", true);
86 16462286 : vi2->offset = 1;
87 16462286 : vi2->size = 1;
88 16462286 : vi2->fullsize = 2;
89 16462286 : vi2->is_full_var = true;
90 16462286 : vi2->is_reg_var = true;
91 :
92 16462286 : vi->next = vi2->id;
93 :
94 16462286 : *slot_p = vi;
95 16462286 : 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 44128191 : 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 26198488 : get_call_clobber_vi (gcall *call)
112 : {
113 26198488 : 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 458654662 : new_constraint (const struct constraint_expr lhs,
130 : const struct constraint_expr rhs)
131 : {
132 0 : constraint_t ret = constraint_pool.allocate ();
133 458654662 : ret->lhs = lhs;
134 458654662 : ret->rhs = rhs;
135 458654662 : 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 95259919 : insert_vi_for_tree (tree t, varinfo_t vi)
142 : {
143 95259919 : gcc_assert (vi);
144 95259919 : bool existed = vi_for_tree->put (t, vi);
145 95259919 : gcc_assert (!existed);
146 95259919 : }
147 :
148 : /* Return a printable name for DECL. */
149 :
150 : static const char *
151 94143706 : alias_get_name (tree decl)
152 : {
153 94143706 : const char *res = "NULL";
154 94143706 : 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 94143706 : 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 250351594 : get_vi_for_tree (tree t)
187 : {
188 250351594 : varinfo_t *slot = vi_for_tree->get (t);
189 250351594 : if (slot == NULL)
190 : {
191 84440583 : unsigned int id = create_variable_info_for (t, alias_get_name (t), false);
192 84440583 : return get_varinfo (id);
193 : }
194 :
195 165911011 : return *slot;
196 : }
197 :
198 : /* Get a scalar constraint expression for a new temporary variable. */
199 :
200 : static struct constraint_expr
201 3296025 : new_scalar_tmp_constraint_exp (const char *name, bool add_id)
202 : {
203 3296025 : struct constraint_expr tmp;
204 3296025 : varinfo_t vi;
205 :
206 3296025 : vi = new_var_info (NULL_TREE, name, add_id);
207 3296025 : vi->offset = 0;
208 3296025 : vi->size = -1;
209 3296025 : vi->fullsize = -1;
210 3296025 : vi->is_full_var = 1;
211 3296025 : vi->is_reg_var = 1;
212 :
213 3296025 : tmp.var = vi->id;
214 3296025 : tmp.type = SCALAR;
215 3296025 : tmp.offset = 0;
216 :
217 3296025 : 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 210838358 : get_constraint_for_ssa_var (tree t, vec<ce_s> *results, bool address_p)
225 : {
226 229336039 : struct constraint_expr cexpr;
227 229336039 : varinfo_t vi;
228 :
229 : /* We allow FUNCTION_DECLs here even though it doesn't make much sense. */
230 229336039 : gcc_assert (TREE_CODE (t) == SSA_NAME || DECL_P (t));
231 :
232 229336039 : if (TREE_CODE (t) == SSA_NAME
233 229336039 : && SSA_NAME_IS_DEFAULT_DEF (t))
234 : {
235 : /* For parameters, get at the points-to set for the actual parm
236 : decl. */
237 18769227 : if (TREE_CODE (SSA_NAME_VAR (t)) == PARM_DECL
238 18769227 : || TREE_CODE (SSA_NAME_VAR (t)) == RESULT_DECL)
239 : {
240 18497681 : get_constraint_for_ssa_var (SSA_NAME_VAR (t), results, address_p);
241 24852877 : return;
242 : }
243 : /* For undefined SSA names return nothing. */
244 271546 : else if (!ssa_defined_default_def_p (t))
245 : {
246 271546 : cexpr.var = nothing_id;
247 271546 : cexpr.type = SCALAR;
248 271546 : cexpr.offset = 0;
249 271546 : results->safe_push (cexpr);
250 271546 : return;
251 : }
252 : }
253 :
254 : /* For global variables resort to the alias target. */
255 210566812 : if (VAR_P (t) && (TREE_STATIC (t) || DECL_EXTERNAL (t)))
256 : {
257 11731383 : varpool_node *node = varpool_node::get (t);
258 11731383 : if (node && node->alias && node->analyzed)
259 : {
260 19079 : 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 19079 : 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 19079 : DECL_PT_UID (t) = DECL_UID (node->decl);
269 19079 : t = node->decl;
270 : }
271 :
272 : /* If this is decl may bind to NULL note that. */
273 11731383 : if (address_p
274 11731383 : && (! node || ! node->nonzero_address ()))
275 : {
276 9567 : cexpr.var = nothing_id;
277 9567 : cexpr.type = SCALAR;
278 9567 : cexpr.offset = 0;
279 9567 : results->safe_push (cexpr);
280 : }
281 : }
282 :
283 210566812 : vi = get_vi_for_tree (t);
284 210566812 : cexpr.var = vi->id;
285 210566812 : cexpr.type = SCALAR;
286 210566812 : 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 210566812 : if (!address_p
291 171777502 : && !vi->is_full_var)
292 : {
293 20446941 : for (; vi; vi = vi_next (vi))
294 : {
295 14363291 : cexpr.var = vi->id;
296 14363291 : results->safe_push (cexpr);
297 : }
298 : return;
299 : }
300 :
301 204483162 : 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 454030173 : process_constraint (constraint_t t)
309 : {
310 454030173 : struct constraint_expr rhs = t->rhs;
311 454030173 : struct constraint_expr lhs = t->lhs;
312 :
313 454030173 : gcc_assert (rhs.var < varmap.length ());
314 454030173 : 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 454030173 : 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 454030173 : 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 454030173 : if (rhs.type != ADDRESSOF
329 454030173 : && !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 453622858 : 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 453621139 : if (rhs.type == DEREF && lhs.type == DEREF && rhs.var != anything_id)
338 : {
339 : /* Split into tmp = *rhs, *lhs = tmp. */
340 322299 : struct constraint_expr tmplhs;
341 322299 : tmplhs = new_scalar_tmp_constraint_exp ("doubledereftmp", true);
342 322299 : process_constraint (new_constraint (tmplhs, rhs));
343 322299 : process_constraint (new_constraint (lhs, tmplhs));
344 322299 : }
345 453298840 : else if ((rhs.type != SCALAR || rhs.offset != 0) && lhs.type == DEREF)
346 : {
347 : /* Split into tmp = &rhs, *lhs = tmp. */
348 2136912 : struct constraint_expr tmplhs;
349 2136912 : tmplhs = new_scalar_tmp_constraint_exp ("derefaddrtmp", true);
350 2136912 : process_constraint (new_constraint (tmplhs, rhs));
351 2136912 : process_constraint (new_constraint (lhs, tmplhs));
352 2136912 : }
353 : else
354 : {
355 451161928 : gcc_assert (rhs.type != ADDRESSOF || rhs.offset == 0);
356 451161928 : if (rhs.type == ADDRESSOF)
357 88814182 : get_varinfo (get_varinfo (rhs.var)->head)->address_taken = true;
358 451161928 : 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 41592927 : bitpos_of_field (const tree fdecl)
368 : {
369 41592927 : if (!tree_fits_uhwi_p (DECL_FIELD_OFFSET (fdecl))
370 41592927 : || !tree_fits_uhwi_p (DECL_FIELD_BIT_OFFSET (fdecl)))
371 : return -1;
372 :
373 41592927 : return (tree_to_uhwi (DECL_FIELD_OFFSET (fdecl)) * BITS_PER_UNIT
374 41592927 : + 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 42301462 : get_constraint_for_ptr_offset (tree ptr, tree offset,
383 : vec<ce_s> *results)
384 : {
385 42301462 : struct constraint_expr c;
386 42301462 : unsigned int j, n;
387 42301462 : 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 42301462 : if (!use_field_sensitive)
392 : {
393 2135015 : get_constraint_for_rhs (ptr, results);
394 2135015 : 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 40166447 : if (offset == NULL_TREE
402 14238856 : || TREE_CODE (offset) != INTEGER_CST)
403 : rhsoffset = UNKNOWN_OFFSET;
404 : else
405 : {
406 : /* Sign-extend the offset. */
407 12222776 : offset_int soffset = offset_int::from (wi::to_wide (offset), SIGNED);
408 12222776 : if (!wi::fits_shwi_p (soffset))
409 : rhsoffset = UNKNOWN_OFFSET;
410 : else
411 : {
412 : /* Make sure the bit-offset also fits. */
413 12222776 : HOST_WIDE_INT rhsunitoffset = soffset.to_shwi ();
414 12222776 : rhsoffset = rhsunitoffset * (unsigned HOST_WIDE_INT) BITS_PER_UNIT;
415 12222776 : if (rhsunitoffset != rhsoffset / BITS_PER_UNIT)
416 362 : rhsoffset = UNKNOWN_OFFSET;
417 : }
418 : }
419 :
420 40166447 : get_constraint_for_rhs (ptr, results);
421 40166447 : if (rhsoffset == 0)
422 : return;
423 :
424 : /* As we are eventually appending to the solution do not use
425 : vec::iterate here. */
426 33788619 : n = results->length ();
427 67577430 : for (j = 0; j < n; j++)
428 : {
429 33788811 : varinfo_t curr;
430 33788811 : c = (*results)[j];
431 33788811 : curr = get_varinfo (c.var);
432 :
433 33788811 : if (c.type == ADDRESSOF
434 : /* If this varinfo represents a full variable just use it. */
435 11171338 : && curr->is_full_var)
436 : ;
437 25162930 : else if (c.type == ADDRESSOF
438 : /* If we do not know the offset add all subfields. */
439 2545457 : && rhsoffset == UNKNOWN_OFFSET)
440 : {
441 42203 : varinfo_t temp = get_varinfo (curr->head);
442 281201 : do
443 : {
444 281201 : struct constraint_expr c2;
445 281201 : c2.var = temp->id;
446 281201 : c2.type = ADDRESSOF;
447 281201 : c2.offset = 0;
448 281201 : if (c2.var != c.var)
449 238998 : results->safe_push (c2);
450 281201 : temp = vi_next (temp);
451 : }
452 281201 : while (temp);
453 : }
454 25120727 : else if (c.type == ADDRESSOF)
455 : {
456 2503254 : varinfo_t temp;
457 2503254 : unsigned HOST_WIDE_INT offset = curr->offset + rhsoffset;
458 :
459 : /* If curr->offset + rhsoffset is less than zero adjust it. */
460 2503254 : if (rhsoffset < 0
461 0 : && curr->offset < offset)
462 2503254 : 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 2503254 : temp = first_or_preceding_vi_for_offset (curr, offset);
470 2503254 : c.var = temp->id;
471 2503254 : c.offset = 0;
472 2503254 : temp = vi_next (temp);
473 2503254 : while (temp
474 2628022 : && temp->offset < offset + curr->size)
475 : {
476 124768 : struct constraint_expr c2;
477 124768 : c2.var = temp->id;
478 124768 : c2.type = ADDRESSOF;
479 124768 : c2.offset = 0;
480 124768 : results->safe_push (c2);
481 124768 : temp = vi_next (temp);
482 : }
483 : }
484 22617473 : else if (c.type == SCALAR)
485 : {
486 22617473 : 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 33788811 : (*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 33277270 : get_constraint_for_component_ref (tree t, vec<ce_s> *results,
505 : bool address_p, bool lhs_p)
506 : {
507 33277270 : tree orig_t = t;
508 33277270 : poly_int64 bitsize = -1;
509 33277270 : poly_int64 bitmaxsize = -1;
510 33277270 : poly_int64 bitpos;
511 33277270 : bool reverse;
512 33277270 : tree forzero;
513 :
514 : /* Some people like to do cute things like take the address of
515 : &0->a.b. */
516 33277270 : forzero = t;
517 33277270 : while (handled_component_p (forzero)
518 48945600 : || INDIRECT_REF_P (forzero)
519 146414384 : || TREE_CODE (forzero) == MEM_REF)
520 64191514 : forzero = TREE_OPERAND (forzero, 0);
521 :
522 33277270 : if (CONSTANT_CLASS_P (forzero) && integer_zerop (forzero))
523 : {
524 1833 : struct constraint_expr temp;
525 :
526 1833 : temp.offset = 0;
527 1833 : temp.var = integer_id;
528 1833 : temp.type = SCALAR;
529 1833 : results->safe_push (temp);
530 1833 : return;
531 : }
532 :
533 33275437 : 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 33275437 : 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 33275427 : if (TREE_CODE (t) == MEM_REF
553 33275427 : && !integer_zerop (TREE_OPERAND (t, 0)))
554 : {
555 12385483 : poly_offset_int off = mem_ref_offset (t);
556 12385483 : off <<= LOG2_BITS_PER_UNIT;
557 12385483 : off += bitpos;
558 12385483 : poly_int64 off_hwi;
559 12385483 : if (off.to_shwi (&off_hwi))
560 12385481 : bitpos = off_hwi;
561 : else
562 : {
563 2 : bitpos = 0;
564 2 : bitmaxsize = -1;
565 : }
566 12385483 : get_constraint_for_1 (TREE_OPERAND (t, 0), results, false, lhs_p);
567 12385483 : do_deref (results);
568 : }
569 : else
570 20889944 : get_constraint_for_1 (t, results, true, lhs_p);
571 :
572 : /* Strip off nothing_id. */
573 33275427 : if (results->length () == 2)
574 : {
575 8588 : gcc_assert ((*results)[0].var == nothing_id);
576 8588 : results->unordered_remove (0);
577 : }
578 33275427 : gcc_assert (results->length () == 1);
579 33275427 : struct constraint_expr &result = results->last ();
580 :
581 33275427 : if (result.type == SCALAR
582 33275427 : && get_varinfo (result.var)->is_full_var)
583 : /* For single-field vars do not bother about the offset. */
584 8642333 : result.offset = 0;
585 24633094 : 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 12247686 : if (maybe_lt (poly_uint64 (bitpos), get_varinfo (result.var)->fullsize)
593 12247686 : && 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 12237636 : struct constraint_expr cexpr = result;
600 12237636 : varinfo_t curr;
601 12237636 : results->pop ();
602 12237636 : cexpr.offset = 0;
603 64145046 : for (curr = get_varinfo (cexpr.var); curr; curr = vi_next (curr))
604 : {
605 52800104 : if (ranges_maybe_overlap_p (poly_int64 (curr->offset),
606 52800104 : curr->size, bitpos, bitmaxsize))
607 : {
608 12477463 : cexpr.var = curr->id;
609 12477463 : results->safe_push (cexpr);
610 12477463 : 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 13130354 : 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 12237612 : 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 10050 : 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 317 : if (dump_file && (dump_flags & TDF_DETAILS))
647 0 : fprintf (dump_file, "Access to past the end of variable, ignoring\n");
648 : }
649 12385408 : 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 12385357 : HOST_WIDE_INT const_bitpos;
655 12385357 : if (!bitpos.is_constant (&const_bitpos)
656 12385357 : || const_bitpos == -1
657 12385357 : || maybe_ne (bitsize, bitmaxsize)
658 11651357 : || AGGREGATE_TYPE_P (TREE_TYPE (orig_t))
659 9937439 : || result.offset == UNKNOWN_OFFSET)
660 2447918 : result.offset = UNKNOWN_OFFSET;
661 : else
662 9937439 : 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 25026179 : do_deref (vec<ce_s> *constraints)
685 : {
686 25026179 : struct constraint_expr *c;
687 25026179 : unsigned int i = 0;
688 :
689 50221489 : FOR_EACH_VEC_ELT (*constraints, i, c)
690 : {
691 25195310 : if (c->type == SCALAR)
692 19040133 : c->type = DEREF;
693 6155177 : else if (c->type == ADDRESSOF)
694 6155171 : 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 25026179 : }
706 :
707 : /* Given a tree T, return the constraint expression for taking the
708 : address of it. */
709 :
710 : static void
711 29205879 : get_constraint_for_address_of (tree t, vec<ce_s> *results)
712 : {
713 29205879 : struct constraint_expr *c;
714 29205879 : unsigned int i;
715 :
716 29205879 : get_constraint_for_1 (t, results, true, true);
717 :
718 87620765 : FOR_EACH_VEC_ELT (*results, i, c)
719 : {
720 29209007 : if (c->type == DEREF)
721 : c->type = SCALAR;
722 : else
723 27494484 : c->type = ADDRESSOF;
724 : }
725 29205879 : }
726 :
727 : /* Given a tree T, return the constraint expression for it. */
728 :
729 : static void
730 328424380 : get_constraint_for_1 (tree t, vec<ce_s> *results, bool address_p,
731 : bool lhs_p)
732 : {
733 329284607 : 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 329284607 : if ((TREE_CODE (t) == INTEGER_CST
749 33423094 : && 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 351881432 : || (TREE_CODE (t) == CONSTRUCTOR
754 592154 : && CONSTRUCTOR_NELTS (t) == 0))
755 : {
756 11354564 : if (flag_delete_null_pointer_checks)
757 : temp.var = nothing_id;
758 : else
759 20140 : temp.var = nonlocal_id;
760 11354564 : temp.type = ADDRESSOF;
761 11354564 : temp.offset = 0;
762 11354564 : results->safe_push (temp);
763 338911603 : return;
764 : }
765 :
766 : /* String constants are read-only, ideally we'd have a CONST_DECL
767 : for those. */
768 317930043 : if (TREE_CODE (t) == STRING_CST)
769 : {
770 6723777 : temp.var = string_id;
771 6723777 : temp.type = SCALAR;
772 6723777 : temp.offset = 0;
773 6723777 : results->safe_push (temp);
774 6723777 : return;
775 : }
776 :
777 311206266 : switch (TREE_CODE_CLASS (TREE_CODE (t)))
778 : {
779 29020985 : case tcc_expression:
780 29020985 : {
781 29020985 : switch (TREE_CODE (t))
782 : {
783 28955011 : case ADDR_EXPR:
784 28955011 : get_constraint_for_address_of (TREE_OPERAND (t, 0), results);
785 28955011 : return;
786 : default:;
787 : }
788 : break;
789 : }
790 46120523 : case tcc_reference:
791 46120523 : {
792 46120523 : if (!lhs_p && TREE_THIS_VOLATILE (t))
793 : /* Fall back to anything. */
794 : break;
795 :
796 46013531 : switch (TREE_CODE (t))
797 : {
798 11876034 : case MEM_REF:
799 11876034 : {
800 11876034 : struct constraint_expr cs;
801 11876034 : varinfo_t vi, curr;
802 11876034 : get_constraint_for_ptr_offset (TREE_OPERAND (t, 0),
803 11876034 : TREE_OPERAND (t, 1), results);
804 11876034 : do_deref (results);
805 :
806 : /* If we are not taking the address then make sure to process
807 : all subvariables we might access. */
808 11876034 : if (address_p)
809 : return;
810 :
811 11227911 : cs = results->last ();
812 11227911 : if (cs.type == DEREF
813 11227911 : && type_can_have_subvars (TREE_TYPE (t)))
814 : {
815 : /* For dereferences this means we have to defer it
816 : to solving time. */
817 597416 : results->last ().offset = UNKNOWN_OFFSET;
818 597416 : return;
819 : }
820 10630495 : if (cs.type != SCALAR)
821 : return;
822 :
823 5170207 : vi = get_varinfo (cs.var);
824 5170207 : curr = vi_next (vi);
825 5170207 : if (!vi->is_full_var
826 3993785 : && curr)
827 : {
828 2589301 : unsigned HOST_WIDE_INT size;
829 2589301 : if (tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (t))))
830 2589301 : size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (t)));
831 : else
832 2589301 : size = -1;
833 5200170 : 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 3536918 : if (curr->offset - (vi->offset + vi->size - 1) < size)
839 : {
840 2610869 : cs.var = curr->id;
841 2610869 : results->safe_push (cs);
842 : }
843 : else
844 : break;
845 : }
846 : }
847 : return;
848 : }
849 33277270 : case ARRAY_REF:
850 33277270 : case ARRAY_RANGE_REF:
851 33277270 : case COMPONENT_REF:
852 33277270 : case IMAGPART_EXPR:
853 33277270 : case REALPART_EXPR:
854 33277270 : case BIT_FIELD_REF:
855 33277270 : get_constraint_for_component_ref (t, results, address_p, lhs_p);
856 33277270 : return;
857 860227 : case VIEW_CONVERT_EXPR:
858 860227 : get_constraint_for_1 (TREE_OPERAND (t, 0), results, address_p,
859 : lhs_p);
860 860227 : return;
861 : /* We are missing handling for TARGET_MEM_REF here. */
862 : default:;
863 : }
864 : break;
865 : }
866 161440110 : case tcc_exceptional:
867 161440110 : {
868 161440110 : switch (TREE_CODE (t))
869 : {
870 161376051 : case SSA_NAME:
871 161376051 : {
872 161376051 : get_constraint_for_ssa_var (t, results, address_p);
873 161376051 : return;
874 : }
875 63859 : case CONSTRUCTOR:
876 63859 : {
877 63859 : unsigned int i;
878 63859 : tree val;
879 63859 : auto_vec<ce_s> tmp;
880 357399 : FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (t), i, val)
881 : {
882 293540 : struct constraint_expr *rhsp;
883 293540 : unsigned j;
884 293540 : get_constraint_for_1 (val, &tmp, address_p, lhs_p);
885 587297 : FOR_EACH_VEC_ELT (tmp, j, rhsp)
886 293757 : results->safe_push (*rhsp);
887 293540 : 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 63859 : return;
893 63859 : }
894 : default:;
895 : }
896 : break;
897 : }
898 50156445 : case tcc_declaration:
899 50156445 : {
900 50156445 : if (!lhs_p && VAR_P (t) && TREE_THIS_VOLATILE (t))
901 : /* Fall back to anything. */
902 : break;
903 49462307 : get_constraint_for_ssa_var (t, results, address_p);
904 49462307 : return;
905 : }
906 24468166 : case tcc_constant:
907 24468166 : {
908 : /* We cannot refer to automatic variables through constants. */
909 24468166 : temp.type = ADDRESSOF;
910 24468166 : temp.var = nonlocal_id;
911 24468166 : temp.offset = 0;
912 24468166 : results->safe_push (temp);
913 24468166 : return;
914 : }
915 801130 : default:;
916 : }
917 :
918 : /* The default fallback is a constraint from anything. */
919 867341 : temp.type = ADDRESSOF;
920 867341 : temp.var = anything_id;
921 867341 : temp.offset = 0;
922 867341 : results->safe_push (temp);
923 : }
924 :
925 : /* Given a gimple tree T, return the constraint expression vector for it. */
926 :
927 : static void
928 90549876 : get_constraint_for (tree t, vec<ce_s> *results)
929 : {
930 90549876 : gcc_assert (results->length () == 0);
931 :
932 90549876 : get_constraint_for_1 (t, results, false, true);
933 90549876 : }
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 175099658 : get_constraint_for_rhs (tree t, vec<ce_s> *results)
940 : {
941 175099658 : gcc_assert (results->length () == 0);
942 :
943 175099658 : get_constraint_for_1 (t, results, false, false);
944 175099658 : }
945 :
946 :
947 : /* Efficiently generates constraints from all entries in *RHSC to all
948 : entries in *LHSC. */
949 :
950 : static void
951 97553731 : process_all_all_constraints (const vec<ce_s> &lhsc,
952 : const vec<ce_s> &rhsc)
953 : {
954 97553731 : struct constraint_expr *lhsp, *rhsp;
955 97553731 : unsigned i, j;
956 :
957 99818592 : if (lhsc.length () <= 1 || rhsc.length () <= 1)
958 : {
959 293447777 : FOR_EACH_VEC_ELT (lhsc, i, lhsp)
960 317190090 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
961 120459236 : process_constraint (new_constraint (*lhsp, *rhsp));
962 : }
963 : else
964 : {
965 836808 : struct constraint_expr tmp;
966 836808 : tmp = new_scalar_tmp_constraint_exp ("allalltmp", true);
967 4372611 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
968 2698995 : process_constraint (new_constraint (tmp, *rhsp));
969 3704117 : FOR_EACH_VEC_ELT (lhsc, i, lhsp)
970 2030501 : process_constraint (new_constraint (*lhsp, tmp));
971 : }
972 97553731 : }
973 :
974 : /* Handle aggregate copies by expanding into copies of the respective
975 : fields of the structures. */
976 :
977 : static void
978 2601969 : do_structure_copy (tree lhsop, tree rhsop)
979 : {
980 2601969 : struct constraint_expr *lhsp, *rhsp;
981 2601969 : auto_vec<ce_s> lhsc;
982 2601969 : auto_vec<ce_s> rhsc;
983 2601969 : unsigned j;
984 :
985 2601969 : get_constraint_for (lhsop, &lhsc);
986 2601969 : get_constraint_for_rhs (rhsop, &rhsc);
987 2601969 : lhsp = &lhsc[0];
988 2601969 : rhsp = &rhsc[0];
989 2601969 : if (lhsp->type == DEREF
990 2039554 : || (lhsp->type == ADDRESSOF && lhsp->var == anything_id)
991 2039554 : || rhsp->type == DEREF)
992 : {
993 910799 : if (lhsp->type == DEREF)
994 : {
995 562415 : gcc_assert (lhsc.length () == 1);
996 562415 : lhsp->offset = UNKNOWN_OFFSET;
997 : }
998 910799 : if (rhsp->type == DEREF)
999 : {
1000 460287 : gcc_assert (rhsc.length () == 1);
1001 460287 : rhsp->offset = UNKNOWN_OFFSET;
1002 : }
1003 910799 : process_all_all_constraints (lhsc, rhsc);
1004 : }
1005 1691170 : else if (lhsp->type == SCALAR
1006 1691170 : && (rhsp->type == SCALAR
1007 473718 : || rhsp->type == ADDRESSOF))
1008 : {
1009 1691170 : HOST_WIDE_INT lhssize, lhsoffset;
1010 1691170 : HOST_WIDE_INT rhssize, rhsoffset;
1011 1691170 : bool reverse;
1012 1691170 : unsigned k = 0;
1013 1691170 : if (!get_ref_base_and_extent_hwi (lhsop, &lhsoffset, &lhssize, &reverse)
1014 1691170 : || !get_ref_base_and_extent_hwi (rhsop, &rhsoffset, &rhssize,
1015 : &reverse))
1016 : {
1017 5064 : process_all_all_constraints (lhsc, rhsc);
1018 5064 : return;
1019 : }
1020 6282855 : for (j = 0; lhsc.iterate (j, &lhsp);)
1021 : {
1022 4669961 : varinfo_t lhsv, rhsv;
1023 4669961 : rhsp = &rhsc[k];
1024 4669961 : lhsv = get_varinfo (lhsp->var);
1025 4669961 : rhsv = get_varinfo (rhsp->var);
1026 4669961 : if (lhsv->may_have_pointers
1027 4669961 : && (lhsv->is_full_var
1028 4090970 : || rhsv->is_full_var
1029 3186491 : || ranges_overlap_p (lhsv->offset + rhsoffset, lhsv->size,
1030 3186491 : rhsv->offset + lhsoffset, rhsv->size)))
1031 3495874 : process_constraint (new_constraint (*lhsp, *rhsp));
1032 4669961 : if (!rhsv->is_full_var
1033 3323640 : && (lhsv->is_full_var
1034 3186491 : || (lhsv->offset + rhsoffset + lhsv->size
1035 3186491 : > rhsv->offset + lhsoffset + rhsv->size)))
1036 : {
1037 1318917 : ++k;
1038 2931811 : if (k >= rhsc.length ())
1039 : break;
1040 : }
1041 : else
1042 3351044 : ++j;
1043 : }
1044 1686106 : }
1045 : else
1046 0 : gcc_unreachable ();
1047 2601969 : }
1048 :
1049 : /* Create constraints ID = { rhsc }. */
1050 :
1051 : static void
1052 58163603 : make_constraints_to (unsigned id, const vec<ce_s> &rhsc)
1053 : {
1054 58163603 : struct constraint_expr *c;
1055 58163603 : struct constraint_expr includes;
1056 58163603 : unsigned int j;
1057 :
1058 58163603 : includes.var = id;
1059 58163603 : includes.offset = 0;
1060 58163603 : includes.type = SCALAR;
1061 :
1062 119663405 : FOR_EACH_VEC_ELT (rhsc, j, c)
1063 61499802 : process_constraint (new_constraint (includes, *c));
1064 58163603 : }
1065 :
1066 : /* Create a constraint ID = OP. */
1067 :
1068 : static void
1069 57993671 : make_constraint_to (unsigned id, tree op)
1070 : {
1071 57993671 : auto_vec<ce_s> rhsc;
1072 57993671 : get_constraint_for_rhs (op, &rhsc);
1073 57993671 : make_constraints_to (id, rhsc);
1074 57993671 : }
1075 :
1076 : /* Create a constraint ID = &FROM. */
1077 :
1078 : static void
1079 11881792 : make_constraint_from (varinfo_t vi, int from)
1080 : {
1081 11881792 : struct constraint_expr lhs, rhs;
1082 :
1083 11881792 : lhs.var = vi->id;
1084 11881792 : lhs.offset = 0;
1085 11881792 : lhs.type = SCALAR;
1086 :
1087 11881792 : rhs.var = from;
1088 11881792 : rhs.offset = 0;
1089 11881792 : rhs.type = ADDRESSOF;
1090 11881792 : process_constraint (new_constraint (lhs, rhs));
1091 11881792 : }
1092 :
1093 : /* Create a constraint ID = FROM. */
1094 :
1095 : static void
1096 79709991 : make_copy_constraint (varinfo_t vi, int from)
1097 : {
1098 79709991 : struct constraint_expr lhs, rhs;
1099 :
1100 79709991 : lhs.var = vi->id;
1101 79709991 : lhs.offset = 0;
1102 79709991 : lhs.type = SCALAR;
1103 :
1104 79709991 : rhs.var = from;
1105 79709991 : rhs.offset = 0;
1106 79709991 : rhs.type = SCALAR;
1107 79709991 : process_constraint (new_constraint (lhs, rhs));
1108 79709991 : }
1109 :
1110 : /* Make constraints necessary to make OP escape. */
1111 :
1112 : static void
1113 24105070 : 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 1299023 : make_indirect_escape_constraint (varinfo_t vi)
1123 : {
1124 1299023 : struct constraint_expr lhs, rhs;
1125 : /* escaped = *(VAR + UNKNOWN); */
1126 1299023 : lhs.type = SCALAR;
1127 1299023 : lhs.var = escaped_id;
1128 1299023 : lhs.offset = 0;
1129 1299023 : rhs.type = DEREF;
1130 1299023 : rhs.var = vi->id;
1131 1299023 : rhs.offset = UNKNOWN_OFFSET;
1132 1299023 : process_constraint (new_constraint (lhs, rhs));
1133 1299023 : }
1134 :
1135 : /* Add constraints to that the solution of VI is transitively closed. */
1136 :
1137 : static void
1138 26645278 : make_transitive_closure_constraints (varinfo_t vi)
1139 : {
1140 26645278 : struct constraint_expr lhs, rhs;
1141 :
1142 : /* VAR = *(VAR + UNKNOWN); */
1143 26645278 : lhs.type = SCALAR;
1144 26645278 : lhs.var = vi->id;
1145 26645278 : lhs.offset = 0;
1146 26645278 : rhs.type = DEREF;
1147 26645278 : rhs.var = vi->id;
1148 26645278 : rhs.offset = UNKNOWN_OFFSET;
1149 26645278 : process_constraint (new_constraint (lhs, rhs));
1150 26645278 : }
1151 :
1152 : /* Add constraints to that the solution of VI has all subvariables added. */
1153 :
1154 : static void
1155 32469308 : make_any_offset_constraints (varinfo_t vi)
1156 : {
1157 32469308 : struct constraint_expr lhs, rhs;
1158 :
1159 : /* VAR = VAR + UNKNOWN; */
1160 32469308 : lhs.type = SCALAR;
1161 32469308 : lhs.var = vi->id;
1162 32469308 : lhs.offset = 0;
1163 32469308 : rhs.type = SCALAR;
1164 32469308 : rhs.var = vi->id;
1165 32469308 : rhs.offset = UNKNOWN_OFFSET;
1166 32469308 : process_constraint (new_constraint (lhs, rhs));
1167 32469308 : }
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 1066513 : build_fake_var_decl (tree type)
1176 : {
1177 1066513 : tree decl = (tree) XOBNEW (&fake_var_decl_obstack, struct tree_var_decl);
1178 1066513 : memset (decl, 0, sizeof (struct tree_var_decl));
1179 1066513 : TREE_SET_CODE (decl, VAR_DECL);
1180 1066513 : TREE_TYPE (decl) = type;
1181 1066513 : DECL_UID (decl) = allocate_decl_uid ();
1182 1066513 : SET_DECL_PT_UID (decl, -1);
1183 1066513 : layout_decl (decl, 0);
1184 1066513 : return decl;
1185 : }
1186 :
1187 : /* Create a new artificial heap variable with NAME.
1188 : Return the created variable. */
1189 :
1190 : static varinfo_t
1191 445729 : make_heapvar (const char *name, bool add_id)
1192 : {
1193 445729 : varinfo_t vi;
1194 445729 : tree heapvar;
1195 :
1196 445729 : heapvar = build_fake_var_decl (ptr_type_node);
1197 445729 : DECL_EXTERNAL (heapvar) = 1;
1198 :
1199 445729 : vi = new_var_info (heapvar, name, add_id);
1200 445729 : vi->is_heap_var = true;
1201 445729 : vi->is_unknown_size_var = true;
1202 445729 : vi->offset = 0;
1203 445729 : vi->fullsize = ~0;
1204 445729 : vi->size = ~0;
1205 445729 : vi->is_full_var = true;
1206 445729 : insert_vi_for_tree (heapvar, vi);
1207 :
1208 445729 : 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 13568 : make_constraint_from_restrict (varinfo_t lhs, const char *name, bool add_id)
1217 : {
1218 13568 : varinfo_t vi = make_heapvar (name, add_id);
1219 13568 : vi->is_restrict_var = 1;
1220 13568 : vi->is_global_var = 1;
1221 13568 : vi->may_have_pointers = 1;
1222 13568 : make_constraint_from (lhs, vi->id);
1223 13568 : 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 13568 : make_constraint_from_global_restrict (varinfo_t lhs, const char *name,
1233 : bool add_id)
1234 : {
1235 13568 : varinfo_t vi = make_constraint_from_restrict (lhs, name, add_id);
1236 13568 : make_copy_constraint (vi, nonlocal_id);
1237 13568 : 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 31272816 : handle_call_arg (gcall *stmt, tree arg, vec<ce_s> *results, int flags,
1284 : int callescape_id, bool writes_global_memory)
1285 : {
1286 31272816 : int relevant_indirect_flags = EAF_NO_INDIRECT_CLOBBER | EAF_NO_INDIRECT_READ
1287 : | EAF_NO_INDIRECT_ESCAPE;
1288 31272816 : int relevant_flags = relevant_indirect_flags
1289 : | EAF_NO_DIRECT_CLOBBER
1290 : | EAF_NO_DIRECT_READ
1291 : | EAF_NO_DIRECT_ESCAPE;
1292 31272816 : if (gimple_call_lhs (stmt))
1293 : {
1294 11731154 : relevant_flags |= EAF_NOT_RETURNED_DIRECTLY | EAF_NOT_RETURNED_INDIRECTLY;
1295 11731154 : 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 11731154 : if (flags & EAF_NO_DIRECT_READ)
1303 2158633 : 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 31272816 : if ((flags & EAF_UNUSED) || ((flags & relevant_flags) == relevant_flags))
1310 : return;
1311 :
1312 : /* Produce varinfo for direct accesses to ARG. */
1313 29976655 : varinfo_t tem = new_var_info (NULL_TREE, "callarg", true);
1314 29976655 : tem->is_reg_var = true;
1315 29976655 : make_constraint_to (tem->id, arg);
1316 29976655 : make_any_offset_constraints (tem);
1317 :
1318 29976655 : 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 29976655 : if (((flags & EAF_NO_INDIRECT_CLOBBER) != 0)
1324 29976655 : == ((flags & EAF_NO_DIRECT_CLOBBER) != 0)
1325 28529105 : && (((flags & EAF_NO_INDIRECT_READ) != 0)
1326 28529105 : == ((flags & EAF_NO_DIRECT_READ) != 0))
1327 27541022 : && (((flags & EAF_NO_INDIRECT_ESCAPE) != 0)
1328 27541022 : == ((flags & EAF_NO_DIRECT_ESCAPE) != 0))
1329 26964851 : && (((flags & EAF_NOT_RETURNED_INDIRECTLY) != 0)
1330 26964851 : == ((flags & EAF_NOT_RETURNED_DIRECTLY) != 0)))
1331 : {
1332 24954792 : make_transitive_closure_constraints (tem);
1333 24954792 : callarg_transitive = true;
1334 : }
1335 :
1336 : /* If necessary, produce varinfo for indirect accesses to ARG. */
1337 29976655 : varinfo_t indir_tem = NULL;
1338 24954792 : if (!callarg_transitive
1339 5021863 : && (flags & relevant_indirect_flags) != relevant_indirect_flags)
1340 : {
1341 1807365 : struct constraint_expr lhs, rhs;
1342 1807365 : indir_tem = new_var_info (NULL_TREE, "indircallarg", true);
1343 1807365 : indir_tem->is_reg_var = true;
1344 :
1345 : /* indir_term = *tem. */
1346 1807365 : lhs.type = SCALAR;
1347 1807365 : lhs.var = indir_tem->id;
1348 1807365 : lhs.offset = 0;
1349 :
1350 1807365 : rhs.type = DEREF;
1351 1807365 : rhs.var = tem->id;
1352 1807365 : rhs.offset = UNKNOWN_OFFSET;
1353 1807365 : process_constraint (new_constraint (lhs, rhs));
1354 :
1355 1807365 : 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 1807365 : if (!(flags & EAF_NO_INDIRECT_READ))
1360 1690486 : make_transitive_closure_constraints (indir_tem);
1361 1807365 : gcc_checking_assert (!(flags & EAF_NO_DIRECT_READ));
1362 : }
1363 :
1364 29976655 : if (gimple_call_lhs (stmt))
1365 : {
1366 11464710 : if (!(flags & EAF_NOT_RETURNED_DIRECTLY))
1367 : {
1368 10469821 : struct constraint_expr cexpr;
1369 10469821 : cexpr.var = tem->id;
1370 10469821 : cexpr.type = SCALAR;
1371 10469821 : cexpr.offset = 0;
1372 10469821 : results->safe_push (cexpr);
1373 : }
1374 11464710 : if (!callarg_transitive & !(flags & EAF_NOT_RETURNED_INDIRECTLY))
1375 : {
1376 638291 : struct constraint_expr cexpr;
1377 638291 : cexpr.var = indir_tem->id;
1378 638291 : cexpr.type = SCALAR;
1379 638291 : cexpr.offset = 0;
1380 638291 : results->safe_push (cexpr);
1381 : }
1382 : }
1383 :
1384 29976655 : if (!(flags & EAF_NO_DIRECT_READ))
1385 : {
1386 27686095 : varinfo_t uses = get_call_use_vi (stmt);
1387 27686095 : make_copy_constraint (uses, tem->id);
1388 27686095 : if (!callarg_transitive & !(flags & EAF_NO_INDIRECT_READ))
1389 1690486 : make_copy_constraint (uses, indir_tem->id);
1390 : }
1391 : else
1392 : /* To read indirectly we need to read directly. */
1393 2290560 : gcc_checking_assert (flags & EAF_NO_INDIRECT_READ);
1394 :
1395 29976655 : if (!(flags & EAF_NO_DIRECT_CLOBBER))
1396 : {
1397 24678753 : struct constraint_expr lhs, rhs;
1398 :
1399 : /* *arg = callescape. */
1400 24678753 : lhs.type = DEREF;
1401 24678753 : lhs.var = tem->id;
1402 24678753 : lhs.offset = 0;
1403 :
1404 24678753 : rhs.type = SCALAR;
1405 24678753 : rhs.var = callescape_id;
1406 24678753 : rhs.offset = 0;
1407 24678753 : process_constraint (new_constraint (lhs, rhs));
1408 :
1409 : /* callclobbered = arg. */
1410 24678753 : make_copy_constraint (get_call_clobber_vi (stmt), tem->id);
1411 : }
1412 29976655 : if (!callarg_transitive & !(flags & EAF_NO_INDIRECT_CLOBBER))
1413 : {
1414 1491108 : struct constraint_expr lhs, rhs;
1415 :
1416 : /* *indir_arg = callescape. */
1417 1491108 : lhs.type = DEREF;
1418 1491108 : lhs.var = indir_tem->id;
1419 1491108 : lhs.offset = 0;
1420 :
1421 1491108 : rhs.type = SCALAR;
1422 1491108 : rhs.var = callescape_id;
1423 1491108 : rhs.offset = 0;
1424 1491108 : process_constraint (new_constraint (lhs, rhs));
1425 :
1426 : /* callclobbered = indir_arg. */
1427 1491108 : make_copy_constraint (get_call_clobber_vi (stmt), indir_tem->id);
1428 : }
1429 :
1430 29976655 : if (!(flags & (EAF_NO_DIRECT_ESCAPE | EAF_NO_INDIRECT_ESCAPE)))
1431 : {
1432 23085851 : struct constraint_expr lhs, rhs;
1433 :
1434 : /* callescape = arg; */
1435 23085851 : lhs.var = callescape_id;
1436 23085851 : lhs.offset = 0;
1437 23085851 : lhs.type = SCALAR;
1438 :
1439 23085851 : rhs.var = tem->id;
1440 23085851 : rhs.offset = 0;
1441 23085851 : rhs.type = SCALAR;
1442 23085851 : process_constraint (new_constraint (lhs, rhs));
1443 :
1444 23085851 : if (writes_global_memory)
1445 22287202 : make_escape_constraint (arg);
1446 : }
1447 6890804 : else if (!callarg_transitive & !(flags & EAF_NO_INDIRECT_ESCAPE))
1448 : {
1449 1419002 : struct constraint_expr lhs, rhs;
1450 :
1451 : /* callescape = *(indir_arg + UNKNOWN); */
1452 1419002 : lhs.var = callescape_id;
1453 1419002 : lhs.offset = 0;
1454 1419002 : lhs.type = SCALAR;
1455 :
1456 1419002 : rhs.var = indir_tem->id;
1457 1419002 : rhs.offset = 0;
1458 1419002 : rhs.type = SCALAR;
1459 1419002 : process_constraint (new_constraint (lhs, rhs));
1460 :
1461 1419002 : if (writes_global_memory)
1462 1299023 : 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 15748371 : 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 15748371 : determine_global_memory_access (stmt, &writes_global_memory,
1481 : &reads_global_memory,
1482 : NULL);
1483 :
1484 15748371 : 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 15748371 : struct constraint_expr lhs, rhs;
1490 :
1491 15748371 : lhs.type = SCALAR;
1492 15748371 : lhs.var = callescape->id;
1493 15748371 : lhs.offset = 0;
1494 :
1495 15748371 : rhs.type = reads_global_memory ? SCALAR : ADDRESSOF;
1496 15748371 : rhs.var = nonlocal_id;
1497 15748371 : rhs.offset = 0;
1498 :
1499 15748371 : process_constraint (new_constraint (lhs, rhs));
1500 15748371 : results->safe_push (rhs);
1501 :
1502 15748371 : varinfo_t uses = get_call_use_vi (stmt);
1503 15748371 : make_copy_constraint (uses, callescape->id);
1504 :
1505 62685522 : for (unsigned i = 0; i < gimple_call_num_args (stmt); ++i)
1506 : {
1507 31188780 : tree arg = gimple_call_arg (stmt, i);
1508 31188780 : int flags = gimple_call_arg_flags (stmt, i);
1509 31188780 : handle_call_arg (stmt, arg, results,
1510 : flags | implicit_eaf_flags,
1511 31188780 : callescape->id, writes_global_memory);
1512 : }
1513 :
1514 : /* The static chain escapes as well. */
1515 15748371 : if (gimple_call_chain (stmt))
1516 84036 : handle_call_arg (stmt, gimple_call_chain (stmt), results,
1517 : implicit_eaf_flags
1518 84036 : | gimple_call_static_chain_flags (stmt),
1519 84036 : callescape->id, writes_global_memory);
1520 :
1521 : /* And if we applied NRV the address of the return slot escapes as well. */
1522 15748371 : if (gimple_call_return_slot_opt_p (stmt)
1523 643808 : && gimple_call_lhs (stmt) != NULL_TREE
1524 16363070 : && TREE_ADDRESSABLE (TREE_TYPE (gimple_call_lhs (stmt))))
1525 : {
1526 88782 : int flags = gimple_call_retslot_flags (stmt);
1527 88782 : const int relevant_flags = EAF_NO_DIRECT_ESCAPE
1528 : | EAF_NOT_RETURNED_DIRECTLY;
1529 :
1530 88782 : if (!(flags & EAF_UNUSED) && (flags & relevant_flags) != relevant_flags)
1531 : {
1532 67081 : auto_vec<ce_s> tmpc;
1533 :
1534 67081 : get_constraint_for_address_of (gimple_call_lhs (stmt), &tmpc);
1535 :
1536 67081 : if (!(flags & EAF_NO_DIRECT_ESCAPE))
1537 : {
1538 67079 : make_constraints_to (callescape->id, tmpc);
1539 67079 : if (writes_global_memory)
1540 65597 : make_constraints_to (escaped_id, tmpc);
1541 : }
1542 67081 : if (!(flags & EAF_NOT_RETURNED_DIRECTLY))
1543 : {
1544 : struct constraint_expr *c;
1545 : unsigned i;
1546 198747 : FOR_EACH_VEC_ELT (tmpc, i, c)
1547 65833 : results->safe_push (*c);
1548 : }
1549 67081 : }
1550 : }
1551 15748371 : }
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 5998033 : handle_lhs_call (gcall *stmt, tree lhs, int flags, vec<ce_s> &rhsc,
1559 : tree fndecl)
1560 : {
1561 5998033 : auto_vec<ce_s> lhsc;
1562 :
1563 5998033 : get_constraint_for (lhs, &lhsc);
1564 : /* If the store is to a global decl make sure to
1565 : add proper escape constraints. */
1566 5998033 : lhs = get_base_address (lhs);
1567 5998033 : if (lhs
1568 5998033 : && DECL_P (lhs)
1569 7028698 : && 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 5998033 : if (flags & ERF_RETURNS_ARG
1581 5998033 : && (flags & ERF_RETURN_ARG_MASK) < gimple_call_num_args (stmt))
1582 : {
1583 107254 : tree arg;
1584 107254 : rhsc.truncate (0);
1585 107254 : arg = gimple_call_arg (stmt, flags & ERF_RETURN_ARG_MASK);
1586 107254 : get_constraint_for (arg, &rhsc);
1587 107254 : process_all_all_constraints (lhsc, rhsc);
1588 107254 : rhsc.truncate (0);
1589 : }
1590 5890779 : else if (flags & ERF_NOALIAS)
1591 : {
1592 399211 : varinfo_t vi;
1593 399211 : struct constraint_expr tmpc;
1594 399211 : rhsc.truncate (0);
1595 399211 : 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 399211 : DECL_EXTERNAL (vi->decl) = 0;
1599 399211 : 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 399211 : if (!fndecl
1604 399211 : || !fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
1605 236907 : make_constraint_from (vi, nonlocal_id);
1606 399211 : tmpc.var = vi->id;
1607 399211 : tmpc.offset = 0;
1608 399211 : tmpc.type = ADDRESSOF;
1609 399211 : rhsc.safe_push (tmpc);
1610 399211 : process_all_all_constraints (lhsc, rhsc);
1611 399211 : rhsc.truncate (0);
1612 : }
1613 : else
1614 5491568 : process_all_all_constraints (lhsc, rhsc);
1615 5998033 : }
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 5310768 : find_func_aliases_for_builtin_call (struct function *fn, gcall *t)
1641 : {
1642 5310768 : tree fndecl = gimple_call_fndecl (t);
1643 5310768 : auto_vec<ce_s, 2> lhsc;
1644 5310768 : auto_vec<ce_s, 4> rhsc;
1645 5310768 : varinfo_t fi;
1646 :
1647 5310768 : 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 4828350 : 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 312719 : case BUILT_IN_STRCPY:
1658 312719 : case BUILT_IN_STRNCPY:
1659 312719 : case BUILT_IN_BCOPY:
1660 312719 : case BUILT_IN_MEMCPY:
1661 312719 : case BUILT_IN_MEMMOVE:
1662 312719 : case BUILT_IN_MEMPCPY:
1663 312719 : case BUILT_IN_STPCPY:
1664 312719 : case BUILT_IN_STPNCPY:
1665 312719 : case BUILT_IN_STRCAT:
1666 312719 : case BUILT_IN_STRNCAT:
1667 312719 : case BUILT_IN_STRCPY_CHK:
1668 312719 : case BUILT_IN_STRNCPY_CHK:
1669 312719 : case BUILT_IN_MEMCPY_CHK:
1670 312719 : case BUILT_IN_MEMMOVE_CHK:
1671 312719 : case BUILT_IN_MEMPCPY_CHK:
1672 312719 : case BUILT_IN_STPCPY_CHK:
1673 312719 : case BUILT_IN_STPNCPY_CHK:
1674 312719 : case BUILT_IN_STRCAT_CHK:
1675 312719 : case BUILT_IN_STRNCAT_CHK:
1676 312719 : case BUILT_IN_TM_MEMCPY:
1677 312719 : case BUILT_IN_TM_MEMMOVE:
1678 312719 : {
1679 312719 : tree res = gimple_call_lhs (t);
1680 625438 : tree dest = gimple_call_arg (t, (DECL_FUNCTION_CODE (fndecl)
1681 : == BUILT_IN_BCOPY ? 1 : 0));
1682 625438 : tree src = gimple_call_arg (t, (DECL_FUNCTION_CODE (fndecl)
1683 312719 : == BUILT_IN_BCOPY ? 0 : 1));
1684 312719 : if (res != NULL_TREE)
1685 : {
1686 26845 : get_constraint_for (res, &lhsc);
1687 26845 : if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_MEMPCPY
1688 23748 : || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPCPY
1689 22575 : || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPNCPY
1690 20813 : || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_MEMPCPY_CHK
1691 20484 : || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPCPY_CHK
1692 47056 : || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPNCPY_CHK)
1693 6906 : get_constraint_for_ptr_offset (dest, NULL_TREE, &rhsc);
1694 : else
1695 19939 : get_constraint_for (dest, &rhsc);
1696 26845 : process_all_all_constraints (lhsc, rhsc);
1697 26845 : lhsc.truncate (0);
1698 26845 : rhsc.truncate (0);
1699 : }
1700 312719 : get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
1701 312719 : get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
1702 312719 : do_deref (&lhsc);
1703 312719 : do_deref (&rhsc);
1704 312719 : process_all_all_constraints (lhsc, rhsc);
1705 312719 : return true;
1706 : }
1707 75415 : case BUILT_IN_MEMSET:
1708 75415 : case BUILT_IN_MEMSET_CHK:
1709 75415 : case BUILT_IN_TM_MEMSET:
1710 75415 : {
1711 75415 : tree res = gimple_call_lhs (t);
1712 75415 : tree dest = gimple_call_arg (t, 0);
1713 75415 : unsigned i;
1714 75415 : ce_s *lhsp;
1715 75415 : struct constraint_expr ac;
1716 75415 : if (res != NULL_TREE)
1717 : {
1718 5365 : get_constraint_for (res, &lhsc);
1719 5365 : get_constraint_for (dest, &rhsc);
1720 5365 : process_all_all_constraints (lhsc, rhsc);
1721 5365 : lhsc.truncate (0);
1722 : }
1723 75415 : get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
1724 75415 : do_deref (&lhsc);
1725 75415 : if (flag_delete_null_pointer_checks
1726 150689 : && 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 75415 : ac.offset = 0;
1737 5468207 : FOR_EACH_VEC_ELT (lhsc, i, lhsp)
1738 82024 : 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 32831 : case BUILT_IN_ALLOCA:
1746 32831 : case BUILT_IN_ALLOCA_WITH_ALIGN:
1747 32831 : case BUILT_IN_ALLOCA_WITH_ALIGN_AND_MAX:
1748 32831 : {
1749 32831 : tree ptr = gimple_call_lhs (t);
1750 32831 : if (ptr == NULL_TREE)
1751 : return true;
1752 32818 : get_constraint_for (ptr, &lhsc);
1753 32818 : 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 32818 : DECL_EXTERNAL (vi->decl) = 0;
1757 32818 : vi->is_global_var = 0;
1758 32818 : vi->is_heap_var = 0;
1759 32818 : struct constraint_expr tmpc;
1760 32818 : tmpc.var = vi->id;
1761 32818 : tmpc.offset = 0;
1762 32818 : tmpc.type = ADDRESSOF;
1763 32818 : rhsc.safe_push (tmpc);
1764 32818 : process_all_all_constraints (lhsc, rhsc);
1765 32818 : 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 134896 : case BUILT_IN_SINCOS:
1801 134896 : case BUILT_IN_SINCOSF:
1802 134896 : case BUILT_IN_SINCOSL:
1803 134896 : case BUILT_IN_FREXP:
1804 134896 : case BUILT_IN_FREXPF:
1805 134896 : case BUILT_IN_FREXPL:
1806 134896 : case BUILT_IN_GAMMA_R:
1807 134896 : case BUILT_IN_GAMMAF_R:
1808 134896 : case BUILT_IN_GAMMAL_R:
1809 134896 : case BUILT_IN_LGAMMA_R:
1810 134896 : case BUILT_IN_LGAMMAF_R:
1811 134896 : case BUILT_IN_LGAMMAL_R:
1812 134896 : case BUILT_IN_MODF:
1813 134896 : case BUILT_IN_MODFF:
1814 134896 : case BUILT_IN_MODFL:
1815 134896 : case BUILT_IN_REMQUO:
1816 134896 : case BUILT_IN_REMQUOF:
1817 134896 : case BUILT_IN_REMQUOL:
1818 134896 : case BUILT_IN_FREE:
1819 134896 : return true;
1820 17555 : case BUILT_IN_STRDUP:
1821 17555 : case BUILT_IN_STRNDUP:
1822 17555 : case BUILT_IN_REALLOC:
1823 17555 : if (gimple_call_lhs (t))
1824 : {
1825 17506 : auto_vec<ce_s> rhsc;
1826 17506 : handle_lhs_call (t, gimple_call_lhs (t),
1827 17506 : gimple_call_return_flags (t) | ERF_NOALIAS,
1828 : rhsc, fndecl);
1829 17506 : get_constraint_for_ptr_offset (gimple_call_lhs (t),
1830 : NULL_TREE, &lhsc);
1831 17506 : get_constraint_for_ptr_offset (gimple_call_arg (t, 0),
1832 : NULL_TREE, &rhsc);
1833 17506 : do_deref (&lhsc);
1834 17506 : do_deref (&rhsc);
1835 17506 : process_all_all_constraints (lhsc, rhsc);
1836 17506 : lhsc.truncate (0);
1837 17506 : 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 17506 : if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_REALLOC)
1842 : {
1843 15849 : get_constraint_for (gimple_call_lhs (t), &lhsc);
1844 15849 : get_constraint_for (gimple_call_arg (t, 0), &rhsc);
1845 15849 : process_all_all_constraints (lhsc, rhsc);
1846 : }
1847 17506 : return true;
1848 17506 : }
1849 : break;
1850 : /* String / character search functions return a pointer into the
1851 : source string or NULL. */
1852 13208 : case BUILT_IN_INDEX:
1853 13208 : case BUILT_IN_STRCHR:
1854 13208 : case BUILT_IN_STRRCHR:
1855 13208 : case BUILT_IN_MEMCHR:
1856 13208 : case BUILT_IN_STRSTR:
1857 13208 : case BUILT_IN_STRPBRK:
1858 13208 : if (gimple_call_lhs (t))
1859 : {
1860 13208 : tree src = gimple_call_arg (t, 0);
1861 13208 : get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
1862 13208 : constraint_expr nul;
1863 13208 : nul.var = nothing_id;
1864 13208 : nul.offset = 0;
1865 13208 : nul.type = ADDRESSOF;
1866 13208 : rhsc.safe_push (nul);
1867 13208 : get_constraint_for (gimple_call_lhs (t), &lhsc);
1868 13208 : 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 635304 : case BUILT_IN_STRCMP:
1875 635304 : case BUILT_IN_STRCMP_EQ:
1876 635304 : case BUILT_IN_STRNCMP:
1877 635304 : case BUILT_IN_STRNCMP_EQ:
1878 635304 : case BUILT_IN_STRCASECMP:
1879 635304 : case BUILT_IN_STRNCASECMP:
1880 635304 : case BUILT_IN_MEMCMP:
1881 635304 : case BUILT_IN_BCMP:
1882 635304 : case BUILT_IN_STRSPN:
1883 635304 : case BUILT_IN_STRCSPN:
1884 635304 : {
1885 635304 : varinfo_t uses = get_call_use_vi (t);
1886 635304 : make_any_offset_constraints (uses);
1887 635304 : make_constraint_to (uses->id, gimple_call_arg (t, 0));
1888 635304 : make_constraint_to (uses->id, gimple_call_arg (t, 1));
1889 : /* No constraints are necessary for the return value. */
1890 635304 : return true;
1891 : }
1892 49984 : case BUILT_IN_STRLEN:
1893 49984 : {
1894 49984 : varinfo_t uses = get_call_use_vi (t);
1895 49984 : make_any_offset_constraints (uses);
1896 49984 : make_constraint_to (uses->id, gimple_call_arg (t, 0));
1897 : /* No constraints are necessary for the return value. */
1898 49984 : return true;
1899 : }
1900 67824 : case BUILT_IN_OBJECT_SIZE:
1901 67824 : case BUILT_IN_CONSTANT_P:
1902 67824 : {
1903 : /* No constraints are necessary for the return value or the
1904 : arguments. */
1905 67824 : 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 20190 : case BUILT_IN_VA_START:
1999 20190 : {
2000 20190 : tree valist = gimple_call_arg (t, 0);
2001 20190 : struct constraint_expr rhs, *lhsp;
2002 20190 : unsigned i;
2003 20190 : get_constraint_for_ptr_offset (valist, NULL_TREE, &lhsc);
2004 20190 : 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 20190 : 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 40547 : FOR_EACH_VEC_ELT (lhsc, i, lhsp)
2021 20357 : process_constraint (new_constraint (*lhsp, rhs));
2022 : /* va_list is clobbered. */
2023 20190 : make_constraint_to (get_call_clobber_vi (t)->id, valist);
2024 20190 : return true;
2025 : }
2026 : /* va_end doesn't have any effect that matters. */
2027 9807 : case BUILT_IN_VA_END:
2028 9807 : 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 55410 : case BUILT_IN_GOMP_PARALLEL:
2049 55410 : case BUILT_IN_GOACC_PARALLEL:
2050 55410 : {
2051 55410 : 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 5310768 : }
2096 :
2097 : /* Create constraints for the call T. */
2098 :
2099 : static void
2100 18675190 : find_func_aliases_for_call (struct function *fn, gcall *t)
2101 : {
2102 18675190 : tree fndecl = gimple_call_fndecl (t);
2103 18675190 : varinfo_t fi;
2104 :
2105 18675190 : if (fndecl != NULL_TREE
2106 17370125 : && fndecl_built_in_p (fndecl)
2107 23985958 : && find_func_aliases_for_builtin_call (fn, t))
2108 : return;
2109 :
2110 17272339 : if (gimple_call_internal_p (t, IFN_VA_ARG)
2111 17272339 : && gimple_call_lhs (t))
2112 : {
2113 8437 : tree valist = gimple_call_arg (t, 0);
2114 8437 : auto_vec<ce_s, 1> rhsc, lhsc;
2115 8437 : get_constraint_for_rhs (valist, &rhsc);
2116 8437 : do_deref (&rhsc);
2117 8437 : get_constraint_for (gimple_call_lhs (t), &lhsc);
2118 8437 : process_all_all_constraints (lhsc, rhsc);
2119 : /* va_list is used and clobbered. */
2120 8437 : make_constraint_to (get_call_use_vi (t)->id, valist);
2121 8437 : make_constraint_to (get_call_clobber_vi (t)->id, valist);
2122 8437 : return;
2123 8437 : }
2124 :
2125 17263902 : if (gimple_call_internal_p (t, IFN_DEFERRED_INIT))
2126 : return;
2127 :
2128 : /* .ASSUME produces a flag and has no observable side-effects. */
2129 17036498 : if (gimple_call_internal_p (t, IFN_ASSUME))
2130 : return;
2131 :
2132 17036141 : fi = get_fi_for_callee (t);
2133 17036141 : if (!in_ipa_mode
2134 244332 : || (fi->decl && fndecl && !fi->is_fn_info))
2135 : {
2136 16848916 : auto_vec<ce_s, 16> rhsc;
2137 16848916 : int flags = gimple_call_flags (t);
2138 :
2139 : /* Const functions can return their arguments and addresses
2140 : of global memory but not of escaped memory. */
2141 16848916 : if (flags & (ECF_CONST|ECF_NOVOPS))
2142 : {
2143 1659328 : if (gimple_call_lhs (t))
2144 942177 : handle_rhs_call (t, &rhsc, implicit_const_eaf_flags, false, false);
2145 : }
2146 : /* Pure functions can return addresses in and of memory
2147 : reachable from their arguments, but they are not an escape
2148 : point for reachable memory of their arguments. */
2149 15189588 : else if (flags & (ECF_PURE|ECF_LOOPING_CONST_OR_PURE))
2150 572820 : handle_rhs_call (t, &rhsc, implicit_pure_eaf_flags, false, true);
2151 : /* If the call is to a replaceable operator delete and results
2152 : from a delete expression as opposed to a direct call to
2153 : such operator, then the effects for PTA (in particular
2154 : the escaping of the pointer) can be ignored. */
2155 14616768 : else if (fndecl
2156 14002420 : && flag_assume_sane_operators_new_delete
2157 14002014 : && DECL_IS_OPERATOR_DELETE_P (fndecl)
2158 387538 : && DECL_IS_REPLACEABLE_OPERATOR (fndecl)
2159 15003878 : && gimple_call_from_new_or_delete (t))
2160 : ;
2161 : else
2162 14233374 : handle_rhs_call (t, &rhsc, 0, true, true);
2163 16848916 : if (gimple_call_lhs (t))
2164 5980527 : handle_lhs_call (t, gimple_call_lhs (t),
2165 : gimple_call_return_flags (t), rhsc, fndecl);
2166 16848916 : }
2167 : else
2168 : {
2169 187225 : auto_vec<ce_s, 2> rhsc;
2170 187225 : tree lhsop;
2171 187225 : unsigned j;
2172 :
2173 : /* Assign all the passed arguments to the appropriate incoming
2174 : parameters of the function. */
2175 997640 : for (j = 0; j < gimple_call_num_args (t); j++)
2176 : {
2177 810415 : tree arg = gimple_call_arg (t, j);
2178 810415 : find_func_aliases_for_call_arg (fi, j, arg);
2179 : }
2180 :
2181 : /* If we are returning a value, assign it to the result. */
2182 187225 : lhsop = gimple_call_lhs (t);
2183 187225 : if (lhsop)
2184 : {
2185 166800 : auto_vec<ce_s, 2> lhsc;
2186 166800 : struct constraint_expr rhs;
2187 166800 : struct constraint_expr *lhsp;
2188 167654 : bool aggr_p = aggregate_value_p (lhsop, gimple_call_fntype (t));
2189 :
2190 166800 : get_constraint_for (lhsop, &lhsc);
2191 166800 : rhs = get_function_part_constraint (fi, fi_result);
2192 166800 : if (aggr_p)
2193 : {
2194 10 : auto_vec<ce_s, 2> tem;
2195 10 : tem.quick_push (rhs);
2196 10 : do_deref (&tem);
2197 10 : gcc_checking_assert (tem.length () == 1);
2198 10 : rhs = tem[0];
2199 10 : }
2200 333605 : FOR_EACH_VEC_ELT (lhsc, j, lhsp)
2201 166805 : process_constraint (new_constraint (*lhsp, rhs));
2202 :
2203 : /* If we pass the result decl by reference, honor that. */
2204 166800 : if (aggr_p)
2205 : {
2206 10 : struct constraint_expr lhs;
2207 10 : struct constraint_expr *rhsp;
2208 :
2209 10 : get_constraint_for_address_of (lhsop, &rhsc);
2210 10 : lhs = get_function_part_constraint (fi, fi_result);
2211 30 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
2212 10 : process_constraint (new_constraint (lhs, *rhsp));
2213 10 : rhsc.truncate (0);
2214 : }
2215 166800 : }
2216 :
2217 : /* If we use a static chain, pass it along. */
2218 187225 : if (gimple_call_chain (t))
2219 : {
2220 278 : struct constraint_expr lhs;
2221 278 : struct constraint_expr *rhsp;
2222 :
2223 278 : get_constraint_for (gimple_call_chain (t), &rhsc);
2224 278 : lhs = get_function_part_constraint (fi, fi_static_chain);
2225 1112 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
2226 278 : process_constraint (new_constraint (lhs, *rhsp));
2227 : }
2228 187225 : }
2229 : }
2230 :
2231 : /* Walk statement T setting up aliasing constraints according to the
2232 : references found in T. This function is the main part of the
2233 : constraint builder. AI points to auxiliary alias information used
2234 : when building alias sets and computing alias grouping heuristics. */
2235 :
2236 : static void
2237 280344856 : find_func_aliases (struct function *fn, gimple *origt)
2238 : {
2239 280344856 : gimple *t = origt;
2240 280344856 : auto_vec<ce_s, 16> lhsc;
2241 280344856 : auto_vec<ce_s, 16> rhsc;
2242 280344856 : varinfo_t fi;
2243 :
2244 : /* Now build constraints expressions. */
2245 280344856 : if (gimple_code (t) == GIMPLE_PHI)
2246 : {
2247 : /* For a phi node, assign all the arguments to
2248 : the result. */
2249 6300887 : get_constraint_for (gimple_phi_result (t), &lhsc);
2250 27910577 : for (unsigned i = 0; i < gimple_phi_num_args (t); i++)
2251 : {
2252 15308803 : get_constraint_for_rhs (gimple_phi_arg_def (t, i), &rhsc);
2253 15308803 : process_all_all_constraints (lhsc, rhsc);
2254 15308803 : rhsc.truncate (0);
2255 : }
2256 : }
2257 : /* In IPA mode, we need to generate constraints to pass call
2258 : arguments through their calls. There are two cases,
2259 : either a GIMPLE_CALL returning a value, or just a plain
2260 : GIMPLE_CALL when we are not.
2261 :
2262 : In non-ipa mode, we need to generate constraints for each
2263 : pointer passed by address. */
2264 274043969 : else if (is_gimple_call (t))
2265 18675190 : find_func_aliases_for_call (fn, as_a <gcall *> (t));
2266 :
2267 : /* Otherwise, just a regular assignment statement. Only care about
2268 : operations with pointer result, others are dealt with as escape
2269 : points if they have pointer operands. */
2270 255368779 : else if (is_gimple_assign (t))
2271 : {
2272 : /* Otherwise, just a regular assignment statement. */
2273 83125496 : tree lhsop = gimple_assign_lhs (t);
2274 83125496 : tree rhsop = (gimple_num_ops (t) == 2) ? gimple_assign_rhs1 (t) : NULL;
2275 :
2276 64982463 : if (rhsop && TREE_CLOBBER_P (rhsop))
2277 : /* Ignore clobbers, they don't actually store anything into
2278 : the LHS. */
2279 : ;
2280 59354842 : else if (rhsop && AGGREGATE_TYPE_P (TREE_TYPE (lhsop)))
2281 2601969 : do_structure_copy (lhsop, rhsop);
2282 : else
2283 : {
2284 74895906 : enum tree_code code = gimple_assign_rhs_code (t);
2285 :
2286 74895906 : get_constraint_for (lhsop, &lhsc);
2287 :
2288 74895906 : if (code == POINTER_PLUS_EXPR)
2289 2746527 : get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
2290 : gimple_assign_rhs2 (t), &rhsc);
2291 72149379 : else if (code == POINTER_DIFF_EXPR)
2292 : /* The result is not a pointer (part). */
2293 : ;
2294 71784848 : else if (code == BIT_AND_EXPR
2295 71784848 : && TREE_CODE (gimple_assign_rhs2 (t)) == INTEGER_CST)
2296 : {
2297 : /* Aligning a pointer via a BIT_AND_EXPR is offsetting
2298 : the pointer. Handle it by offsetting it by UNKNOWN. */
2299 595361 : get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
2300 : NULL_TREE, &rhsc);
2301 : }
2302 71189487 : else if (code == TRUNC_DIV_EXPR
2303 : || code == CEIL_DIV_EXPR
2304 : || code == FLOOR_DIV_EXPR
2305 71189487 : || code == ROUND_DIV_EXPR
2306 71189487 : || code == EXACT_DIV_EXPR
2307 : || code == TRUNC_MOD_EXPR
2308 70807476 : || code == CEIL_MOD_EXPR
2309 : || code == FLOOR_MOD_EXPR
2310 70638578 : || code == ROUND_MOD_EXPR)
2311 : /* Division and modulo transfer the pointer from the LHS. */
2312 552442 : get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
2313 : NULL_TREE, &rhsc);
2314 70637045 : else if (CONVERT_EXPR_CODE_P (code)
2315 70637045 : || gimple_assign_single_p (t))
2316 : /* See through conversions, single RHS are handled by
2317 : get_constraint_for_rhs. */
2318 56033885 : get_constraint_for_rhs (rhsop, &rhsc);
2319 14603160 : else if (code == COND_EXPR)
2320 : {
2321 : /* The result is a merge of both COND_EXPR arms. */
2322 11315 : auto_vec<ce_s, 2> tmp;
2323 11315 : struct constraint_expr *rhsp;
2324 11315 : unsigned i;
2325 11315 : get_constraint_for_rhs (gimple_assign_rhs2 (t), &rhsc);
2326 11315 : get_constraint_for_rhs (gimple_assign_rhs3 (t), &tmp);
2327 45260 : FOR_EACH_VEC_ELT (tmp, i, rhsp)
2328 11315 : rhsc.safe_push (*rhsp);
2329 11315 : }
2330 14591845 : else if (truth_value_p (code))
2331 : /* Truth value results are not pointer (parts). Or at least
2332 : very unreasonable obfuscation of a part. */
2333 : ;
2334 : else
2335 : {
2336 : /* All other operations are possibly offsetting merges. */
2337 13178243 : auto_vec<ce_s, 4> tmp;
2338 13178243 : struct constraint_expr *rhsp;
2339 13178243 : unsigned i, j;
2340 13178243 : get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
2341 : NULL_TREE, &rhsc);
2342 38931866 : for (i = 2; i < gimple_num_ops (t); ++i)
2343 : {
2344 12575380 : get_constraint_for_ptr_offset (gimple_op (t, i),
2345 : NULL_TREE, &tmp);
2346 37726140 : FOR_EACH_VEC_ELT (tmp, j, rhsp)
2347 12575380 : rhsc.safe_push (*rhsp);
2348 12575380 : tmp.truncate (0);
2349 : }
2350 13178243 : }
2351 74895906 : process_all_all_constraints (lhsc, rhsc);
2352 : }
2353 : /* If there is a store to a global variable the rhs escapes. */
2354 83125496 : if ((lhsop = get_base_address (lhsop)) != NULL_TREE
2355 83125496 : && DECL_P (lhsop))
2356 : {
2357 23102389 : varinfo_t vi = get_vi_for_tree (lhsop);
2358 23102389 : if ((! in_ipa_mode && vi->is_global_var)
2359 21428678 : || vi->is_ipa_escape_point)
2360 1676279 : make_escape_constraint (rhsop);
2361 : }
2362 : }
2363 : /* Handle escapes through return. */
2364 172243283 : else if (gimple_code (t) == GIMPLE_RETURN
2365 172243283 : && gimple_return_retval (as_a <greturn *> (t)) != NULL_TREE)
2366 : {
2367 2558627 : greturn *return_stmt = as_a <greturn *> (t);
2368 2558627 : tree retval = gimple_return_retval (return_stmt);
2369 2558627 : if (!in_ipa_mode)
2370 2554290 : make_constraint_to (escaped_return_id, retval);
2371 : else
2372 : {
2373 4337 : struct constraint_expr lhs ;
2374 4337 : struct constraint_expr *rhsp;
2375 4337 : unsigned i;
2376 :
2377 4337 : fi = lookup_vi_for_tree (fn->decl);
2378 4337 : lhs = get_function_part_constraint (fi, fi_result);
2379 4337 : get_constraint_for_rhs (retval, &rhsc);
2380 17350 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
2381 4339 : process_constraint (new_constraint (lhs, *rhsp));
2382 : }
2383 : }
2384 : /* Handle asms conservatively by adding escape constraints to everything. */
2385 280571993 : else if (gasm *asm_stmt = dyn_cast <gasm *> (t))
2386 : {
2387 227137 : unsigned i, noutputs;
2388 227137 : const char **oconstraints;
2389 227137 : const char *constraint;
2390 227137 : bool allows_mem, allows_reg, is_inout;
2391 :
2392 227137 : noutputs = gimple_asm_noutputs (asm_stmt);
2393 227137 : oconstraints = XALLOCAVEC (const char *, noutputs);
2394 :
2395 479537 : for (i = 0; i < noutputs; ++i)
2396 : {
2397 252400 : tree link = gimple_asm_output_op (asm_stmt, i);
2398 252400 : tree op = TREE_VALUE (link);
2399 :
2400 252400 : constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
2401 252400 : oconstraints[i] = constraint;
2402 252400 : parse_output_constraint (&constraint, i, 0, 0, &allows_mem,
2403 : &allows_reg, &is_inout, nullptr);
2404 :
2405 : /* A memory constraint makes the address of the operand escape. */
2406 252400 : if (!allows_reg && allows_mem)
2407 : {
2408 18061 : auto_vec<ce_s> tmpc;
2409 18061 : get_constraint_for_address_of (op, &tmpc);
2410 18061 : make_constraints_to (escaped_id, tmpc);
2411 18061 : }
2412 :
2413 : /* The asm may read global memory, so outputs may point to
2414 : any global memory. */
2415 252400 : if (op)
2416 : {
2417 252400 : auto_vec<ce_s, 2> lhsc;
2418 252400 : struct constraint_expr rhsc, *lhsp;
2419 252400 : unsigned j;
2420 252400 : get_constraint_for (op, &lhsc);
2421 252400 : rhsc.var = nonlocal_id;
2422 252400 : rhsc.offset = 0;
2423 252400 : rhsc.type = SCALAR;
2424 1009603 : FOR_EACH_VEC_ELT (lhsc, j, lhsp)
2425 252403 : process_constraint (new_constraint (*lhsp, rhsc));
2426 252400 : }
2427 : }
2428 387921 : for (i = 0; i < gimple_asm_ninputs (asm_stmt); ++i)
2429 : {
2430 160784 : tree link = gimple_asm_input_op (asm_stmt, i);
2431 160784 : tree op = TREE_VALUE (link);
2432 :
2433 160784 : constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
2434 :
2435 160784 : parse_input_constraint (&constraint, 0, 0, noutputs, 0, oconstraints,
2436 : &allows_mem, &allows_reg, nullptr);
2437 :
2438 : /* A memory constraint makes the address of the operand escape. */
2439 160784 : if (!allows_reg && allows_mem)
2440 : {
2441 19195 : auto_vec<ce_s> tmpc;
2442 19195 : get_constraint_for_address_of (op, &tmpc);
2443 19195 : make_constraints_to (escaped_id, tmpc);
2444 19195 : }
2445 : /* Strictly we'd only need the constraint to ESCAPED if
2446 : the asm clobbers memory, otherwise using something
2447 : along the lines of per-call clobbers/uses would be enough. */
2448 141589 : else if (op)
2449 141589 : make_escape_constraint (op);
2450 : }
2451 : }
2452 280344856 : }
2453 :
2454 :
2455 : /* Create a constraint adding to the clobber set of FI the memory
2456 : pointed to by PTR. */
2457 :
2458 : static void
2459 0 : process_ipa_clobber (varinfo_t fi, tree ptr)
2460 : {
2461 0 : vec<ce_s> ptrc = vNULL;
2462 0 : struct constraint_expr *c, lhs;
2463 0 : unsigned i;
2464 0 : get_constraint_for_rhs (ptr, &ptrc);
2465 0 : lhs = get_function_part_constraint (fi, fi_clobbers);
2466 0 : FOR_EACH_VEC_ELT (ptrc, i, c)
2467 0 : process_constraint (new_constraint (lhs, *c));
2468 0 : ptrc.release ();
2469 0 : }
2470 :
2471 : /* Walk statement T setting up clobber and use constraints according to the
2472 : references found in T. This function is a main part of the
2473 : IPA constraint builder. */
2474 :
2475 : static void
2476 976205 : find_func_clobbers (struct function *fn, gimple *origt)
2477 : {
2478 976205 : gimple *t = origt;
2479 976205 : auto_vec<ce_s, 16> lhsc;
2480 976205 : auto_vec<ce_s, 16> rhsc;
2481 976205 : varinfo_t fi;
2482 :
2483 : /* Add constraints for clobbered/used in IPA mode.
2484 : We are not interested in what automatic variables are clobbered
2485 : or used as we only use the information in the caller to which
2486 : they do not escape. */
2487 976205 : gcc_assert (in_ipa_mode);
2488 :
2489 : /* If the stmt refers to memory in any way it better had a VUSE. */
2490 2086746 : if (gimple_vuse (t) == NULL_TREE)
2491 : return;
2492 :
2493 : /* We'd better have function information for the current function. */
2494 643760 : fi = lookup_vi_for_tree (fn->decl);
2495 643760 : gcc_assert (fi != NULL);
2496 :
2497 : /* Account for stores in assignments and calls. */
2498 1287520 : if (gimple_vdef (t) != NULL_TREE
2499 847588 : && gimple_has_lhs (t))
2500 : {
2501 340425 : tree lhs = gimple_get_lhs (t);
2502 340425 : tree tem = lhs;
2503 859064 : while (handled_component_p (tem))
2504 178214 : tem = TREE_OPERAND (tem, 0);
2505 340425 : if ((DECL_P (tem)
2506 193667 : && !auto_var_in_fn_p (tem, fn->decl))
2507 335254 : || INDIRECT_REF_P (tem)
2508 675679 : || (TREE_CODE (tem) == MEM_REF
2509 30382 : && !(TREE_CODE (TREE_OPERAND (tem, 0)) == ADDR_EXPR
2510 : && auto_var_in_fn_p
2511 4138 : (TREE_OPERAND (TREE_OPERAND (tem, 0), 0), fn->decl))))
2512 : {
2513 28173 : struct constraint_expr lhsc, *rhsp;
2514 28173 : unsigned i;
2515 28173 : lhsc = get_function_part_constraint (fi, fi_clobbers);
2516 28173 : get_constraint_for_address_of (lhs, &rhsc);
2517 84519 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
2518 28173 : process_constraint (new_constraint (lhsc, *rhsp));
2519 28173 : rhsc.truncate (0);
2520 : }
2521 : }
2522 :
2523 : /* Account for uses in assignments and returns. */
2524 643760 : if (gimple_assign_single_p (t)
2525 643760 : || (gimple_code (t) == GIMPLE_RETURN
2526 23483 : && gimple_return_retval (as_a <greturn *> (t)) != NULL_TREE))
2527 : {
2528 366413 : tree rhs = (gimple_assign_single_p (t)
2529 366413 : ? gimple_assign_rhs1 (t)
2530 4337 : : gimple_return_retval (as_a <greturn *> (t)));
2531 366413 : tree tem = rhs;
2532 521830 : while (handled_component_p (tem))
2533 155417 : tem = TREE_OPERAND (tem, 0);
2534 366413 : if ((DECL_P (tem)
2535 53661 : && !auto_var_in_fn_p (tem, fn->decl))
2536 357668 : || INDIRECT_REF_P (tem)
2537 724081 : || (TREE_CODE (tem) == MEM_REF
2538 90167 : && !(TREE_CODE (TREE_OPERAND (tem, 0)) == ADDR_EXPR
2539 : && auto_var_in_fn_p
2540 1108 : (TREE_OPERAND (TREE_OPERAND (tem, 0), 0), fn->decl))))
2541 : {
2542 97210 : struct constraint_expr lhs, *rhsp;
2543 97210 : unsigned i;
2544 97210 : lhs = get_function_part_constraint (fi, fi_uses);
2545 97210 : get_constraint_for_address_of (rhs, &rhsc);
2546 291630 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
2547 97210 : process_constraint (new_constraint (lhs, *rhsp));
2548 97210 : rhsc.truncate (0);
2549 : }
2550 : }
2551 :
2552 643760 : if (gcall *call_stmt = dyn_cast <gcall *> (t))
2553 : {
2554 258159 : varinfo_t cfi = NULL;
2555 258159 : tree decl = gimple_call_fndecl (t);
2556 258159 : struct constraint_expr lhs, rhs;
2557 258159 : unsigned i, j;
2558 :
2559 : /* For builtins we do not have separate function info. For those
2560 : we do not generate escapes for we have to generate clobbers/uses. */
2561 258159 : if (gimple_call_builtin_p (t, BUILT_IN_NORMAL))
2562 38279 : switch (DECL_FUNCTION_CODE (decl))
2563 : {
2564 : /* The following functions use and clobber memory pointed to
2565 : by their arguments. */
2566 162 : case BUILT_IN_STRCPY:
2567 162 : case BUILT_IN_STRNCPY:
2568 162 : case BUILT_IN_BCOPY:
2569 162 : case BUILT_IN_MEMCPY:
2570 162 : case BUILT_IN_MEMMOVE:
2571 162 : case BUILT_IN_MEMPCPY:
2572 162 : case BUILT_IN_STPCPY:
2573 162 : case BUILT_IN_STPNCPY:
2574 162 : case BUILT_IN_STRCAT:
2575 162 : case BUILT_IN_STRNCAT:
2576 162 : case BUILT_IN_STRCPY_CHK:
2577 162 : case BUILT_IN_STRNCPY_CHK:
2578 162 : case BUILT_IN_MEMCPY_CHK:
2579 162 : case BUILT_IN_MEMMOVE_CHK:
2580 162 : case BUILT_IN_MEMPCPY_CHK:
2581 162 : case BUILT_IN_STPCPY_CHK:
2582 162 : case BUILT_IN_STPNCPY_CHK:
2583 162 : case BUILT_IN_STRCAT_CHK:
2584 162 : case BUILT_IN_STRNCAT_CHK:
2585 162 : {
2586 324 : tree dest = gimple_call_arg (t, (DECL_FUNCTION_CODE (decl)
2587 : == BUILT_IN_BCOPY ? 1 : 0));
2588 324 : tree src = gimple_call_arg (t, (DECL_FUNCTION_CODE (decl)
2589 162 : == BUILT_IN_BCOPY ? 0 : 1));
2590 162 : unsigned i;
2591 162 : struct constraint_expr *rhsp, *lhsp;
2592 162 : get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
2593 162 : lhs = get_function_part_constraint (fi, fi_clobbers);
2594 486 : FOR_EACH_VEC_ELT (lhsc, i, lhsp)
2595 162 : process_constraint (new_constraint (lhs, *lhsp));
2596 162 : get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
2597 162 : lhs = get_function_part_constraint (fi, fi_uses);
2598 486 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
2599 162 : process_constraint (new_constraint (lhs, *rhsp));
2600 : return;
2601 : }
2602 : /* The following function clobbers memory pointed to by
2603 : its argument. */
2604 890 : case BUILT_IN_MEMSET:
2605 890 : case BUILT_IN_MEMSET_CHK:
2606 890 : case BUILT_IN_POSIX_MEMALIGN:
2607 890 : {
2608 890 : tree dest = gimple_call_arg (t, 0);
2609 890 : unsigned i;
2610 890 : ce_s *lhsp;
2611 890 : get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
2612 890 : lhs = get_function_part_constraint (fi, fi_clobbers);
2613 2670 : FOR_EACH_VEC_ELT (lhsc, i, lhsp)
2614 890 : process_constraint (new_constraint (lhs, *lhsp));
2615 : return;
2616 : }
2617 : /* The following functions clobber their second and third
2618 : arguments. */
2619 0 : case BUILT_IN_SINCOS:
2620 0 : case BUILT_IN_SINCOSF:
2621 0 : case BUILT_IN_SINCOSL:
2622 0 : {
2623 0 : process_ipa_clobber (fi, gimple_call_arg (t, 1));
2624 0 : process_ipa_clobber (fi, gimple_call_arg (t, 2));
2625 0 : return;
2626 : }
2627 : /* The following functions clobber their second argument. */
2628 0 : case BUILT_IN_FREXP:
2629 0 : case BUILT_IN_FREXPF:
2630 0 : case BUILT_IN_FREXPL:
2631 0 : case BUILT_IN_LGAMMA_R:
2632 0 : case BUILT_IN_LGAMMAF_R:
2633 0 : case BUILT_IN_LGAMMAL_R:
2634 0 : case BUILT_IN_GAMMA_R:
2635 0 : case BUILT_IN_GAMMAF_R:
2636 0 : case BUILT_IN_GAMMAL_R:
2637 0 : case BUILT_IN_MODF:
2638 0 : case BUILT_IN_MODFF:
2639 0 : case BUILT_IN_MODFL:
2640 0 : {
2641 0 : process_ipa_clobber (fi, gimple_call_arg (t, 1));
2642 0 : return;
2643 : }
2644 : /* The following functions clobber their third argument. */
2645 0 : case BUILT_IN_REMQUO:
2646 0 : case BUILT_IN_REMQUOF:
2647 0 : case BUILT_IN_REMQUOL:
2648 0 : {
2649 0 : process_ipa_clobber (fi, gimple_call_arg (t, 2));
2650 0 : return;
2651 : }
2652 : /* The following functions use what their first argument
2653 : points to. */
2654 60 : case BUILT_IN_STRDUP:
2655 60 : case BUILT_IN_STRNDUP:
2656 60 : case BUILT_IN_REALLOC:
2657 60 : case BUILT_IN_INDEX:
2658 60 : case BUILT_IN_STRCHR:
2659 60 : case BUILT_IN_STRRCHR:
2660 60 : case BUILT_IN_MEMCHR:
2661 60 : {
2662 60 : tree src = gimple_call_arg (t, 0);
2663 60 : get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
2664 60 : lhs = get_function_part_constraint (fi, fi_uses);
2665 60 : struct constraint_expr *rhsp;
2666 180 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
2667 60 : process_constraint (new_constraint (lhs, *rhsp));
2668 : return;
2669 : }
2670 : /* The following functions use what their first and second argument
2671 : point to. */
2672 16 : case BUILT_IN_STRSTR:
2673 16 : case BUILT_IN_STRPBRK:
2674 16 : {
2675 16 : tree src = gimple_call_arg (t, 0);
2676 16 : get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
2677 16 : lhs = get_function_part_constraint (fi, fi_uses);
2678 16 : struct constraint_expr *rhsp;
2679 48 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
2680 16 : process_constraint (new_constraint (lhs, *rhsp));
2681 16 : rhsc.truncate (0);
2682 16 : src = gimple_call_arg (t, 1);
2683 16 : get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
2684 251435 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
2685 16 : process_constraint (new_constraint (lhs, *rhsp));
2686 : return;
2687 : }
2688 : /* The following functions neither read nor clobber memory. */
2689 : case BUILT_IN_ASSUME_ALIGNED:
2690 : case BUILT_IN_FREE:
2691 : return;
2692 : /* Trampolines are of no interest to us. */
2693 : case BUILT_IN_INIT_TRAMPOLINE:
2694 : case BUILT_IN_ADJUST_TRAMPOLINE:
2695 : return;
2696 : case BUILT_IN_VA_START:
2697 : case BUILT_IN_VA_END:
2698 : return;
2699 14092 : case BUILT_IN_GOMP_PARALLEL:
2700 14092 : case BUILT_IN_GOACC_PARALLEL:
2701 14092 : {
2702 14092 : unsigned int fnpos, argpos;
2703 14092 : unsigned int implicit_use_args[2];
2704 14092 : unsigned int num_implicit_use_args = 0;
2705 14092 : switch (DECL_FUNCTION_CODE (decl))
2706 : {
2707 : case BUILT_IN_GOMP_PARALLEL:
2708 : /* __builtin_GOMP_parallel (fn, data, num_threads, flags). */
2709 : fnpos = 0;
2710 : argpos = 1;
2711 : break;
2712 14079 : case BUILT_IN_GOACC_PARALLEL:
2713 : /* __builtin_GOACC_parallel (flags_m, fn, mapnum, hostaddrs,
2714 : sizes, kinds, ...). */
2715 14079 : fnpos = 1;
2716 14079 : argpos = 3;
2717 14079 : implicit_use_args[num_implicit_use_args++] = 4;
2718 14079 : implicit_use_args[num_implicit_use_args++] = 5;
2719 14079 : break;
2720 : default:
2721 : gcc_unreachable ();
2722 : }
2723 :
2724 14092 : tree fnarg = gimple_call_arg (t, fnpos);
2725 14092 : gcc_assert (TREE_CODE (fnarg) == ADDR_EXPR);
2726 14092 : tree fndecl = TREE_OPERAND (fnarg, 0);
2727 14092 : if (fndecl_maybe_in_other_partition (fndecl))
2728 : /* Fallthru to general call handling. */
2729 : break;
2730 :
2731 14049 : varinfo_t cfi = get_vi_for_tree (fndecl);
2732 :
2733 14049 : tree arg = gimple_call_arg (t, argpos);
2734 :
2735 : /* Parameter passed by value is used. */
2736 14049 : lhs = get_function_part_constraint (fi, fi_uses);
2737 14049 : struct constraint_expr *rhsp;
2738 14049 : get_constraint_for (arg, &rhsc);
2739 42147 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
2740 14049 : process_constraint (new_constraint (lhs, *rhsp));
2741 14049 : rhsc.truncate (0);
2742 :
2743 : /* Handle parameters used by the call, but not used in cfi, as
2744 : implicitly used by cfi. */
2745 14049 : lhs = get_function_part_constraint (cfi, fi_uses);
2746 56176 : for (unsigned i = 0; i < num_implicit_use_args; ++i)
2747 : {
2748 28078 : tree arg = gimple_call_arg (t, implicit_use_args[i]);
2749 28078 : get_constraint_for (arg, &rhsc);
2750 84234 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
2751 28078 : process_constraint (new_constraint (lhs, *rhsp));
2752 28078 : rhsc.truncate (0);
2753 : }
2754 :
2755 : /* The caller clobbers what the callee does. */
2756 14049 : lhs = get_function_part_constraint (fi, fi_clobbers);
2757 14049 : rhs = get_function_part_constraint (cfi, fi_clobbers);
2758 14049 : process_constraint (new_constraint (lhs, rhs));
2759 :
2760 : /* The caller uses what the callee does. */
2761 14049 : lhs = get_function_part_constraint (fi, fi_uses);
2762 14049 : rhs = get_function_part_constraint (cfi, fi_uses);
2763 14049 : process_constraint (new_constraint (lhs, rhs));
2764 :
2765 14049 : return;
2766 : }
2767 : /* printf-style functions may have hooks to set pointers to
2768 : point to somewhere into the generated string. Leave them
2769 : for a later exercise... */
2770 : default:
2771 : /* Fallthru to general call handling. */;
2772 : }
2773 :
2774 : /* Parameters passed by value are used. */
2775 241044 : lhs = get_function_part_constraint (fi, fi_uses);
2776 1417971 : for (i = 0; i < gimple_call_num_args (t); i++)
2777 : {
2778 935883 : struct constraint_expr *rhsp;
2779 935883 : tree arg = gimple_call_arg (t, i);
2780 :
2781 1850628 : if (TREE_CODE (arg) == SSA_NAME
2782 935883 : || is_gimple_min_invariant (arg))
2783 914745 : continue;
2784 :
2785 21138 : get_constraint_for_address_of (arg, &rhsc);
2786 63415 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
2787 21139 : process_constraint (new_constraint (lhs, *rhsp));
2788 21138 : rhsc.truncate (0);
2789 : }
2790 :
2791 : /* Build constraints for propagating clobbers/uses along the
2792 : callgraph edges. */
2793 241044 : cfi = get_fi_for_callee (call_stmt);
2794 241044 : if (cfi->id == anything_id)
2795 : {
2796 356620 : if (gimple_vdef (t))
2797 125194 : make_constraint_from (first_vi_for_offset (fi, fi_clobbers),
2798 : anything_id);
2799 178310 : make_constraint_from (first_vi_for_offset (fi, fi_uses),
2800 : anything_id);
2801 178310 : return;
2802 : }
2803 :
2804 : /* For callees without function info (that's external functions),
2805 : ESCAPED is clobbered and used. */
2806 62734 : if (cfi->decl
2807 62733 : && TREE_CODE (cfi->decl) == FUNCTION_DECL
2808 62054 : && !cfi->is_fn_info)
2809 : {
2810 55962 : varinfo_t vi;
2811 :
2812 111924 : if (gimple_vdef (t))
2813 55777 : make_copy_constraint (first_vi_for_offset (fi, fi_clobbers),
2814 : escaped_id);
2815 55962 : make_copy_constraint (first_vi_for_offset (fi, fi_uses), escaped_id);
2816 :
2817 : /* Also honor the call statement use/clobber info. */
2818 55962 : if ((vi = lookup_call_clobber_vi (call_stmt)) != NULL)
2819 55676 : make_copy_constraint (first_vi_for_offset (fi, fi_clobbers),
2820 55676 : vi->id);
2821 55962 : if ((vi = lookup_call_use_vi (call_stmt)) != NULL)
2822 55676 : make_copy_constraint (first_vi_for_offset (fi, fi_uses),
2823 55676 : vi->id);
2824 : return;
2825 : }
2826 :
2827 : /* Otherwise the caller clobbers and uses what the callee does.
2828 : ??? This should use a new complex constraint that filters
2829 : local variables of the callee. */
2830 13544 : if (gimple_vdef (t))
2831 : {
2832 5758 : lhs = get_function_part_constraint (fi, fi_clobbers);
2833 5758 : rhs = get_function_part_constraint (cfi, fi_clobbers);
2834 5758 : process_constraint (new_constraint (lhs, rhs));
2835 : }
2836 6772 : lhs = get_function_part_constraint (fi, fi_uses);
2837 6772 : rhs = get_function_part_constraint (cfi, fi_uses);
2838 6772 : process_constraint (new_constraint (lhs, rhs));
2839 : }
2840 385601 : else if (gimple_code (t) == GIMPLE_ASM)
2841 : {
2842 : /* ??? Ick. We can do better. */
2843 42 : if (gimple_vdef (t))
2844 42 : make_constraint_from (first_vi_for_offset (fi, fi_clobbers),
2845 : anything_id);
2846 42 : make_constraint_from (first_vi_for_offset (fi, fi_uses),
2847 : anything_id);
2848 : }
2849 976205 : }
2850 :
2851 :
2852 : /* This structure is used during pushing fields onto the fieldstack
2853 : to track the offset of the field, since bitpos_of_field gives it
2854 : relative to its immediate containing type, and we want it relative
2855 : to the ultimate containing object. */
2856 :
2857 : struct fieldoff
2858 : {
2859 : /* Offset from the base of the base containing object to this field. */
2860 : HOST_WIDE_INT offset;
2861 :
2862 : /* Size, in bits, of the field. */
2863 : unsigned HOST_WIDE_INT size;
2864 :
2865 : unsigned has_unknown_size : 1;
2866 :
2867 : unsigned must_have_pointers : 1;
2868 :
2869 : unsigned may_have_pointers : 1;
2870 :
2871 : unsigned only_restrict_pointers : 1;
2872 :
2873 : tree restrict_pointed_type;
2874 : };
2875 : typedef struct fieldoff fieldoff_s;
2876 :
2877 :
2878 : /* qsort comparison function for two fieldoff's PA and PB. */
2879 :
2880 : static int
2881 192994089 : fieldoff_compare (const void *pa, const void *pb)
2882 : {
2883 192994089 : const fieldoff_s *foa = (const fieldoff_s *)pa;
2884 192994089 : const fieldoff_s *fob = (const fieldoff_s *)pb;
2885 192994089 : unsigned HOST_WIDE_INT foasize, fobsize;
2886 :
2887 192994089 : if (foa->offset < fob->offset)
2888 : return -1;
2889 100557224 : else if (foa->offset > fob->offset)
2890 : return 1;
2891 :
2892 1230077 : foasize = foa->size;
2893 1230077 : fobsize = fob->size;
2894 1230077 : if (foasize < fobsize)
2895 : return -1;
2896 1029417 : else if (foasize > fobsize)
2897 116815 : return 1;
2898 : return 0;
2899 : }
2900 :
2901 : /* Sort a fieldstack according to the field offset and sizes. */
2902 : static void
2903 7922806 : sort_fieldstack (vec<fieldoff_s> &fieldstack)
2904 : {
2905 7922806 : fieldstack.qsort (fieldoff_compare);
2906 7922806 : }
2907 :
2908 : /* Return true if T is a type that can have subvars. */
2909 :
2910 : static inline bool
2911 68342045 : type_can_have_subvars (const_tree t)
2912 : {
2913 : /* Aggregates without overlapping fields can have subvars. */
2914 6057704 : return TREE_CODE (t) == RECORD_TYPE;
2915 : }
2916 :
2917 : /* Return true if V is a tree that we can have subvars for.
2918 : Normally, this is any aggregate type. Also complex
2919 : types which are not gimple registers can have subvars. */
2920 :
2921 : static inline bool
2922 124892482 : var_can_have_subvars (const_tree v)
2923 : {
2924 : /* Volatile variables should never have subvars. */
2925 124892482 : if (TREE_THIS_VOLATILE (v))
2926 : return false;
2927 :
2928 : /* Non decls or memory tags can never have subvars. */
2929 124595003 : if (!DECL_P (v))
2930 : return false;
2931 :
2932 62284341 : return type_can_have_subvars (TREE_TYPE (v));
2933 : }
2934 :
2935 : /* Return true if T is a type that does contain pointers. */
2936 :
2937 : static bool
2938 34613624 : type_must_have_pointers (tree type)
2939 : {
2940 35407044 : if (POINTER_TYPE_P (type))
2941 : return true;
2942 :
2943 19835267 : if (TREE_CODE (type) == ARRAY_TYPE)
2944 793420 : return type_must_have_pointers (TREE_TYPE (type));
2945 :
2946 : /* A function or method can have pointers as arguments, so track
2947 : those separately. */
2948 19041847 : if (FUNC_OR_METHOD_TYPE_P (type))
2949 0 : return true;
2950 :
2951 : return false;
2952 : }
2953 :
2954 : static bool
2955 34613624 : field_must_have_pointers (tree t)
2956 : {
2957 34613624 : return type_must_have_pointers (TREE_TYPE (t));
2958 : }
2959 :
2960 : /* Given a TYPE, and a vector of field offsets FIELDSTACK, push all
2961 : the fields of TYPE onto fieldstack, recording their offsets along
2962 : the way.
2963 :
2964 : OFFSET is used to keep track of the offset in this entire
2965 : structure, rather than just the immediately containing structure.
2966 : Returns false if the caller is supposed to handle the field we
2967 : recursed for. */
2968 :
2969 : static bool
2970 15145669 : push_fields_onto_fieldstack (tree type, vec<fieldoff_s> *fieldstack,
2971 : unsigned HOST_WIDE_INT offset)
2972 : {
2973 15145669 : tree field;
2974 15145669 : bool empty_p = true;
2975 :
2976 15145669 : if (TREE_CODE (type) != RECORD_TYPE)
2977 : return false;
2978 :
2979 : /* If the vector of fields is growing too big, bail out early.
2980 : Callers check for vec::length <= param_max_fields_for_field_sensitive, make
2981 : sure this fails. */
2982 15145669 : if (fieldstack->length () > (unsigned)param_max_fields_for_field_sensitive)
2983 : return false;
2984 :
2985 374069590 : for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
2986 359111874 : if (TREE_CODE (field) == FIELD_DECL)
2987 : {
2988 41592927 : bool push = false;
2989 41592927 : unsigned HOST_WIDE_INT foff = bitpos_of_field (field);
2990 41592927 : tree field_type = TREE_TYPE (field);
2991 :
2992 41592927 : if (!var_can_have_subvars (field)
2993 7191790 : || TREE_CODE (field_type) == QUAL_UNION_TYPE
2994 48784717 : || TREE_CODE (field_type) == UNION_TYPE)
2995 : push = true;
2996 7191790 : else if (!push_fields_onto_fieldstack
2997 7191790 : (field_type, fieldstack, offset + foff)
2998 7191790 : && (DECL_SIZE (field)
2999 1385411 : && !integer_zerop (DECL_SIZE (field))))
3000 : /* Empty structures may have actual size, like in C++. So
3001 : see if we didn't push any subfields and the size is
3002 : nonzero, push the field onto the stack. */
3003 : push = true;
3004 :
3005 : if (push)
3006 : {
3007 34613624 : fieldoff_s *pair = NULL;
3008 34613624 : bool has_unknown_size = false;
3009 34613624 : bool must_have_pointers_p;
3010 :
3011 34613624 : if (!fieldstack->is_empty ())
3012 26984174 : pair = &fieldstack->last ();
3013 :
3014 : /* If there isn't anything at offset zero, create sth. */
3015 26984174 : if (!pair
3016 7629450 : && offset + foff != 0)
3017 : {
3018 8968 : fieldoff_s e
3019 8968 : = {0, offset + foff, false, false, true, false, NULL_TREE};
3020 8968 : pair = fieldstack->safe_push (e);
3021 : }
3022 :
3023 34613624 : if (!DECL_SIZE (field)
3024 34613624 : || !tree_fits_uhwi_p (DECL_SIZE (field)))
3025 : has_unknown_size = true;
3026 :
3027 : /* If adjacent fields do not contain pointers merge them. */
3028 34613624 : must_have_pointers_p = field_must_have_pointers (field);
3029 34613624 : if (pair
3030 34613624 : && !has_unknown_size
3031 26962124 : && !must_have_pointers_p
3032 16784428 : && !pair->must_have_pointers
3033 11864943 : && !pair->has_unknown_size
3034 11864940 : && pair->offset + pair->size == offset + foff)
3035 : {
3036 11313821 : pair->size += tree_to_uhwi (DECL_SIZE (field));
3037 : }
3038 : else
3039 : {
3040 23299803 : fieldoff_s e;
3041 23299803 : e.offset = offset + foff;
3042 23299803 : e.has_unknown_size = has_unknown_size;
3043 23299803 : if (!has_unknown_size)
3044 23268730 : e.size = tree_to_uhwi (DECL_SIZE (field));
3045 : else
3046 : e.size = -1;
3047 23299803 : e.must_have_pointers = must_have_pointers_p;
3048 23299803 : e.may_have_pointers = true;
3049 23299803 : e.only_restrict_pointers
3050 23299803 : = (!has_unknown_size
3051 23268730 : && POINTER_TYPE_P (field_type)
3052 38863050 : && TYPE_RESTRICT (field_type));
3053 23299803 : if (e.only_restrict_pointers)
3054 122653 : e.restrict_pointed_type = TREE_TYPE (field_type);
3055 23299803 : fieldstack->safe_push (e);
3056 : }
3057 : }
3058 :
3059 : empty_p = false;
3060 : }
3061 :
3062 14957716 : return !empty_p;
3063 : }
3064 :
3065 : /* Count the number of arguments DECL has, and set IS_VARARGS to true
3066 : if it is a varargs function. */
3067 :
3068 : static unsigned int
3069 23885 : count_num_arguments (tree decl, bool *is_varargs)
3070 : {
3071 23885 : unsigned int num = 0;
3072 23885 : tree t;
3073 :
3074 : /* Capture named arguments for K&R functions. They do not
3075 : have a prototype and thus no TYPE_ARG_TYPES. */
3076 49517 : for (t = DECL_ARGUMENTS (decl); t; t = DECL_CHAIN (t))
3077 25632 : ++num;
3078 :
3079 : /* Check if the function has variadic arguments. */
3080 49517 : for (t = TYPE_ARG_TYPES (TREE_TYPE (decl)); t; t = TREE_CHAIN (t))
3081 49509 : if (TREE_VALUE (t) == void_type_node)
3082 : break;
3083 23885 : if (!t)
3084 8 : *is_varargs = true;
3085 :
3086 23885 : return num;
3087 : }
3088 :
3089 : /* Creation function node for DECL, using NAME, and return the index
3090 : of the variable we've created for the function. If NONLOCAL_p, create
3091 : initial constraints. */
3092 :
3093 : static varinfo_t
3094 23885 : create_function_info_for (tree decl, const char *name, bool add_id,
3095 : bool nonlocal_p)
3096 : {
3097 23885 : struct function *fn = DECL_STRUCT_FUNCTION (decl);
3098 23885 : varinfo_t vi, prev_vi;
3099 23885 : tree arg;
3100 23885 : unsigned int i;
3101 23885 : bool is_varargs = false;
3102 23885 : unsigned int num_args = count_num_arguments (decl, &is_varargs);
3103 :
3104 : /* Create the variable info. */
3105 :
3106 23885 : vi = new_var_info (decl, name, add_id);
3107 23885 : vi->offset = 0;
3108 23885 : vi->size = 1;
3109 23885 : vi->fullsize = fi_parm_base + num_args;
3110 23885 : vi->is_fn_info = 1;
3111 23885 : vi->may_have_pointers = false;
3112 23885 : if (is_varargs)
3113 8 : vi->fullsize = ~0;
3114 23885 : insert_vi_for_tree (vi->decl, vi);
3115 :
3116 23885 : prev_vi = vi;
3117 :
3118 : /* Create a variable for things the function clobbers and one for
3119 : things the function uses. */
3120 23885 : {
3121 23885 : varinfo_t clobbervi, usevi;
3122 23885 : const char *newname;
3123 23885 : char *tempname;
3124 :
3125 23885 : tempname = xasprintf ("%s.clobber", name);
3126 23885 : newname = ggc_strdup (tempname);
3127 23885 : free (tempname);
3128 :
3129 23885 : clobbervi = new_var_info (NULL, newname, false);
3130 23885 : clobbervi->offset = fi_clobbers;
3131 23885 : clobbervi->size = 1;
3132 23885 : clobbervi->fullsize = vi->fullsize;
3133 23885 : clobbervi->is_full_var = true;
3134 23885 : clobbervi->is_global_var = false;
3135 23885 : clobbervi->is_reg_var = true;
3136 :
3137 23885 : gcc_assert (prev_vi->offset < clobbervi->offset);
3138 23885 : prev_vi->next = clobbervi->id;
3139 23885 : prev_vi = clobbervi;
3140 :
3141 23885 : tempname = xasprintf ("%s.use", name);
3142 23885 : newname = ggc_strdup (tempname);
3143 23885 : free (tempname);
3144 :
3145 23885 : usevi = new_var_info (NULL, newname, false);
3146 23885 : usevi->offset = fi_uses;
3147 23885 : usevi->size = 1;
3148 23885 : usevi->fullsize = vi->fullsize;
3149 23885 : usevi->is_full_var = true;
3150 23885 : usevi->is_global_var = false;
3151 23885 : usevi->is_reg_var = true;
3152 :
3153 23885 : gcc_assert (prev_vi->offset < usevi->offset);
3154 23885 : prev_vi->next = usevi->id;
3155 23885 : prev_vi = usevi;
3156 : }
3157 :
3158 : /* And one for the static chain. */
3159 23885 : if (fn->static_chain_decl != NULL_TREE)
3160 : {
3161 139 : varinfo_t chainvi;
3162 139 : const char *newname;
3163 139 : char *tempname;
3164 :
3165 139 : tempname = xasprintf ("%s.chain", name);
3166 139 : newname = ggc_strdup (tempname);
3167 139 : free (tempname);
3168 :
3169 139 : chainvi = new_var_info (fn->static_chain_decl, newname, false);
3170 139 : chainvi->offset = fi_static_chain;
3171 139 : chainvi->size = 1;
3172 139 : chainvi->fullsize = vi->fullsize;
3173 139 : chainvi->is_full_var = true;
3174 139 : chainvi->is_global_var = false;
3175 :
3176 139 : insert_vi_for_tree (fn->static_chain_decl, chainvi);
3177 :
3178 139 : if (nonlocal_p
3179 0 : && chainvi->may_have_pointers)
3180 0 : make_constraint_from (chainvi, nonlocal_id);
3181 :
3182 139 : gcc_assert (prev_vi->offset < chainvi->offset);
3183 139 : prev_vi->next = chainvi->id;
3184 139 : prev_vi = chainvi;
3185 : }
3186 :
3187 : /* Create a variable for the return var. */
3188 23885 : if (DECL_RESULT (decl) != NULL
3189 23885 : || !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
3190 : {
3191 23885 : varinfo_t resultvi;
3192 23885 : const char *newname;
3193 23885 : char *tempname;
3194 23885 : tree resultdecl = decl;
3195 :
3196 23885 : if (DECL_RESULT (decl))
3197 23885 : resultdecl = DECL_RESULT (decl);
3198 :
3199 23885 : tempname = xasprintf ("%s.result", name);
3200 23885 : newname = ggc_strdup (tempname);
3201 23885 : free (tempname);
3202 :
3203 23885 : resultvi = new_var_info (resultdecl, newname, false);
3204 23885 : resultvi->offset = fi_result;
3205 23885 : resultvi->size = 1;
3206 23885 : resultvi->fullsize = vi->fullsize;
3207 23885 : resultvi->is_full_var = true;
3208 23885 : if (DECL_RESULT (decl))
3209 23885 : resultvi->may_have_pointers = true;
3210 :
3211 23885 : if (DECL_RESULT (decl))
3212 23885 : insert_vi_for_tree (DECL_RESULT (decl), resultvi);
3213 :
3214 23885 : if (nonlocal_p
3215 7092 : && DECL_RESULT (decl)
3216 30977 : && DECL_BY_REFERENCE (DECL_RESULT (decl)))
3217 6 : make_constraint_from (resultvi, nonlocal_id);
3218 :
3219 23885 : gcc_assert (prev_vi->offset < resultvi->offset);
3220 23885 : prev_vi->next = resultvi->id;
3221 23885 : prev_vi = resultvi;
3222 : }
3223 :
3224 : /* We also need to make function return values escape. Nothing
3225 : escapes by returning from main though. */
3226 23885 : if (nonlocal_p
3227 23885 : && !MAIN_NAME_P (DECL_NAME (decl)))
3228 : {
3229 3504 : varinfo_t fi, rvi;
3230 3504 : fi = lookup_vi_for_tree (decl);
3231 3504 : rvi = first_vi_for_offset (fi, fi_result);
3232 3504 : if (rvi && rvi->offset == fi_result)
3233 3504 : make_copy_constraint (get_varinfo (escaped_id), rvi->id);
3234 : }
3235 :
3236 : /* Set up variables for each argument. */
3237 23885 : arg = DECL_ARGUMENTS (decl);
3238 49517 : for (i = 0; i < num_args; i++)
3239 : {
3240 25632 : varinfo_t argvi;
3241 25632 : const char *newname;
3242 25632 : char *tempname;
3243 25632 : tree argdecl = decl;
3244 :
3245 25632 : if (arg)
3246 25632 : argdecl = arg;
3247 :
3248 25632 : tempname = xasprintf ("%s.arg%d", name, i);
3249 25632 : newname = ggc_strdup (tempname);
3250 25632 : free (tempname);
3251 :
3252 25632 : argvi = new_var_info (argdecl, newname, false);
3253 25632 : argvi->offset = fi_parm_base + i;
3254 25632 : argvi->size = 1;
3255 25632 : argvi->is_full_var = true;
3256 25632 : argvi->fullsize = vi->fullsize;
3257 25632 : if (arg)
3258 25632 : argvi->may_have_pointers = true;
3259 :
3260 25632 : if (arg)
3261 25632 : insert_vi_for_tree (arg, argvi);
3262 :
3263 25632 : if (nonlocal_p
3264 9300 : && argvi->may_have_pointers)
3265 9300 : make_constraint_from (argvi, nonlocal_id);
3266 :
3267 25632 : gcc_assert (prev_vi->offset < argvi->offset);
3268 25632 : prev_vi->next = argvi->id;
3269 25632 : prev_vi = argvi;
3270 25632 : if (arg)
3271 25632 : arg = DECL_CHAIN (arg);
3272 : }
3273 :
3274 : /* Add one representative for all further args. */
3275 23885 : if (is_varargs)
3276 : {
3277 8 : varinfo_t argvi;
3278 8 : const char *newname;
3279 8 : char *tempname;
3280 8 : tree decl;
3281 :
3282 8 : tempname = xasprintf ("%s.varargs", name);
3283 8 : newname = ggc_strdup (tempname);
3284 8 : free (tempname);
3285 :
3286 : /* We need sth that can be pointed to for va_start. */
3287 8 : decl = build_fake_var_decl (ptr_type_node);
3288 :
3289 8 : argvi = new_var_info (decl, newname, false);
3290 8 : argvi->offset = fi_parm_base + num_args;
3291 8 : argvi->size = ~0;
3292 8 : argvi->is_full_var = true;
3293 8 : argvi->is_heap_var = true;
3294 8 : argvi->fullsize = vi->fullsize;
3295 :
3296 8 : if (nonlocal_p
3297 6 : && argvi->may_have_pointers)
3298 6 : make_constraint_from (argvi, nonlocal_id);
3299 :
3300 8 : gcc_assert (prev_vi->offset < argvi->offset);
3301 8 : prev_vi->next = argvi->id;
3302 : }
3303 :
3304 23885 : return vi;
3305 : }
3306 :
3307 :
3308 : /* Return true if FIELDSTACK contains fields that overlap.
3309 : FIELDSTACK is assumed to be sorted by offset. */
3310 :
3311 : static bool
3312 7922806 : check_for_overlaps (const vec<fieldoff_s> &fieldstack)
3313 : {
3314 7922806 : fieldoff_s *fo = NULL;
3315 7922806 : unsigned int i;
3316 7922806 : HOST_WIDE_INT lastoffset = -1;
3317 :
3318 30469656 : FOR_EACH_VEC_ELT (fieldstack, i, fo)
3319 : {
3320 22564637 : if (fo->offset == lastoffset)
3321 : return true;
3322 22546850 : lastoffset = fo->offset;
3323 : }
3324 : return false;
3325 : }
3326 :
3327 : /* Create a varinfo structure for NAME and DECL, and add it to VARMAP.
3328 : This will also create any varinfo structures necessary for fields
3329 : of DECL. DECL is a function parameter if HANDLE_PARAM is set.
3330 : HANDLED_STRUCT_TYPE is used to register struct types reached by following
3331 : restrict pointers. This is needed to prevent infinite recursion.
3332 : If ADD_RESTRICT, pretend that the pointer NAME is restrict even if DECL
3333 : does not advertise it. */
3334 :
3335 : static varinfo_t
3336 94740596 : create_variable_info_for_1 (tree decl, const char *name, bool add_id,
3337 : bool handle_param, bitmap handled_struct_type,
3338 : bool add_restrict = false)
3339 : {
3340 94740596 : varinfo_t vi, newvi;
3341 94740596 : tree decl_type = TREE_TYPE (decl);
3342 94740596 : tree declsize = DECL_P (decl) ? DECL_SIZE (decl) : TYPE_SIZE (decl_type);
3343 94740596 : auto_vec<fieldoff_s> fieldstack;
3344 94740596 : fieldoff_s *fo;
3345 94740596 : unsigned int i;
3346 :
3347 94740596 : if (!declsize
3348 86210386 : || !tree_fits_uhwi_p (declsize))
3349 : {
3350 8544538 : vi = new_var_info (decl, name, add_id);
3351 8544538 : vi->offset = 0;
3352 8544538 : vi->size = ~0;
3353 8544538 : vi->fullsize = ~0;
3354 8544538 : vi->is_unknown_size_var = true;
3355 8544538 : vi->is_full_var = true;
3356 8544538 : vi->may_have_pointers = true;
3357 8544538 : return vi;
3358 : }
3359 :
3360 : /* Collect field information. */
3361 86196058 : if (use_field_sensitive
3362 82058003 : && var_can_have_subvars (decl)
3363 : /* ??? Force us to not use subfields for globals in IPA mode.
3364 : Else we'd have to parse arbitrary initializers. */
3365 94170710 : && !(in_ipa_mode
3366 20310 : && is_global_var (decl)))
3367 : {
3368 7953879 : fieldoff_s *fo = NULL;
3369 7953879 : bool notokay = false;
3370 7953879 : unsigned int i;
3371 :
3372 7953879 : push_fields_onto_fieldstack (decl_type, &fieldstack, 0);
3373 :
3374 39185453 : for (i = 0; !notokay && fieldstack.iterate (i, &fo); i++)
3375 23308768 : if (fo->has_unknown_size
3376 23277695 : || fo->offset < 0)
3377 : {
3378 : notokay = true;
3379 : break;
3380 : }
3381 :
3382 : /* We can't sort them if we have a field with a variable sized type,
3383 : which will make notokay = true. In that case, we are going to return
3384 : without creating varinfos for the fields anyway, so sorting them is a
3385 : waste to boot. */
3386 7953879 : if (!notokay)
3387 : {
3388 7922806 : sort_fieldstack (fieldstack);
3389 : /* Due to some C++ FE issues, like PR 22488, we might end up
3390 : what appear to be overlapping fields even though they,
3391 : in reality, do not overlap. Until the C++ FE is fixed,
3392 : we will simply disable field-sensitivity for these cases. */
3393 7922806 : notokay = check_for_overlaps (fieldstack);
3394 : }
3395 :
3396 7922806 : if (notokay)
3397 48860 : fieldstack.release ();
3398 : }
3399 :
3400 : /* If we didn't end up collecting sub-variables create a full
3401 : variable for the decl. */
3402 86196058 : if (fieldstack.length () == 0
3403 7580590 : || fieldstack.length () > (unsigned)param_max_fields_for_field_sensitive)
3404 : {
3405 78615886 : vi = new_var_info (decl, name, add_id);
3406 78615886 : vi->offset = 0;
3407 78615886 : vi->may_have_pointers = true;
3408 78615886 : vi->fullsize = tree_to_uhwi (declsize);
3409 78615886 : vi->size = vi->fullsize;
3410 78615886 : vi->is_full_var = true;
3411 78615886 : if (POINTER_TYPE_P (decl_type)
3412 78615886 : && (TYPE_RESTRICT (decl_type) || add_restrict))
3413 885114 : vi->only_restrict_pointers = 1;
3414 78615886 : if (vi->only_restrict_pointers
3415 885114 : && !type_contains_placeholder_p (TREE_TYPE (decl_type))
3416 885114 : && handle_param
3417 79206145 : && !bitmap_bit_p (handled_struct_type,
3418 590259 : TYPE_UID (TREE_TYPE (decl_type))))
3419 : {
3420 590259 : varinfo_t rvi;
3421 590259 : tree heapvar = build_fake_var_decl (TREE_TYPE (decl_type));
3422 590259 : DECL_EXTERNAL (heapvar) = 1;
3423 590259 : if (var_can_have_subvars (heapvar))
3424 911890 : bitmap_set_bit (handled_struct_type,
3425 455945 : TYPE_UID (TREE_TYPE (decl_type)));
3426 590259 : rvi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS", true,
3427 : true, handled_struct_type);
3428 590259 : if (var_can_have_subvars (heapvar))
3429 911890 : bitmap_clear_bit (handled_struct_type,
3430 455945 : TYPE_UID (TREE_TYPE (decl_type)));
3431 590259 : rvi->is_restrict_var = 1;
3432 590259 : insert_vi_for_tree (heapvar, rvi);
3433 590259 : make_constraint_from (vi, rvi->id);
3434 590259 : make_param_constraints (rvi);
3435 : }
3436 78615886 : fieldstack.release ();
3437 78615886 : return vi;
3438 : }
3439 :
3440 7580172 : vi = new_var_info (decl, name, add_id);
3441 7580172 : vi->fullsize = tree_to_uhwi (declsize);
3442 7580172 : if (fieldstack.length () == 1)
3443 1662196 : vi->is_full_var = true;
3444 7580172 : for (i = 0, newvi = vi;
3445 124780525 : fieldstack.iterate (i, &fo);
3446 22459757 : ++i, newvi = vi_next (newvi))
3447 : {
3448 22459757 : const char *newname = NULL;
3449 22459757 : char *tempname;
3450 :
3451 22459757 : if (dump_file)
3452 : {
3453 334 : if (fieldstack.length () != 1)
3454 : {
3455 304 : tempname
3456 304 : = xasprintf ("%s." HOST_WIDE_INT_PRINT_DEC
3457 : "+" HOST_WIDE_INT_PRINT_DEC, name,
3458 : fo->offset, fo->size);
3459 304 : newname = ggc_strdup (tempname);
3460 304 : free (tempname);
3461 : }
3462 : }
3463 : else
3464 : newname = "NULL";
3465 :
3466 304 : if (newname)
3467 22459727 : newvi->name = newname;
3468 22459757 : newvi->offset = fo->offset;
3469 22459757 : newvi->size = fo->size;
3470 22459757 : newvi->fullsize = vi->fullsize;
3471 22459757 : newvi->may_have_pointers = fo->may_have_pointers;
3472 22459757 : newvi->only_restrict_pointers = fo->only_restrict_pointers;
3473 22459757 : if (handle_param
3474 1712591 : && newvi->only_restrict_pointers
3475 30520 : && !type_contains_placeholder_p (fo->restrict_pointed_type)
3476 22490277 : && !bitmap_bit_p (handled_struct_type,
3477 30520 : TYPE_UID (fo->restrict_pointed_type)))
3478 : {
3479 30517 : varinfo_t rvi;
3480 30517 : tree heapvar = build_fake_var_decl (fo->restrict_pointed_type);
3481 30517 : DECL_EXTERNAL (heapvar) = 1;
3482 30517 : if (var_can_have_subvars (heapvar))
3483 82 : bitmap_set_bit (handled_struct_type,
3484 41 : TYPE_UID (fo->restrict_pointed_type));
3485 30517 : rvi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS", true,
3486 : true, handled_struct_type);
3487 30517 : if (var_can_have_subvars (heapvar))
3488 82 : bitmap_clear_bit (handled_struct_type,
3489 41 : TYPE_UID (fo->restrict_pointed_type));
3490 30517 : rvi->is_restrict_var = 1;
3491 30517 : insert_vi_for_tree (heapvar, rvi);
3492 30517 : make_constraint_from (newvi, rvi->id);
3493 30517 : make_param_constraints (rvi);
3494 : }
3495 37339342 : if (i + 1 < fieldstack.length ())
3496 : {
3497 14879585 : varinfo_t tem = new_var_info (decl, name, false);
3498 14879585 : newvi->next = tem->id;
3499 14879585 : tem->head = vi->id;
3500 : }
3501 : }
3502 :
3503 : return vi;
3504 94740596 : }
3505 :
3506 : static unsigned int
3507 84440583 : create_variable_info_for (tree decl, const char *name, bool add_id)
3508 : {
3509 : /* First see if we are dealing with an ifunc resolver call and
3510 : associate that with a call to the resolver function result. */
3511 84440583 : cgraph_node *node;
3512 84440583 : if (in_ipa_mode
3513 704807 : && TREE_CODE (decl) == FUNCTION_DECL
3514 18353 : && (node = cgraph_node::get (decl))
3515 84458934 : && node->ifunc_resolver)
3516 : {
3517 1 : varinfo_t fi = get_vi_for_tree (node->get_alias_target ()->decl);
3518 1 : constraint_expr rhs
3519 1 : = get_function_part_constraint (fi, fi_result);
3520 1 : fi = new_var_info (NULL_TREE, "ifuncres", true);
3521 1 : fi->is_reg_var = true;
3522 1 : constraint_expr lhs;
3523 1 : lhs.type = SCALAR;
3524 1 : lhs.var = fi->id;
3525 1 : lhs.offset = 0;
3526 1 : process_constraint (new_constraint (lhs, rhs));
3527 1 : insert_vi_for_tree (decl, fi);
3528 1 : return fi->id;
3529 : }
3530 :
3531 84440582 : varinfo_t vi = create_variable_info_for_1 (decl, name, add_id, false, NULL);
3532 84440582 : unsigned int id = vi->id;
3533 :
3534 84440582 : insert_vi_for_tree (decl, vi);
3535 :
3536 84440582 : if (!VAR_P (decl))
3537 : return id;
3538 :
3539 : /* Create initial constraints for globals. */
3540 33910706 : for (; vi; vi = vi_next (vi))
3541 : {
3542 23817946 : if (!vi->may_have_pointers
3543 23817946 : || !vi->is_global_var)
3544 15593807 : continue;
3545 :
3546 : /* Mark global restrict qualified pointers. */
3547 16088366 : if ((POINTER_TYPE_P (TREE_TYPE (decl))
3548 360067 : && TYPE_RESTRICT (TREE_TYPE (decl)))
3549 16440622 : || vi->only_restrict_pointers)
3550 : {
3551 13568 : varinfo_t rvi
3552 13568 : = make_constraint_from_global_restrict (vi, "GLOBAL_RESTRICT",
3553 : true);
3554 : /* ??? For now exclude reads from globals as restrict sources
3555 : if those are not (indirectly) from incoming parameters. */
3556 13568 : rvi->is_restrict_var = false;
3557 13568 : continue;
3558 13568 : }
3559 :
3560 : /* In non-IPA mode the initializer from nonlocal is all we need. */
3561 8210571 : if (!in_ipa_mode
3562 8247583 : || DECL_HARD_REGISTER (decl))
3563 8173559 : make_copy_constraint (vi, nonlocal_id);
3564 :
3565 : /* In IPA mode parse the initializer and generate proper constraints
3566 : for it. */
3567 : else
3568 : {
3569 37012 : varpool_node *vnode = varpool_node::get (decl);
3570 :
3571 : /* For escaped variables initialize them from nonlocal. */
3572 37012 : if (!vnode || !vnode->all_refs_explicit_p ())
3573 1456 : make_copy_constraint (vi, nonlocal_id);
3574 :
3575 : /* While we can in theory walk references for the varpool
3576 : node that does not cover zero-initialization or references
3577 : to the constant pool. */
3578 37012 : if (DECL_INITIAL (decl))
3579 : {
3580 35914 : auto_vec<ce_s> rhsc;
3581 35914 : struct constraint_expr lhs, *rhsp;
3582 35914 : unsigned i;
3583 35914 : lhs.var = vi->id;
3584 35914 : lhs.offset = 0;
3585 35914 : lhs.type = SCALAR;
3586 35914 : get_constraint_for (DECL_INITIAL (decl), &rhsc);
3587 184583 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
3588 112755 : process_constraint (new_constraint (lhs, *rhsp));
3589 : /* If this is a variable that escapes from the unit
3590 : the initializer escapes as well. */
3591 35914 : if (!vnode || !vnode->all_refs_explicit_p ())
3592 : {
3593 2167 : lhs.var = escaped_id;
3594 2167 : lhs.offset = 0;
3595 2167 : lhs.type = SCALAR;
3596 38081 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
3597 1556 : process_constraint (new_constraint (lhs, *rhsp));
3598 : }
3599 35914 : }
3600 : }
3601 : }
3602 :
3603 : return id;
3604 : }
3605 :
3606 : /* Register the constraints for function parameter related VI. */
3607 :
3608 : static void
3609 10300014 : make_param_constraints (varinfo_t vi)
3610 : {
3611 11699215 : for (; vi; vi = vi_next (vi))
3612 : {
3613 11210337 : if (vi->only_restrict_pointers)
3614 : ;
3615 10589558 : else if (vi->may_have_pointers)
3616 10589558 : make_constraint_from (vi, nonlocal_id);
3617 :
3618 11210337 : if (vi->is_full_var)
3619 : break;
3620 : }
3621 10300014 : }
3622 :
3623 : /* Create varinfo structures for parameters, return value and the static
3624 : chain of FN. Intended for intraprocedural mode. */
3625 :
3626 : static void
3627 4619994 : intra_create_variable_infos (struct function *fn)
3628 : {
3629 4619994 : tree t;
3630 4619994 : bitmap handled_struct_type = NULL;
3631 4619994 : bool this_parm_in_ctor = DECL_CXX_CONSTRUCTOR_P (fn->decl);
3632 :
3633 : /* For each incoming pointer argument arg, create the constraint ARG
3634 : = NONLOCAL or a dummy variable if it is a restrict qualified
3635 : passed-by-reference argument. */
3636 14299232 : for (t = DECL_ARGUMENTS (fn->decl); t; t = DECL_CHAIN (t))
3637 : {
3638 9679238 : if (handled_struct_type == NULL)
3639 3902003 : handled_struct_type = BITMAP_ALLOC (NULL);
3640 :
3641 9679238 : varinfo_t p
3642 9679238 : = create_variable_info_for_1 (t, alias_get_name (t), false, true,
3643 : handled_struct_type, this_parm_in_ctor);
3644 9679238 : insert_vi_for_tree (t, p);
3645 :
3646 9679238 : make_param_constraints (p);
3647 :
3648 9679238 : this_parm_in_ctor = false;
3649 : }
3650 :
3651 4619994 : if (handled_struct_type != NULL)
3652 3902003 : BITMAP_FREE (handled_struct_type);
3653 :
3654 : /* Add a constraint for a result decl that is passed by reference. */
3655 4619994 : if (DECL_RESULT (fn->decl)
3656 4619994 : && DECL_BY_REFERENCE (DECL_RESULT (fn->decl)))
3657 : {
3658 59684 : varinfo_t p, result_vi = get_vi_for_tree (DECL_RESULT (fn->decl));
3659 :
3660 179052 : for (p = result_vi; p; p = vi_next (p))
3661 59684 : make_constraint_from (p, nonlocal_id);
3662 : }
3663 :
3664 : /* Add a constraint for the incoming static chain parameter. */
3665 4619994 : if (fn->static_chain_decl != NULL_TREE)
3666 : {
3667 47459 : varinfo_t p, chain_vi = get_vi_for_tree (fn->static_chain_decl);
3668 :
3669 142377 : for (p = chain_vi; p; p = vi_next (p))
3670 47459 : make_constraint_from (p, nonlocal_id);
3671 : }
3672 4619994 : }
3673 :
3674 : /* Initialize the always-existing constraint variables for NULL
3675 : ANYTHING, READONLY, and INTEGER. */
3676 :
3677 : static void
3678 4624489 : init_base_vars (void)
3679 : {
3680 4624489 : struct constraint_expr lhs, rhs;
3681 4624489 : varinfo_t var_anything;
3682 4624489 : varinfo_t var_nothing;
3683 4624489 : varinfo_t var_string;
3684 4624489 : varinfo_t var_escaped;
3685 4624489 : varinfo_t var_nonlocal;
3686 4624489 : varinfo_t var_escaped_return;
3687 4624489 : varinfo_t var_storedanything;
3688 4624489 : varinfo_t var_integer;
3689 :
3690 : /* Variable ID zero is reserved and should be NULL. */
3691 4624489 : varmap.safe_push (NULL);
3692 :
3693 : /* Create the NULL variable, used to represent that a variable points
3694 : to NULL. */
3695 4624489 : var_nothing = new_var_info (NULL_TREE, "NULL", false);
3696 4624489 : gcc_assert (var_nothing->id == nothing_id);
3697 4624489 : var_nothing->is_artificial_var = 1;
3698 4624489 : var_nothing->offset = 0;
3699 4624489 : var_nothing->size = ~0;
3700 4624489 : var_nothing->fullsize = ~0;
3701 4624489 : var_nothing->is_special_var = 1;
3702 4624489 : var_nothing->may_have_pointers = 0;
3703 4624489 : var_nothing->is_global_var = 0;
3704 :
3705 : /* Create the ANYTHING variable, used to represent that a variable
3706 : points to some unknown piece of memory. */
3707 4624489 : var_anything = new_var_info (NULL_TREE, "ANYTHING", false);
3708 4624489 : gcc_assert (var_anything->id == anything_id);
3709 4624489 : var_anything->is_artificial_var = 1;
3710 4624489 : var_anything->size = ~0;
3711 4624489 : var_anything->offset = 0;
3712 4624489 : var_anything->fullsize = ~0;
3713 4624489 : var_anything->is_special_var = 1;
3714 :
3715 : /* Anything points to anything. This makes deref constraints just
3716 : work in the presence of linked list and other p = *p type loops,
3717 : by saying that *ANYTHING = ANYTHING. */
3718 4624489 : lhs.type = SCALAR;
3719 4624489 : lhs.var = anything_id;
3720 4624489 : lhs.offset = 0;
3721 4624489 : rhs.type = ADDRESSOF;
3722 4624489 : rhs.var = anything_id;
3723 4624489 : rhs.offset = 0;
3724 :
3725 : /* This specifically does not use process_constraint because
3726 : process_constraint ignores all anything = anything constraints, since all
3727 : but this one are redundant. */
3728 4624489 : constraints.safe_push (new_constraint (lhs, rhs));
3729 :
3730 : /* Create the STRING variable, used to represent that a variable
3731 : points to a string literal. String literals don't contain
3732 : pointers so STRING doesn't point to anything. */
3733 4624489 : var_string = new_var_info (NULL_TREE, "STRING", false);
3734 4624489 : gcc_assert (var_string->id == string_id);
3735 4624489 : var_string->is_artificial_var = 1;
3736 4624489 : var_string->offset = 0;
3737 4624489 : var_string->size = ~0;
3738 4624489 : var_string->fullsize = ~0;
3739 4624489 : var_string->is_special_var = 1;
3740 4624489 : var_string->may_have_pointers = 0;
3741 :
3742 : /* Create the ESCAPED variable, used to represent the set of escaped
3743 : memory. */
3744 4624489 : var_escaped = new_var_info (NULL_TREE, "ESCAPED", false);
3745 4624489 : gcc_assert (var_escaped->id == escaped_id);
3746 4624489 : var_escaped->is_artificial_var = 1;
3747 4624489 : var_escaped->offset = 0;
3748 4624489 : var_escaped->size = ~0;
3749 4624489 : var_escaped->fullsize = ~0;
3750 4624489 : var_escaped->is_special_var = 0;
3751 :
3752 : /* Create the NONLOCAL variable, used to represent the set of nonlocal
3753 : memory. */
3754 4624489 : var_nonlocal = new_var_info (NULL_TREE, "NONLOCAL", false);
3755 4624489 : gcc_assert (var_nonlocal->id == nonlocal_id);
3756 4624489 : var_nonlocal->is_artificial_var = 1;
3757 4624489 : var_nonlocal->offset = 0;
3758 4624489 : var_nonlocal->size = ~0;
3759 4624489 : var_nonlocal->fullsize = ~0;
3760 4624489 : var_nonlocal->is_special_var = 1;
3761 :
3762 : /* Create the ESCAPED_RETURN variable, used to represent the set of escaped
3763 : memory via a regular return stmt. */
3764 4624489 : var_escaped_return = new_var_info (NULL_TREE, "ESCAPED_RETURN", false);
3765 4624489 : gcc_assert (var_escaped_return->id == escaped_return_id);
3766 4624489 : var_escaped_return->is_artificial_var = 1;
3767 4624489 : var_escaped_return->offset = 0;
3768 4624489 : var_escaped_return->size = ~0;
3769 4624489 : var_escaped_return->fullsize = ~0;
3770 4624489 : var_escaped_return->is_special_var = 0;
3771 :
3772 : /* ESCAPED = *ESCAPED, because escaped is may-deref'd at calls, etc. */
3773 4624489 : lhs.type = SCALAR;
3774 4624489 : lhs.var = escaped_id;
3775 4624489 : lhs.offset = 0;
3776 4624489 : rhs.type = DEREF;
3777 4624489 : rhs.var = escaped_id;
3778 4624489 : rhs.offset = 0;
3779 4624489 : process_constraint (new_constraint (lhs, rhs));
3780 :
3781 : /* ESCAPED = ESCAPED + UNKNOWN_OFFSET, because if a sub-field escapes the
3782 : whole variable escapes. */
3783 4624489 : lhs.type = SCALAR;
3784 4624489 : lhs.var = escaped_id;
3785 4624489 : lhs.offset = 0;
3786 4624489 : rhs.type = SCALAR;
3787 4624489 : rhs.var = escaped_id;
3788 4624489 : rhs.offset = UNKNOWN_OFFSET;
3789 4624489 : process_constraint (new_constraint (lhs, rhs));
3790 :
3791 : /* *ESCAPED = NONLOCAL. This is true because we have to assume
3792 : everything pointed to by escaped points to what global memory can
3793 : point to. */
3794 4624489 : lhs.type = DEREF;
3795 4624489 : lhs.var = escaped_id;
3796 4624489 : lhs.offset = 0;
3797 4624489 : rhs.type = SCALAR;
3798 4624489 : rhs.var = nonlocal_id;
3799 4624489 : rhs.offset = 0;
3800 4624489 : process_constraint (new_constraint (lhs, rhs));
3801 :
3802 : /* NONLOCAL = &NONLOCAL, NONLOCAL = &ESCAPED. This is true because
3803 : global memory may point to global memory and escaped memory. */
3804 4624489 : lhs.type = SCALAR;
3805 4624489 : lhs.var = nonlocal_id;
3806 4624489 : lhs.offset = 0;
3807 4624489 : rhs.type = ADDRESSOF;
3808 4624489 : rhs.var = nonlocal_id;
3809 4624489 : rhs.offset = 0;
3810 4624489 : process_constraint (new_constraint (lhs, rhs));
3811 4624489 : rhs.type = ADDRESSOF;
3812 4624489 : rhs.var = escaped_id;
3813 4624489 : rhs.offset = 0;
3814 4624489 : process_constraint (new_constraint (lhs, rhs));
3815 :
3816 : /* Transitively close ESCAPED_RETURN.
3817 : ESCAPED_RETURN = ESCAPED_RETURN + UNKNOWN_OFFSET
3818 : ESCAPED_RETURN = *ESCAPED_RETURN. */
3819 4624489 : lhs.type = SCALAR;
3820 4624489 : lhs.var = escaped_return_id;
3821 4624489 : lhs.offset = 0;
3822 4624489 : rhs.type = SCALAR;
3823 4624489 : rhs.var = escaped_return_id;
3824 4624489 : rhs.offset = UNKNOWN_OFFSET;
3825 4624489 : process_constraint (new_constraint (lhs, rhs));
3826 4624489 : lhs.type = SCALAR;
3827 4624489 : lhs.var = escaped_return_id;
3828 4624489 : lhs.offset = 0;
3829 4624489 : rhs.type = DEREF;
3830 4624489 : rhs.var = escaped_return_id;
3831 4624489 : rhs.offset = 0;
3832 4624489 : process_constraint (new_constraint (lhs, rhs));
3833 :
3834 : /* Create the STOREDANYTHING variable, used to represent the set of
3835 : variables stored to *ANYTHING. */
3836 4624489 : var_storedanything = new_var_info (NULL_TREE, "STOREDANYTHING", false);
3837 4624489 : gcc_assert (var_storedanything->id == storedanything_id);
3838 4624489 : var_storedanything->is_artificial_var = 1;
3839 4624489 : var_storedanything->offset = 0;
3840 4624489 : var_storedanything->size = ~0;
3841 4624489 : var_storedanything->fullsize = ~0;
3842 4624489 : var_storedanything->is_special_var = 0;
3843 :
3844 : /* Create the INTEGER variable, used to represent that a variable points
3845 : to what an INTEGER "points to". */
3846 4624489 : var_integer = new_var_info (NULL_TREE, "INTEGER", false);
3847 4624489 : gcc_assert (var_integer->id == integer_id);
3848 4624489 : var_integer->is_artificial_var = 1;
3849 4624489 : var_integer->size = ~0;
3850 4624489 : var_integer->fullsize = ~0;
3851 4624489 : var_integer->offset = 0;
3852 4624489 : var_integer->is_special_var = 1;
3853 :
3854 : /* INTEGER = ANYTHING, because we don't know where a dereference of
3855 : a random integer will point to. */
3856 4624489 : lhs.type = SCALAR;
3857 4624489 : lhs.var = integer_id;
3858 4624489 : lhs.offset = 0;
3859 4624489 : rhs.type = ADDRESSOF;
3860 4624489 : rhs.var = anything_id;
3861 4624489 : rhs.offset = 0;
3862 4624489 : process_constraint (new_constraint (lhs, rhs));
3863 4624489 : }
3864 :
3865 : /* Associate node with varinfo DATA. Worker for
3866 : cgraph_for_symbol_thunks_and_aliases. */
3867 : static bool
3868 23941 : associate_varinfo_to_alias (struct cgraph_node *node, void *data)
3869 : {
3870 23941 : if ((node->alias
3871 23888 : || (node->thunk
3872 3 : && ! node->inlined_to))
3873 53 : && node->analyzed
3874 53 : && !node->ifunc_resolver)
3875 52 : insert_vi_for_tree (node->decl, (varinfo_t)data);
3876 23941 : return false;
3877 : }
3878 :
3879 : /* Compute whether node is referred to non-locally. Worker for
3880 : cgraph_for_symbol_thunks_and_aliases. */
3881 : static bool
3882 23941 : refered_from_nonlocal_fn (struct cgraph_node *node, void *data)
3883 : {
3884 23941 : bool *nonlocal_p = (bool *)data;
3885 47882 : *nonlocal_p |= (node->used_from_other_partition
3886 23895 : || DECL_EXTERNAL (node->decl)
3887 23890 : || TREE_PUBLIC (node->decl)
3888 16808 : || node->force_output
3889 16798 : || node->ref_by_asm
3890 40739 : || lookup_attribute ("noipa", DECL_ATTRIBUTES (node->decl)));
3891 23941 : return false;
3892 : }
3893 :
3894 : /* Same for varpool nodes. */
3895 : static bool
3896 37215 : refered_from_nonlocal_var (struct varpool_node *node, void *data)
3897 : {
3898 37215 : bool *nonlocal_p = (bool *)data;
3899 74430 : *nonlocal_p |= (node->used_from_other_partition
3900 37114 : || DECL_EXTERNAL (node->decl)
3901 36628 : || TREE_PUBLIC (node->decl)
3902 35576 : || node->ref_by_asm
3903 72791 : || node->force_output);
3904 37215 : return false;
3905 : }
3906 :
3907 : /* Create function infos. */
3908 :
3909 : static void
3910 4495 : ipa_create_function_infos (void)
3911 : {
3912 4495 : struct cgraph_node *node;
3913 4495 : unsigned int constr_count = constraints.length ();
3914 :
3915 29628 : FOR_EACH_DEFINED_FUNCTION (node)
3916 : {
3917 25133 : varinfo_t vi;
3918 : /* Nodes without a body in this partition are not interesting.
3919 : Especially do not visit clones at this point for now - we
3920 : get duplicate decls there for inline clones at least. */
3921 26381 : if (!node->has_gimple_body_p ()
3922 25032 : || node->in_other_partition
3923 50165 : || node->inlined_to)
3924 1248 : continue;
3925 23885 : node->get_body ();
3926 :
3927 23885 : gcc_assert (!node->clone_of);
3928 :
3929 : /* For externally visible or attribute used annotated functions use
3930 : local constraints for their arguments.
3931 : For local functions we see all callers and thus do not need initial
3932 : constraints for parameters. */
3933 23885 : bool nonlocal_p = (node->used_from_other_partition
3934 23839 : || DECL_EXTERNAL (node->decl)
3935 23835 : || TREE_PUBLIC (node->decl)
3936 16804 : || node->force_output
3937 40679 : || lookup_attribute ("noipa",
3938 16794 : DECL_ATTRIBUTES (node->decl)));
3939 23885 : node->call_for_symbol_thunks_and_aliases (refered_from_nonlocal_fn,
3940 : &nonlocal_p, true);
3941 :
3942 23885 : vi = create_function_info_for (node->decl,
3943 : alias_get_name (node->decl), false,
3944 : nonlocal_p);
3945 57 : if (dump_file && (dump_flags & TDF_DETAILS)
3946 23940 : && constr_count != constraints.length ())
3947 : {
3948 22 : fprintf (dump_file,
3949 : "Generating initial constraints for %s",
3950 : node->dump_name ());
3951 22 : if (DECL_ASSEMBLER_NAME_SET_P (node->decl))
3952 44 : fprintf (dump_file, " (%s)",
3953 22 : IDENTIFIER_POINTER
3954 : (DECL_ASSEMBLER_NAME (node->decl)));
3955 22 : fprintf (dump_file, "\n\n");
3956 22 : dump_constraints (dump_file, constr_count);
3957 22 : fprintf (dump_file, "\n");
3958 :
3959 22 : constr_count = constraints.length ();
3960 : }
3961 :
3962 23885 : node->call_for_symbol_thunks_and_aliases
3963 23885 : (associate_varinfo_to_alias, vi, true);
3964 : }
3965 4495 : }
3966 :
3967 : /* Create constraints for global variables and their initializers. */
3968 :
3969 : static void
3970 4495 : ipa_create_global_variable_infos (void)
3971 : {
3972 4495 : varpool_node *var;
3973 4495 : unsigned int constr_count = constraints.length ();
3974 :
3975 41710 : FOR_EACH_VARIABLE (var)
3976 : {
3977 37215 : if (var->alias && var->analyzed)
3978 17 : continue;
3979 :
3980 37198 : varinfo_t vi = get_vi_for_tree (var->decl);
3981 :
3982 : /* For the purpose of IPA PTA unit-local globals are not
3983 : escape points. */
3984 37198 : bool nonlocal_p = (DECL_EXTERNAL (var->decl)
3985 36712 : || TREE_PUBLIC (var->decl)
3986 35560 : || var->used_from_other_partition
3987 35560 : || var->force_output
3988 72754 : || var->ref_by_asm);
3989 37198 : var->call_for_symbol_and_aliases (refered_from_nonlocal_var,
3990 : &nonlocal_p, true);
3991 37198 : if (nonlocal_p)
3992 1643 : vi->is_ipa_escape_point = true;
3993 : }
3994 :
3995 20 : if (dump_file && (dump_flags & TDF_DETAILS)
3996 4513 : && constr_count != constraints.length ())
3997 : {
3998 11 : fprintf (dump_file,
3999 : "Generating constraints for global initializers\n\n");
4000 11 : dump_constraints (dump_file, constr_count);
4001 11 : fprintf (dump_file, "\n");
4002 11 : constr_count = constraints.length ();
4003 : }
4004 4495 : }
4005 :
4006 :
4007 : namespace pointer_analysis {
4008 :
4009 : /* Find the variable info for tree T in VI_FOR_TREE. If T does not
4010 : exist in the map, return NULL, otherwise, return the varinfo we found. */
4011 :
4012 : varinfo_t
4013 53913918 : lookup_vi_for_tree (tree t)
4014 : {
4015 53913918 : varinfo_t *slot = vi_for_tree->get (t);
4016 53913918 : if (slot == NULL)
4017 : return NULL;
4018 :
4019 51824539 : return *slot;
4020 : }
4021 :
4022 : /* Lookup the variable for the call statement CALL representing
4023 : the uses. Returns NULL if there is nothing special about this call. */
4024 :
4025 : varinfo_t
4026 31890582 : lookup_call_use_vi (gcall *call)
4027 : {
4028 31890582 : varinfo_t *slot_p = call_stmt_vars->get (call);
4029 31890582 : if (slot_p)
4030 29904549 : return *slot_p;
4031 :
4032 : return NULL;
4033 : }
4034 :
4035 : /* Lookup the variable for the call statement CALL representing
4036 : the clobbers. Returns NULL if there is nothing special about this call. */
4037 :
4038 : varinfo_t
4039 15300865 : lookup_call_clobber_vi (gcall *call)
4040 : {
4041 15300865 : varinfo_t uses = lookup_call_use_vi (call);
4042 15300865 : if (!uses)
4043 : return NULL;
4044 :
4045 14317668 : return vi_next (uses);
4046 : }
4047 :
4048 : /* Return the varinfo for the callee of CALL. */
4049 :
4050 : varinfo_t
4051 17458375 : get_fi_for_callee (gcall *call)
4052 : {
4053 17458375 : tree decl, fn = gimple_call_fn (call);
4054 :
4055 17458375 : if (fn && TREE_CODE (fn) == OBJ_TYPE_REF)
4056 141157 : fn = OBJ_TYPE_REF_EXPR (fn);
4057 :
4058 : /* If we can directly resolve the function being called, do so.
4059 : Otherwise, it must be some sort of indirect expression that
4060 : we should still be able to handle. */
4061 17458375 : decl = gimple_call_addr_fndecl (fn);
4062 17458375 : if (decl)
4063 16029330 : return get_vi_for_tree (decl);
4064 :
4065 : /* If the function is anything other than a SSA name pointer we have no
4066 : clue and should be getting ANYFN (well, ANYTHING for now). */
4067 1429045 : if (!fn || TREE_CODE (fn) != SSA_NAME)
4068 948422 : return get_varinfo (anything_id);
4069 :
4070 480623 : if (SSA_NAME_IS_DEFAULT_DEF (fn)
4071 480623 : && (TREE_CODE (SSA_NAME_VAR (fn)) == PARM_DECL
4072 15 : || TREE_CODE (SSA_NAME_VAR (fn)) == RESULT_DECL))
4073 13379 : fn = SSA_NAME_VAR (fn);
4074 :
4075 480623 : return get_vi_for_tree (fn);
4076 : }
4077 :
4078 : /* Initialize constraint builder. */
4079 :
4080 : void
4081 4624489 : init_constraint_builder (void)
4082 : {
4083 4624489 : vi_for_tree = new hash_map<tree, varinfo_t>;
4084 4624489 : call_stmt_vars = new hash_map<gimple *, varinfo_t>;
4085 4624489 : gcc_obstack_init (&fake_var_decl_obstack);
4086 :
4087 4624489 : init_base_vars ();
4088 4624489 : }
4089 :
4090 : /* Deallocate constraint builder globals. */
4091 :
4092 : void
4093 4624489 : delete_constraint_builder (void)
4094 : {
4095 9248978 : delete vi_for_tree;
4096 9248978 : delete call_stmt_vars;
4097 4624489 : constraint_pool.release ();
4098 4624489 : obstack_free (&fake_var_decl_obstack, NULL);
4099 4624489 : }
4100 :
4101 : /* Build constraints for intraprocedural mode. */
4102 :
4103 : void
4104 4619994 : intra_build_constraints (void)
4105 : {
4106 4619994 : basic_block bb;
4107 :
4108 4619994 : intra_create_variable_infos (cfun);
4109 :
4110 : /* Now walk all statements and build the constraint set. */
4111 41035184 : FOR_EACH_BB_FN (bb, cfun)
4112 : {
4113 48347516 : for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
4114 11932326 : gsi_next (&gsi))
4115 : {
4116 11932326 : gphi *phi = gsi.phi ();
4117 :
4118 23864652 : if (! virtual_operand_p (gimple_phi_result (phi)))
4119 6236358 : find_func_aliases (cfun, phi);
4120 : }
4121 :
4122 345898144 : for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
4123 273067764 : gsi_next (&gsi))
4124 : {
4125 273067764 : gimple *stmt = gsi_stmt (gsi);
4126 :
4127 273067764 : find_func_aliases (cfun, stmt);
4128 : }
4129 : }
4130 :
4131 4619994 : if (dump_file && (dump_flags & TDF_DETAILS))
4132 : {
4133 283 : fprintf (dump_file, "Points-to analysis\n\nConstraints:\n\n");
4134 283 : dump_constraints (dump_file, 0);
4135 : }
4136 4619994 : }
4137 :
4138 : /* Build constraints for ipa mode. */
4139 :
4140 : void
4141 4495 : ipa_build_constraints (void)
4142 : {
4143 4495 : struct cgraph_node *node;
4144 :
4145 4495 : ipa_create_function_infos ();
4146 4495 : ipa_create_global_variable_infos ();
4147 :
4148 4495 : unsigned int constr_count = constraints.length ();
4149 :
4150 28433 : FOR_EACH_DEFINED_FUNCTION (node)
4151 : {
4152 23938 : struct function *func;
4153 23938 : basic_block bb;
4154 :
4155 : /* Nodes without a body in this partition are not interesting. */
4156 23991 : if (!node->has_gimple_body_p ()
4157 23885 : || node->in_other_partition
4158 47823 : || node->clone_of)
4159 53 : continue;
4160 :
4161 23885 : if (dump_file && (dump_flags & TDF_DETAILS))
4162 : {
4163 55 : fprintf (dump_file,
4164 : "Generating constraints for %s", node->dump_name ());
4165 55 : if (DECL_ASSEMBLER_NAME_SET_P (node->decl))
4166 110 : fprintf (dump_file, " (%s)",
4167 55 : IDENTIFIER_POINTER
4168 : (DECL_ASSEMBLER_NAME (node->decl)));
4169 55 : fprintf (dump_file, "\n");
4170 : }
4171 :
4172 23885 : func = DECL_STRUCT_FUNCTION (node->decl);
4173 23885 : gcc_assert (cfun == NULL);
4174 :
4175 : /* Build constraints for the function body. */
4176 363569 : FOR_EACH_BB_FN (bb, func)
4177 : {
4178 448724 : for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
4179 109040 : gsi_next (&gsi))
4180 : {
4181 109040 : gphi *phi = gsi.phi ();
4182 :
4183 218080 : if (! virtual_operand_p (gimple_phi_result (phi)))
4184 64529 : find_func_aliases (func, phi);
4185 : }
4186 :
4187 1655573 : for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
4188 976205 : gsi_next (&gsi))
4189 : {
4190 976205 : gimple *stmt = gsi_stmt (gsi);
4191 :
4192 976205 : find_func_aliases (func, stmt);
4193 976205 : find_func_clobbers (func, stmt);
4194 : }
4195 : }
4196 :
4197 23885 : if (dump_file && (dump_flags & TDF_DETAILS))
4198 : {
4199 55 : fprintf (dump_file, "\n");
4200 55 : dump_constraints (dump_file, constr_count);
4201 55 : fprintf (dump_file, "\n");
4202 23993 : constr_count = constraints.length ();
4203 : }
4204 : }
4205 4495 : }
4206 :
4207 : } // namespace pointer_analysis
|