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

Generated by: LCOV version 2.4-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.