LCOV - code coverage report
Current view: top level - gcc - gimple-ssa-pta-constraints.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 97.4 % 2308 2247
Test Date: 2026-10-17 16:30:31 Functions: 98.6 % 69 68
Legend: Lines:     hit not hit

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

Generated by: LCOV version 2.5.0-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.