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