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