LCOV - code coverage report
Current view: top level - gcc - tree-ssa-structalias.c (source / functions) Hit Total Coverage
Test: gcc.info Lines: 3869 4079 94.9 %
Date: 2020-04-04 11:58:09 Functions: 141 161 87.6 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /* Tree based points-to analysis
       2                 :            :    Copyright (C) 2005-2020 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                 :            : 
      47                 :            : /* The idea behind this analyzer is to generate set constraints from the
      48                 :            :    program, then solve the resulting constraints in order to generate the
      49                 :            :    points-to sets.
      50                 :            : 
      51                 :            :    Set constraints are a way of modeling program analysis problems that
      52                 :            :    involve sets.  They consist of an inclusion constraint language,
      53                 :            :    describing the variables (each variable is a set) and operations that
      54                 :            :    are involved on the variables, and a set of rules that derive facts
      55                 :            :    from these operations.  To solve a system of set constraints, you derive
      56                 :            :    all possible facts under the rules, which gives you the correct sets
      57                 :            :    as a consequence.
      58                 :            : 
      59                 :            :    See  "Efficient Field-sensitive pointer analysis for C" by "David
      60                 :            :    J. Pearce and Paul H. J. Kelly and Chris Hankin, at
      61                 :            :    http://citeseer.ist.psu.edu/pearce04efficient.html
      62                 :            : 
      63                 :            :    Also see "Ultra-fast Aliasing Analysis using CLA: A Million Lines
      64                 :            :    of C Code in a Second" by ""Nevin Heintze and Olivier Tardieu" at
      65                 :            :    http://citeseer.ist.psu.edu/heintze01ultrafast.html
      66                 :            : 
      67                 :            :    There are three types of real constraint expressions, DEREF,
      68                 :            :    ADDRESSOF, and SCALAR.  Each constraint expression consists
      69                 :            :    of a constraint type, a variable, and an offset.
      70                 :            : 
      71                 :            :    SCALAR is a constraint expression type used to represent x, whether
      72                 :            :    it appears on the LHS or the RHS of a statement.
      73                 :            :    DEREF is a constraint expression type used to represent *x, whether
      74                 :            :    it appears on the LHS or the RHS of a statement.
      75                 :            :    ADDRESSOF is a constraint expression used to represent &x, whether
      76                 :            :    it appears on the LHS or the RHS of a statement.
      77                 :            : 
      78                 :            :    Each pointer variable in the program is assigned an integer id, and
      79                 :            :    each field of a structure variable is assigned an integer id as well.
      80                 :            : 
      81                 :            :    Structure variables are linked to their list of fields through a "next
      82                 :            :    field" in each variable that points to the next field in offset
      83                 :            :    order.
      84                 :            :    Each variable for a structure field has
      85                 :            : 
      86                 :            :    1. "size", that tells the size in bits of that field.
      87                 :            :    2. "fullsize, that tells the size in bits of the entire structure.
      88                 :            :    3. "offset", that tells the offset in bits from the beginning of the
      89                 :            :    structure to this field.
      90                 :            : 
      91                 :            :    Thus,
      92                 :            :    struct f
      93                 :            :    {
      94                 :            :      int a;
      95                 :            :      int b;
      96                 :            :    } foo;
      97                 :            :    int *bar;
      98                 :            : 
      99                 :            :    looks like
     100                 :            : 
     101                 :            :    foo.a -> id 1, size 32, offset 0, fullsize 64, next foo.b
     102                 :            :    foo.b -> id 2, size 32, offset 32, fullsize 64, next NULL
     103                 :            :    bar -> id 3, size 32, offset 0, fullsize 32, next NULL
     104                 :            : 
     105                 :            : 
     106                 :            :   In order to solve the system of set constraints, the following is
     107                 :            :   done:
     108                 :            : 
     109                 :            :   1. Each constraint variable x has a solution set associated with it,
     110                 :            :   Sol(x).
     111                 :            : 
     112                 :            :   2. Constraints are separated into direct, copy, and complex.
     113                 :            :   Direct constraints are ADDRESSOF constraints that require no extra
     114                 :            :   processing, such as P = &Q
     115                 :            :   Copy constraints are those of the form P = Q.
     116                 :            :   Complex constraints are all the constraints involving dereferences
     117                 :            :   and offsets (including offsetted copies).
     118                 :            : 
     119                 :            :   3. All direct constraints of the form P = &Q are processed, such
     120                 :            :   that Q is added to Sol(P)
     121                 :            : 
     122                 :            :   4. All complex constraints for a given constraint variable are stored in a
     123                 :            :   linked list attached to that variable's node.
     124                 :            : 
     125                 :            :   5. A directed graph is built out of the copy constraints. Each
     126                 :            :   constraint variable is a node in the graph, and an edge from
     127                 :            :   Q to P is added for each copy constraint of the form P = Q
     128                 :            : 
     129                 :            :   6. The graph is then walked, and solution sets are
     130                 :            :   propagated along the copy edges, such that an edge from Q to P
     131                 :            :   causes Sol(P) <- Sol(P) union Sol(Q).
     132                 :            : 
     133                 :            :   7.  As we visit each node, all complex constraints associated with
     134                 :            :   that node are processed by adding appropriate copy edges to the graph, or the
     135                 :            :   appropriate variables to the solution set.
     136                 :            : 
     137                 :            :   8. The process of walking the graph is iterated until no solution
     138                 :            :   sets change.
     139                 :            : 
     140                 :            :   Prior to walking the graph in steps 6 and 7, We perform static
     141                 :            :   cycle elimination on the constraint graph, as well
     142                 :            :   as off-line variable substitution.
     143                 :            : 
     144                 :            :   TODO: Adding offsets to pointer-to-structures can be handled (IE not punted
     145                 :            :   on and turned into anything), but isn't.  You can just see what offset
     146                 :            :   inside the pointed-to struct it's going to access.
     147                 :            : 
     148                 :            :   TODO: Constant bounded arrays can be handled as if they were structs of the
     149                 :            :   same number of elements.
     150                 :            : 
     151                 :            :   TODO: Modeling heap and incoming pointers becomes much better if we
     152                 :            :   add fields to them as we discover them, which we could do.
     153                 :            : 
     154                 :            :   TODO: We could handle unions, but to be honest, it's probably not
     155                 :            :   worth the pain or slowdown.  */
     156                 :            : 
     157                 :            : /* IPA-PTA optimizations possible.
     158                 :            : 
     159                 :            :    When the indirect function called is ANYTHING we can add disambiguation
     160                 :            :    based on the function signatures (or simply the parameter count which
     161                 :            :    is the varinfo size).  We also do not need to consider functions that
     162                 :            :    do not have their address taken.
     163                 :            : 
     164                 :            :    The is_global_var bit which marks escape points is overly conservative
     165                 :            :    in IPA mode.  Split it to is_escape_point and is_global_var - only
     166                 :            :    externally visible globals are escape points in IPA mode.
     167                 :            :    There is now is_ipa_escape_point but this is only used in a few
     168                 :            :    selected places.
     169                 :            : 
     170                 :            :    The way we introduce DECL_PT_UID to avoid fixing up all points-to
     171                 :            :    sets in the translation unit when we copy a DECL during inlining
     172                 :            :    pessimizes precision.  The advantage is that the DECL_PT_UID keeps
     173                 :            :    compile-time and memory usage overhead low - the points-to sets
     174                 :            :    do not grow or get unshared as they would during a fixup phase.
     175                 :            :    An alternative solution is to delay IPA PTA until after all
     176                 :            :    inlining transformations have been applied.
     177                 :            : 
     178                 :            :    The way we propagate clobber/use information isn't optimized.
     179                 :            :    It should use a new complex constraint that properly filters
     180                 :            :    out local variables of the callee (though that would make
     181                 :            :    the sets invalid after inlining).  OTOH we might as well
     182                 :            :    admit defeat to WHOPR and simply do all the clobber/use analysis
     183                 :            :    and propagation after PTA finished but before we threw away
     184                 :            :    points-to information for memory variables.  WHOPR and PTA
     185                 :            :    do not play along well anyway - the whole constraint solving
     186                 :            :    would need to be done in WPA phase and it will be very interesting
     187                 :            :    to apply the results to local SSA names during LTRANS phase.
     188                 :            : 
     189                 :            :    We probably should compute a per-function unit-ESCAPE solution
     190                 :            :    propagating it simply like the clobber / uses solutions.  The
     191                 :            :    solution can go alongside the non-IPA espaced solution and be
     192                 :            :    used to query which vars escape the unit through a function.
     193                 :            :    This is also required to make the escaped-HEAP trick work in IPA mode.
     194                 :            : 
     195                 :            :    We never put function decls in points-to sets so we do not
     196                 :            :    keep the set of called functions for indirect calls.
     197                 :            : 
     198                 :            :    And probably more.  */
     199                 :            : 
     200                 :            : static bool use_field_sensitive = true;
     201                 :            : static int in_ipa_mode = 0;
     202                 :            : 
     203                 :            : /* Used for predecessor bitmaps. */
     204                 :            : static bitmap_obstack predbitmap_obstack;
     205                 :            : 
     206                 :            : /* Used for points-to sets.  */
     207                 :            : static bitmap_obstack pta_obstack;
     208                 :            : 
     209                 :            : /* Used for oldsolution members of variables. */
     210                 :            : static bitmap_obstack oldpta_obstack;
     211                 :            : 
     212                 :            : /* Used for per-solver-iteration bitmaps.  */
     213                 :            : static bitmap_obstack iteration_obstack;
     214                 :            : 
     215                 :            : static unsigned int create_variable_info_for (tree, const char *, bool);
     216                 :            : typedef struct constraint_graph *constraint_graph_t;
     217                 :            : static void unify_nodes (constraint_graph_t, unsigned int, unsigned int, bool);
     218                 :            : 
     219                 :            : struct constraint;
     220                 :            : typedef struct constraint *constraint_t;
     221                 :            : 
     222                 :            : 
     223                 :            : #define EXECUTE_IF_IN_NONNULL_BITMAP(a, b, c, d)        \
     224                 :            :   if (a)                                                \
     225                 :            :     EXECUTE_IF_SET_IN_BITMAP (a, b, c, d)
     226                 :            : 
     227                 :            : static struct constraint_stats
     228                 :            : {
     229                 :            :   unsigned int total_vars;
     230                 :            :   unsigned int nonpointer_vars;
     231                 :            :   unsigned int unified_vars_static;
     232                 :            :   unsigned int unified_vars_dynamic;
     233                 :            :   unsigned int iterations;
     234                 :            :   unsigned int num_edges;
     235                 :            :   unsigned int num_implicit_edges;
     236                 :            :   unsigned int points_to_sets_created;
     237                 :            : } stats;
     238                 :            : 
     239                 :            : struct variable_info
     240                 :            : {
     241                 :            :   /* ID of this variable  */
     242                 :            :   unsigned int id;
     243                 :            : 
     244                 :            :   /* True if this is a variable created by the constraint analysis, such as
     245                 :            :      heap variables and constraints we had to break up.  */
     246                 :            :   unsigned int is_artificial_var : 1;
     247                 :            : 
     248                 :            :   /* True if this is a special variable whose solution set should not be
     249                 :            :      changed.  */
     250                 :            :   unsigned int is_special_var : 1;
     251                 :            : 
     252                 :            :   /* True for variables whose size is not known or variable.  */
     253                 :            :   unsigned int is_unknown_size_var : 1;
     254                 :            : 
     255                 :            :   /* True for (sub-)fields that represent a whole variable.  */
     256                 :            :   unsigned int is_full_var : 1;
     257                 :            : 
     258                 :            :   /* True if this is a heap variable.  */
     259                 :            :   unsigned int is_heap_var : 1;
     260                 :            : 
     261                 :            :   /* True if this is a register variable.  */
     262                 :            :   unsigned int is_reg_var : 1;
     263                 :            : 
     264                 :            :   /* True if this field may contain pointers.  */
     265                 :            :   unsigned int may_have_pointers : 1;
     266                 :            : 
     267                 :            :   /* True if this field has only restrict qualified pointers.  */
     268                 :            :   unsigned int only_restrict_pointers : 1;
     269                 :            : 
     270                 :            :   /* True if this represents a heap var created for a restrict qualified
     271                 :            :      pointer.  */
     272                 :            :   unsigned int is_restrict_var : 1;
     273                 :            : 
     274                 :            :   /* True if this represents a global variable.  */
     275                 :            :   unsigned int is_global_var : 1;
     276                 :            : 
     277                 :            :   /* True if this represents a module escape point for IPA analysis.  */
     278                 :            :   unsigned int is_ipa_escape_point : 1;
     279                 :            : 
     280                 :            :   /* True if this represents a IPA function info.  */
     281                 :            :   unsigned int is_fn_info : 1;
     282                 :            : 
     283                 :            :   /* ???  Store somewhere better.  */
     284                 :            :   unsigned short ruid;
     285                 :            : 
     286                 :            :   /* The ID of the variable for the next field in this structure
     287                 :            :      or zero for the last field in this structure.  */
     288                 :            :   unsigned next;
     289                 :            : 
     290                 :            :   /* The ID of the variable for the first field in this structure.  */
     291                 :            :   unsigned head;
     292                 :            : 
     293                 :            :   /* Offset of this variable, in bits, from the base variable  */
     294                 :            :   unsigned HOST_WIDE_INT offset;
     295                 :            : 
     296                 :            :   /* Size of the variable, in bits.  */
     297                 :            :   unsigned HOST_WIDE_INT size;
     298                 :            : 
     299                 :            :   /* Full size of the base variable, in bits.  */
     300                 :            :   unsigned HOST_WIDE_INT fullsize;
     301                 :            : 
     302                 :            :   /* In IPA mode the shadow UID in case the variable needs to be duplicated in
     303                 :            :      the final points-to solution because it reaches its containing
     304                 :            :      function recursively.  Zero if none is needed.  */
     305                 :            :   unsigned int shadow_var_uid;
     306                 :            : 
     307                 :            :   /* Name of this variable */
     308                 :            :   const char *name;
     309                 :            : 
     310                 :            :   /* Tree that this variable is associated with.  */
     311                 :            :   tree decl;
     312                 :            : 
     313                 :            :   /* Points-to set for this variable.  */
     314                 :            :   bitmap solution;
     315                 :            : 
     316                 :            :   /* Old points-to set for this variable.  */
     317                 :            :   bitmap oldsolution;
     318                 :            : };
     319                 :            : typedef struct variable_info *varinfo_t;
     320                 :            : 
     321                 :            : static varinfo_t first_vi_for_offset (varinfo_t, unsigned HOST_WIDE_INT);
     322                 :            : static varinfo_t first_or_preceding_vi_for_offset (varinfo_t,
     323                 :            :                                                    unsigned HOST_WIDE_INT);
     324                 :            : static varinfo_t lookup_vi_for_tree (tree);
     325                 :            : static inline bool type_can_have_subvars (const_tree);
     326                 :            : static void make_param_constraints (varinfo_t);
     327                 :            : 
     328                 :            : /* Pool of variable info structures.  */
     329                 :            : static object_allocator<variable_info> variable_info_pool
     330                 :            :   ("Variable info pool");
     331                 :            : 
     332                 :            : /* Map varinfo to final pt_solution.  */
     333                 :            : static hash_map<varinfo_t, pt_solution *> *final_solutions;
     334                 :            : struct obstack final_solutions_obstack;
     335                 :            : 
     336                 :            : /* Table of variable info structures for constraint variables.
     337                 :            :    Indexed directly by variable info id.  */
     338                 :            : static vec<varinfo_t> varmap;
     339                 :            : 
     340                 :            : /* Return the varmap element N */
     341                 :            : 
     342                 :            : static inline varinfo_t
     343                 : 1420460000 : get_varinfo (unsigned int n)
     344                 :            : {
     345                 :   38110000 :   return varmap[n];
     346                 :            : }
     347                 :            : 
     348                 :            : /* Return the next variable in the list of sub-variables of VI
     349                 :            :    or NULL if VI is the last sub-variable.  */
     350                 :            : 
     351                 :            : static inline varinfo_t
     352                 :  180396000 : vi_next (varinfo_t vi)
     353                 :            : {
     354                 :  360792000 :   return get_varinfo (vi->next);
     355                 :            : }
     356                 :            : 
     357                 :            : /* Static IDs for the special variables.  Variable ID zero is unused
     358                 :            :    and used as terminator for the sub-variable chain.  */
     359                 :            : enum { nothing_id = 1, anything_id = 2, string_id = 3,
     360                 :            :        escaped_id = 4, nonlocal_id = 5,
     361                 :            :        storedanything_id = 6, integer_id = 7 };
     362                 :            : 
     363                 :            : /* Return a new variable info structure consisting for a variable
     364                 :            :    named NAME, and using constraint graph node NODE.  Append it
     365                 :            :    to the vector of variable info structures.  */
     366                 :            : 
     367                 :            : static varinfo_t
     368                 :   98719400 : new_var_info (tree t, const char *name, bool add_id)
     369                 :            : {
     370                 :   98719400 :   unsigned index = varmap.length ();
     371                 :   98719400 :   varinfo_t ret = variable_info_pool.allocate ();
     372                 :            : 
     373                 :   98719400 :   if (dump_file && add_id)
     374                 :            :     {
     375                 :        488 :       char *tempname = xasprintf ("%s(%d)", name, index);
     376                 :        488 :       name = ggc_strdup (tempname);
     377                 :        488 :       free (tempname);
     378                 :            :     }
     379                 :            : 
     380                 :   98719400 :   ret->id = index;
     381                 :   98719400 :   ret->name = name;
     382                 :   98719400 :   ret->decl = t;
     383                 :            :   /* Vars without decl are artificial and do not have sub-variables.  */
     384                 :   98719400 :   ret->is_artificial_var = (t == NULL_TREE);
     385                 :   98719400 :   ret->is_special_var = false;
     386                 :   98719400 :   ret->is_unknown_size_var = false;
     387                 :   98719400 :   ret->is_full_var = (t == NULL_TREE);
     388                 :   98719400 :   ret->is_heap_var = false;
     389                 :   98719400 :   ret->may_have_pointers = true;
     390                 :   98719400 :   ret->only_restrict_pointers = false;
     391                 :   98719400 :   ret->is_restrict_var = false;
     392                 :   98719400 :   ret->ruid = 0;
     393                 :   98719400 :   ret->is_global_var = (t == NULL_TREE);
     394                 :   98719400 :   ret->is_ipa_escape_point = false;
     395                 :   98719400 :   ret->is_fn_info = false;
     396                 :   98719400 :   if (t && DECL_P (t))
     397                 :   64998600 :     ret->is_global_var = (is_global_var (t)
     398                 :            :                           /* We have to treat even local register variables
     399                 :            :                              as escape points.  */
     400                 :   32499300 :                           || (VAR_P (t) && DECL_HARD_REGISTER (t)));
     401                 :   98719400 :   ret->is_reg_var = (t && TREE_CODE (t) == SSA_NAME);
     402                 :   98719400 :   ret->solution = BITMAP_ALLOC (&pta_obstack);
     403                 :   98719400 :   ret->oldsolution = NULL;
     404                 :   98719400 :   ret->next = 0;
     405                 :   98719400 :   ret->shadow_var_uid = 0;
     406                 :   98719400 :   ret->head = ret->id;
     407                 :            : 
     408                 :   98719400 :   stats.total_vars++;
     409                 :            : 
     410                 :   98719400 :   varmap.safe_push (ret);
     411                 :            : 
     412                 :   98719400 :   return ret;
     413                 :            : }
     414                 :            : 
     415                 :            : /* A map mapping call statements to per-stmt variables for uses
     416                 :            :    and clobbers specific to the call.  */
     417                 :            : static hash_map<gimple *, varinfo_t> *call_stmt_vars;
     418                 :            : 
     419                 :            : /* Lookup or create the variable for the call statement CALL.  */
     420                 :            : 
     421                 :            : static varinfo_t
     422                 :    2239580 : get_call_vi (gcall *call)
     423                 :            : {
     424                 :    2239580 :   varinfo_t vi, vi2;
     425                 :            : 
     426                 :    2239580 :   bool existed;
     427                 :    2239580 :   varinfo_t *slot_p = &call_stmt_vars->get_or_insert (call, &existed);
     428                 :    2239580 :   if (existed)
     429                 :    1242470 :     return *slot_p;
     430                 :            : 
     431                 :     997111 :   vi = new_var_info (NULL_TREE, "CALLUSED", true);
     432                 :     997111 :   vi->offset = 0;
     433                 :     997111 :   vi->size = 1;
     434                 :     997111 :   vi->fullsize = 2;
     435                 :     997111 :   vi->is_full_var = true;
     436                 :     997111 :   vi->is_reg_var = true;
     437                 :            : 
     438                 :     997111 :   vi2 = new_var_info (NULL_TREE, "CALLCLOBBERED", true);
     439                 :     997111 :   vi2->offset = 1;
     440                 :     997111 :   vi2->size = 1;
     441                 :     997111 :   vi2->fullsize = 2;
     442                 :     997111 :   vi2->is_full_var = true;
     443                 :     997111 :   vi2->is_reg_var = true;
     444                 :            : 
     445                 :     997111 :   vi->next = vi2->id;
     446                 :            : 
     447                 :     997111 :   *slot_p = vi;
     448                 :     997111 :   return vi;
     449                 :            : }
     450                 :            : 
     451                 :            : /* Lookup the variable for the call statement CALL representing
     452                 :            :    the uses.  Returns NULL if there is nothing special about this call.  */
     453                 :            : 
     454                 :            : static varinfo_t
     455                 :   20675300 : lookup_call_use_vi (gcall *call)
     456                 :            : {
     457                 :   20675300 :   varinfo_t *slot_p = call_stmt_vars->get (call);
     458                 :   19068600 :   if (slot_p)
     459                 :    1606690 :     return *slot_p;
     460                 :            : 
     461                 :            :   return NULL;
     462                 :            : }
     463                 :            : 
     464                 :            : /* Lookup the variable for the call statement CALL representing
     465                 :            :    the clobbers.  Returns NULL if there is nothing special about this call.  */
     466                 :            : 
     467                 :            : static varinfo_t
     468                 :   10104500 : lookup_call_clobber_vi (gcall *call)
     469                 :            : {
     470                 :   10104500 :   varinfo_t uses = lookup_call_use_vi (call);
     471                 :   10104500 :   if (!uses)
     472                 :            :     return NULL;
     473                 :            : 
     474                 :     603216 :   return vi_next (uses);
     475                 :            : }
     476                 :            : 
     477                 :            : /* Lookup or create the variable for the call statement CALL representing
     478                 :            :    the uses.  */
     479                 :            : 
     480                 :            : static varinfo_t
     481                 :    1834320 : get_call_use_vi (gcall *call)
     482                 :            : {
     483                 :          0 :   return get_call_vi (call);
     484                 :            : }
     485                 :            : 
     486                 :            : /* Lookup or create the variable for the call statement CALL representing
     487                 :            :    the clobbers.  */
     488                 :            : 
     489                 :            : static varinfo_t ATTRIBUTE_UNUSED
     490                 :     405267 : get_call_clobber_vi (gcall *call)
     491                 :            : {
     492                 :     405267 :   return vi_next (get_call_vi (call));
     493                 :            : }
     494                 :            : 
     495                 :            : 
     496                 :            : enum constraint_expr_type {SCALAR, DEREF, ADDRESSOF};
     497                 :            : 
     498                 :            : /* An expression that appears in a constraint.  */
     499                 :            : 
     500                 :            : struct constraint_expr
     501                 :            : {
     502                 :            :   /* Constraint type.  */
     503                 :            :   constraint_expr_type type;
     504                 :            : 
     505                 :            :   /* Variable we are referring to in the constraint.  */
     506                 :            :   unsigned int var;
     507                 :            : 
     508                 :            :   /* Offset, in bits, of this constraint from the beginning of
     509                 :            :      variables it ends up referring to.
     510                 :            : 
     511                 :            :      IOW, in a deref constraint, we would deref, get the result set,
     512                 :            :      then add OFFSET to each member.   */
     513                 :            :   HOST_WIDE_INT offset;
     514                 :            : };
     515                 :            : 
     516                 :            : /* Use 0x8000... as special unknown offset.  */
     517                 :            : #define UNKNOWN_OFFSET HOST_WIDE_INT_MIN
     518                 :            : 
     519                 :            : typedef struct constraint_expr ce_s;
     520                 :            : static void get_constraint_for_1 (tree, vec<ce_s> *, bool, bool);
     521                 :            : static void get_constraint_for (tree, vec<ce_s> *);
     522                 :            : static void get_constraint_for_rhs (tree, vec<ce_s> *);
     523                 :            : static void do_deref (vec<ce_s> *);
     524                 :            : 
     525                 :            : /* Our set constraints are made up of two constraint expressions, one
     526                 :            :    LHS, and one RHS.
     527                 :            : 
     528                 :            :    As described in the introduction, our set constraints each represent an
     529                 :            :    operation between set valued variables.
     530                 :            : */
     531                 :            : struct constraint
     532                 :            : {
     533                 :            :   struct constraint_expr lhs;
     534                 :            :   struct constraint_expr rhs;
     535                 :            : };
     536                 :            : 
     537                 :            : /* List of constraints that we use to build the constraint graph from.  */
     538                 :            : 
     539                 :            : static vec<constraint_t> constraints;
     540                 :            : static object_allocator<constraint> constraint_pool ("Constraint pool");
     541                 :            : 
     542                 :            : /* The constraint graph is represented as an array of bitmaps
     543                 :            :    containing successor nodes.  */
     544                 :            : 
     545                 :            : struct constraint_graph
     546                 :            : {
     547                 :            :   /* Size of this graph, which may be different than the number of
     548                 :            :      nodes in the variable map.  */
     549                 :            :   unsigned int size;
     550                 :            : 
     551                 :            :   /* Explicit successors of each node. */
     552                 :            :   bitmap *succs;
     553                 :            : 
     554                 :            :   /* Implicit predecessors of each node (Used for variable
     555                 :            :      substitution). */
     556                 :            :   bitmap *implicit_preds;
     557                 :            : 
     558                 :            :   /* Explicit predecessors of each node (Used for variable substitution).  */
     559                 :            :   bitmap *preds;
     560                 :            : 
     561                 :            :   /* Indirect cycle representatives, or -1 if the node has no indirect
     562                 :            :      cycles.  */
     563                 :            :   int *indirect_cycles;
     564                 :            : 
     565                 :            :   /* Representative node for a node.  rep[a] == a unless the node has
     566                 :            :      been unified. */
     567                 :            :   unsigned int *rep;
     568                 :            : 
     569                 :            :   /* Equivalence class representative for a label.  This is used for
     570                 :            :      variable substitution.  */
     571                 :            :   int *eq_rep;
     572                 :            : 
     573                 :            :   /* Pointer equivalence label for a node.  All nodes with the same
     574                 :            :      pointer equivalence label can be unified together at some point
     575                 :            :      (either during constraint optimization or after the constraint
     576                 :            :      graph is built).  */
     577                 :            :   unsigned int *pe;
     578                 :            : 
     579                 :            :   /* Pointer equivalence representative for a label.  This is used to
     580                 :            :      handle nodes that are pointer equivalent but not location
     581                 :            :      equivalent.  We can unite these once the addressof constraints
     582                 :            :      are transformed into initial points-to sets.  */
     583                 :            :   int *pe_rep;
     584                 :            : 
     585                 :            :   /* Pointer equivalence label for each node, used during variable
     586                 :            :      substitution.  */
     587                 :            :   unsigned int *pointer_label;
     588                 :            : 
     589                 :            :   /* Location equivalence label for each node, used during location
     590                 :            :      equivalence finding.  */
     591                 :            :   unsigned int *loc_label;
     592                 :            : 
     593                 :            :   /* Pointed-by set for each node, used during location equivalence
     594                 :            :      finding.  This is pointed-by rather than pointed-to, because it
     595                 :            :      is constructed using the predecessor graph.  */
     596                 :            :   bitmap *pointed_by;
     597                 :            : 
     598                 :            :   /* Points to sets for pointer equivalence.  This is *not* the actual
     599                 :            :      points-to sets for nodes.  */
     600                 :            :   bitmap *points_to;
     601                 :            : 
     602                 :            :   /* Bitmap of nodes where the bit is set if the node is a direct
     603                 :            :      node.  Used for variable substitution.  */
     604                 :            :   sbitmap direct_nodes;
     605                 :            : 
     606                 :            :   /* Bitmap of nodes where the bit is set if the node is address
     607                 :            :      taken.  Used for variable substitution.  */
     608                 :            :   bitmap address_taken;
     609                 :            : 
     610                 :            :   /* Vector of complex constraints for each graph node.  Complex
     611                 :            :      constraints are those involving dereferences or offsets that are
     612                 :            :      not 0.  */
     613                 :            :   vec<constraint_t> *complex;
     614                 :            : };
     615                 :            : 
     616                 :            : static constraint_graph_t graph;
     617                 :            : 
     618                 :            : /* During variable substitution and the offline version of indirect
     619                 :            :    cycle finding, we create nodes to represent dereferences and
     620                 :            :    address taken constraints.  These represent where these start and
     621                 :            :    end.  */
     622                 :            : #define FIRST_REF_NODE (varmap).length ()
     623                 :            : #define LAST_REF_NODE (FIRST_REF_NODE + (FIRST_REF_NODE - 1))
     624                 :            : 
     625                 :            : /* Return the representative node for NODE, if NODE has been unioned
     626                 :            :    with another NODE.
     627                 :            :    This function performs path compression along the way to finding
     628                 :            :    the representative.  */
     629                 :            : 
     630                 :            : static unsigned int
     631                 : 2229570000 : find (unsigned int node)
     632                 :            : {
     633                 : 2229570000 :   gcc_checking_assert (node < graph->size);
     634                 : 2229570000 :   if (graph->rep[node] != node)
     635                 :  260524000 :     return graph->rep[node] = find (graph->rep[node]);
     636                 :            :   return node;
     637                 :            : }
     638                 :            : 
     639                 :            : /* Union the TO and FROM nodes to the TO nodes.
     640                 :            :    Note that at some point in the future, we may want to do
     641                 :            :    union-by-rank, in which case we are going to have to return the
     642                 :            :    node we unified to.  */
     643                 :            : 
     644                 :            : static bool
     645                 :  131980000 : unite (unsigned int to, unsigned int from)
     646                 :            : {
     647                 :  131980000 :   gcc_checking_assert (to < graph->size && from < graph->size);
     648                 :  131980000 :   if (to != from && graph->rep[from] != to)
     649                 :            :     {
     650                 :   31838900 :       graph->rep[from] = to;
     651                 :   31838900 :       return true;
     652                 :            :     }
     653                 :            :   return false;
     654                 :            : }
     655                 :            : 
     656                 :            : /* Create a new constraint consisting of LHS and RHS expressions.  */
     657                 :            : 
     658                 :            : static constraint_t
     659                 :  136284000 : new_constraint (const struct constraint_expr lhs,
     660                 :            :                 const struct constraint_expr rhs)
     661                 :            : {
     662                 :          0 :   constraint_t ret = constraint_pool.allocate ();
     663                 :  136284000 :   ret->lhs = lhs;
     664                 :  136284000 :   ret->rhs = rhs;
     665                 :  136284000 :   return ret;
     666                 :            : }
     667                 :            : 
     668                 :            : /* Print out constraint C to FILE.  */
     669                 :            : 
     670                 :            : static void
     671                 :      10158 : dump_constraint (FILE *file, constraint_t c)
     672                 :            : {
     673                 :      10158 :   if (c->lhs.type == ADDRESSOF)
     674                 :          0 :     fprintf (file, "&");
     675                 :      10158 :   else if (c->lhs.type == DEREF)
     676                 :        824 :     fprintf (file, "*");
     677                 :      10158 :   fprintf (file, "%s", get_varinfo (c->lhs.var)->name);
     678                 :      10158 :   if (c->lhs.offset == UNKNOWN_OFFSET)
     679                 :         11 :     fprintf (file, " + UNKNOWN");
     680                 :      10147 :   else if (c->lhs.offset != 0)
     681                 :          6 :     fprintf (file, " + " HOST_WIDE_INT_PRINT_DEC, c->lhs.offset);
     682                 :      10158 :   fprintf (file, " = ");
     683                 :      10158 :   if (c->rhs.type == ADDRESSOF)
     684                 :       4973 :     fprintf (file, "&");
     685                 :       5185 :   else if (c->rhs.type == DEREF)
     686                 :       1069 :     fprintf (file, "*");
     687                 :      10158 :   fprintf (file, "%s", get_varinfo (c->rhs.var)->name);
     688                 :      10158 :   if (c->rhs.offset == UNKNOWN_OFFSET)
     689                 :       1635 :     fprintf (file, " + UNKNOWN");
     690                 :       8523 :   else if (c->rhs.offset != 0)
     691                 :        210 :     fprintf (file, " + " HOST_WIDE_INT_PRINT_DEC, c->rhs.offset);
     692                 :      10158 : }
     693                 :            : 
     694                 :            : 
     695                 :            : void debug_constraint (constraint_t);
     696                 :            : void debug_constraints (void);
     697                 :            : void debug_constraint_graph (void);
     698                 :            : void debug_solution_for_var (unsigned int);
     699                 :            : void debug_sa_points_to_info (void);
     700                 :            : void debug_varinfo (varinfo_t);
     701                 :            : void debug_varmap (void);
     702                 :            : 
     703                 :            : /* Print out constraint C to stderr.  */
     704                 :            : 
     705                 :            : DEBUG_FUNCTION void
     706                 :          0 : debug_constraint (constraint_t c)
     707                 :            : {
     708                 :          0 :   dump_constraint (stderr, c);
     709                 :          0 :   fprintf (stderr, "\n");
     710                 :          0 : }
     711                 :            : 
     712                 :            : /* Print out all constraints to FILE */
     713                 :            : 
     714                 :            : static void
     715                 :        591 : dump_constraints (FILE *file, int from)
     716                 :            : {
     717                 :        591 :   int i;
     718                 :        591 :   constraint_t c;
     719                 :      10715 :   for (i = from; constraints.iterate (i, &c); i++)
     720                 :      10124 :     if (c)
     721                 :            :       {
     722                 :      10124 :         dump_constraint (file, c);
     723                 :      10124 :         fprintf (file, "\n");
     724                 :            :       }
     725                 :        591 : }
     726                 :            : 
     727                 :            : /* Print out all constraints to stderr.  */
     728                 :            : 
     729                 :            : DEBUG_FUNCTION void
     730                 :          0 : debug_constraints (void)
     731                 :            : {
     732                 :          0 :   dump_constraints (stderr, 0);
     733                 :          0 : }
     734                 :            : 
     735                 :            : /* Print the constraint graph in dot format.  */
     736                 :            : 
     737                 :            : static void
     738                 :          6 : dump_constraint_graph (FILE *file)
     739                 :            : {
     740                 :          6 :   unsigned int i;
     741                 :            : 
     742                 :            :   /* Only print the graph if it has already been initialized:  */
     743                 :          6 :   if (!graph)
     744                 :            :     return;
     745                 :            : 
     746                 :            :   /* Prints the header of the dot file:  */
     747                 :          6 :   fprintf (file, "strict digraph {\n");
     748                 :          6 :   fprintf (file, "  node [\n    shape = box\n  ]\n");
     749                 :          6 :   fprintf (file, "  edge [\n    fontsize = \"12\"\n  ]\n");
     750                 :          6 :   fprintf (file, "\n  // List of nodes and complex constraints in "
     751                 :            :            "the constraint graph:\n");
     752                 :            : 
     753                 :            :   /* The next lines print the nodes in the graph together with the
     754                 :            :      complex constraints attached to them.  */
     755                 :         76 :   for (i = 1; i < graph->size; i++)
     756                 :            :     {
     757                 :        140 :       if (i == FIRST_REF_NODE)
     758                 :          0 :         continue;
     759                 :         70 :       if (find (i) != i)
     760                 :          2 :         continue;
     761                 :        136 :       if (i < FIRST_REF_NODE)
     762                 :         68 :         fprintf (file, "\"%s\"", get_varinfo (i)->name);
     763                 :            :       else
     764                 :          0 :         fprintf (file, "\"*%s\"", get_varinfo (i - FIRST_REF_NODE)->name);
     765                 :         68 :       if (graph->complex[i].exists ())
     766                 :            :         {
     767                 :         10 :           unsigned j;
     768                 :         10 :           constraint_t c;
     769                 :         10 :           fprintf (file, " [label=\"\\N\\n");
     770                 :         36 :           for (j = 0; graph->complex[i].iterate (j, &c); ++j)
     771                 :            :             {
     772                 :         26 :               dump_constraint (file, c);
     773                 :         26 :               fprintf (file, "\\l");
     774                 :            :             }
     775                 :         10 :           fprintf (file, "\"]");
     776                 :            :         }
     777                 :         68 :       fprintf (file, ";\n");
     778                 :            :     }
     779                 :            : 
     780                 :            :   /* Go over the edges.  */
     781                 :          6 :   fprintf (file, "\n  // Edges in the constraint graph:\n");
     782                 :         76 :   for (i = 1; i < graph->size; i++)
     783                 :            :     {
     784                 :         70 :       unsigned j;
     785                 :         70 :       bitmap_iterator bi;
     786                 :         70 :       if (find (i) != i)
     787                 :          2 :         continue;
     788                 :         80 :       EXECUTE_IF_IN_NONNULL_BITMAP (graph->succs[i], 0, j, bi)
     789                 :            :         {
     790                 :         12 :           unsigned to = find (j);
     791                 :         12 :           if (i == to)
     792                 :          0 :             continue;
     793                 :         24 :           if (i < FIRST_REF_NODE)
     794                 :         12 :             fprintf (file, "\"%s\"", get_varinfo (i)->name);
     795                 :            :           else
     796                 :          0 :             fprintf (file, "\"*%s\"", get_varinfo (i - FIRST_REF_NODE)->name);
     797                 :         12 :           fprintf (file, " -> ");
     798                 :         24 :           if (to < FIRST_REF_NODE)
     799                 :         12 :             fprintf (file, "\"%s\"", get_varinfo (to)->name);
     800                 :            :           else
     801                 :          0 :             fprintf (file, "\"*%s\"", get_varinfo (to - FIRST_REF_NODE)->name);
     802                 :         12 :           fprintf (file, ";\n");
     803                 :            :         }
     804                 :            :     }
     805                 :            : 
     806                 :            :   /* Prints the tail of the dot file.  */
     807                 :          6 :   fprintf (file, "}\n");
     808                 :            : }
     809                 :            : 
     810                 :            : /* Print out the constraint graph to stderr.  */
     811                 :            : 
     812                 :            : DEBUG_FUNCTION void
     813                 :          0 : debug_constraint_graph (void)
     814                 :            : {
     815                 :          0 :   dump_constraint_graph (stderr);
     816                 :          0 : }
     817                 :            : 
     818                 :            : /* SOLVER FUNCTIONS
     819                 :            : 
     820                 :            :    The solver is a simple worklist solver, that works on the following
     821                 :            :    algorithm:
     822                 :            : 
     823                 :            :    sbitmap changed_nodes = all zeroes;
     824                 :            :    changed_count = 0;
     825                 :            :    For each node that is not already collapsed:
     826                 :            :        changed_count++;
     827                 :            :        set bit in changed nodes
     828                 :            : 
     829                 :            :    while (changed_count > 0)
     830                 :            :    {
     831                 :            :      compute topological ordering for constraint graph
     832                 :            : 
     833                 :            :      find and collapse cycles in the constraint graph (updating
     834                 :            :      changed if necessary)
     835                 :            : 
     836                 :            :      for each node (n) in the graph in topological order:
     837                 :            :        changed_count--;
     838                 :            : 
     839                 :            :        Process each complex constraint associated with the node,
     840                 :            :        updating changed if necessary.
     841                 :            : 
     842                 :            :        For each outgoing edge from n, propagate the solution from n to
     843                 :            :        the destination of the edge, updating changed as necessary.
     844                 :            : 
     845                 :            :    }  */
     846                 :            : 
     847                 :            : /* Return true if two constraint expressions A and B are equal.  */
     848                 :            : 
     849                 :            : static bool
     850                 :   11963900 : constraint_expr_equal (struct constraint_expr a, struct constraint_expr b)
     851                 :            : {
     852                 :    6325460 :   return a.type == b.type && a.var == b.var && a.offset == b.offset;
     853                 :            : }
     854                 :            : 
     855                 :            : /* Return true if constraint expression A is less than constraint expression
     856                 :            :    B.  This is just arbitrary, but consistent, in order to give them an
     857                 :            :    ordering.  */
     858                 :            : 
     859                 :            : static bool
     860                 :   66965100 : constraint_expr_less (struct constraint_expr a, struct constraint_expr b)
     861                 :            : {
     862                 :          0 :   if (a.type == b.type)
     863                 :            :     {
     864                 :   51512300 :       if (a.var == b.var)
     865                 :   25015300 :         return a.offset < b.offset;
     866                 :            :       else
     867                 :   26497000 :         return a.var < b.var;
     868                 :            :     }
     869                 :            :   else
     870                 :   15452800 :     return a.type < b.type;
     871                 :            : }
     872                 :            : 
     873                 :            : /* Return true if constraint A is less than constraint B.  This is just
     874                 :            :    arbitrary, but consistent, in order to give them an ordering.  */
     875                 :            : 
     876                 :            : static bool
     877                 :   42674500 : constraint_less (const constraint_t &a, const constraint_t &b)
     878                 :            : {
     879                 :   85349000 :   if (constraint_expr_less (a->lhs, b->lhs))
     880                 :            :     return true;
     881                 :   31536800 :   else if (constraint_expr_less (b->lhs, a->lhs))
     882                 :            :     return false;
     883                 :            :   else
     884                 :    8522210 :     return constraint_expr_less (a->rhs, b->rhs);
     885                 :            : }
     886                 :            : 
     887                 :            : /* Return true if two constraints A and B are equal.  */
     888                 :            : 
     889                 :            : static bool
     890                 :    7704900 : constraint_equal (struct constraint a, struct constraint b)
     891                 :            : {
     892                 :   11963900 :   return constraint_expr_equal (a.lhs, b.lhs)
     893                 :    7704900 :     && constraint_expr_equal (a.rhs, b.rhs);
     894                 :            : }
     895                 :            : 
     896                 :            : 
     897                 :            : /* Find a constraint LOOKFOR in the sorted constraint vector VEC */
     898                 :            : 
     899                 :            : static constraint_t
     900                 :     211334 : constraint_vec_find (vec<constraint_t> vec,
     901                 :            :                      struct constraint lookfor)
     902                 :            : {
     903                 :     211334 :   unsigned int place;
     904                 :     211334 :   constraint_t found;
     905                 :            : 
     906                 :     211334 :   if (!vec.exists ())
     907                 :            :     return NULL;
     908                 :            : 
     909                 :     166069 :   place = vec.lower_bound (&lookfor, constraint_less);
     910                 :     166069 :   if (place >= vec.length ())
     911                 :            :     return NULL;
     912                 :      53271 :   found = vec[place];
     913                 :      53271 :   if (!constraint_equal (*found, lookfor))
     914                 :      53124 :     return NULL;
     915                 :            :   return found;
     916                 :            : }
     917                 :            : 
     918                 :            : /* Union two constraint vectors, TO and FROM.  Put the result in TO. 
     919                 :            :    Returns true of TO set is changed.  */
     920                 :            : 
     921                 :            : static bool
     922                 :   31767200 : constraint_set_union (vec<constraint_t> *to,
     923                 :            :                       vec<constraint_t> *from)
     924                 :            : {
     925                 :   31767200 :   int i;
     926                 :   31767200 :   constraint_t c;
     927                 :   31767200 :   bool any_change = false;
     928                 :            : 
     929                 :   32049200 :   FOR_EACH_VEC_ELT (*from, i, c)
     930                 :            :     {
     931                 :     211334 :       if (constraint_vec_find (*to, *c) == NULL)
     932                 :            :         {
     933                 :     211187 :           unsigned int place = to->lower_bound (c, constraint_less);
     934                 :     211187 :           to->safe_insert (place, c);
     935                 :     211187 :           any_change = true;
     936                 :            :         }
     937                 :            :     }
     938                 :   31767200 :   return any_change;
     939                 :            : }
     940                 :            : 
     941                 :            : /* Expands the solution in SET to all sub-fields of variables included.  */
     942                 :            : 
     943                 :            : static bitmap
     944                 :   23602700 : solution_set_expand (bitmap set, bitmap *expanded)
     945                 :            : {
     946                 :   23602700 :   bitmap_iterator bi;
     947                 :   23602700 :   unsigned j;
     948                 :            : 
     949                 :   23602700 :   if (*expanded)
     950                 :            :     return *expanded;
     951                 :            : 
     952                 :   15101600 :   *expanded = BITMAP_ALLOC (&iteration_obstack);
     953                 :            : 
     954                 :            :   /* In a first pass expand to the head of the variables we need to
     955                 :            :      add all sub-fields off.  This avoids quadratic behavior.  */
     956                 :   52415200 :   EXECUTE_IF_SET_IN_BITMAP (set, 0, j, bi)
     957                 :            :     {
     958                 :   37313600 :       varinfo_t v = get_varinfo (j);
     959                 :   61293600 :       if (v->is_artificial_var
     960                 :   37313600 :           || v->is_full_var)
     961                 :   23980100 :         continue;
     962                 :   13333500 :       bitmap_set_bit (*expanded, v->head);
     963                 :            :     }
     964                 :            : 
     965                 :            :   /* In the second pass now expand all head variables with subfields.  */
     966                 :   20986900 :   EXECUTE_IF_SET_IN_BITMAP (*expanded, 0, j, bi)
     967                 :            :     {
     968                 :    5885290 :       varinfo_t v = get_varinfo (j);
     969                 :    5885290 :       if (v->head != j)
     970                 :    2370000 :         continue;
     971                 :   26083400 :       for (v = vi_next (v); v != NULL; v = vi_next (v))
     972                 :   22568100 :         bitmap_set_bit (*expanded, v->id);
     973                 :            :     }
     974                 :            : 
     975                 :            :   /* And finally set the rest of the bits from SET.  */
     976                 :   15101600 :   bitmap_ior_into (*expanded, set);
     977                 :            : 
     978                 :   15101600 :   return *expanded;
     979                 :            : }
     980                 :            : 
     981                 :            : /* Union solution sets TO and DELTA, and add INC to each member of DELTA in the
     982                 :            :    process.  */
     983                 :            : 
     984                 :            : static bool
     985                 :   20282800 : set_union_with_increment  (bitmap to, bitmap delta, HOST_WIDE_INT inc,
     986                 :            :                            bitmap *expanded_delta)
     987                 :            : {
     988                 :   20282800 :   bool changed = false;
     989                 :   20282800 :   bitmap_iterator bi;
     990                 :   20282800 :   unsigned int i;
     991                 :            : 
     992                 :            :   /* If the solution of DELTA contains anything it is good enough to transfer
     993                 :            :      this to TO.  */
     994                 :   20282800 :   if (bitmap_bit_p (delta, anything_id))
     995                 :      65199 :     return bitmap_set_bit (to, anything_id);
     996                 :            : 
     997                 :            :   /* If the offset is unknown we have to expand the solution to
     998                 :            :      all subfields.  */
     999                 :   20217600 :   if (inc == UNKNOWN_OFFSET)
    1000                 :            :     {
    1001                 :   19640600 :       delta = solution_set_expand (delta, expanded_delta);
    1002                 :   19640600 :       changed |= bitmap_ior_into (to, delta);
    1003                 :   19640600 :       return changed;
    1004                 :            :     }
    1005                 :            : 
    1006                 :            :   /* For non-zero offset union the offsetted solution into the destination.  */
    1007                 :    1958470 :   EXECUTE_IF_SET_IN_BITMAP (delta, 0, i, bi)
    1008                 :            :     {
    1009                 :    1381540 :       varinfo_t vi = get_varinfo (i);
    1010                 :            : 
    1011                 :            :       /* If this is a variable with just one field just set its bit
    1012                 :            :          in the result.  */
    1013                 :    1381540 :       if (vi->is_artificial_var
    1014                 :            :           || vi->is_unknown_size_var
    1015                 :    1381540 :           || vi->is_full_var)
    1016                 :     938006 :         changed |= bitmap_set_bit (to, i);
    1017                 :            :       else
    1018                 :            :         {
    1019                 :     443530 :           HOST_WIDE_INT fieldoffset = vi->offset + inc;
    1020                 :     443530 :           unsigned HOST_WIDE_INT size = vi->size;
    1021                 :            : 
    1022                 :            :           /* If the offset makes the pointer point to before the
    1023                 :            :              variable use offset zero for the field lookup.  */
    1024                 :     443530 :           if (fieldoffset < 0)
    1025                 :       2121 :             vi = get_varinfo (vi->head);
    1026                 :            :           else
    1027                 :     441409 :             vi = first_or_preceding_vi_for_offset (vi, fieldoffset);
    1028                 :            : 
    1029                 :     510154 :           do
    1030                 :            :             {
    1031                 :     510154 :               changed |= bitmap_set_bit (to, vi->id);
    1032                 :     510154 :               if (vi->is_full_var
    1033                 :     510154 :                   || vi->next == 0)
    1034                 :            :                 break;
    1035                 :            : 
    1036                 :            :               /* We have to include all fields that overlap the current field
    1037                 :            :                  shifted by inc.  */
    1038                 :     266827 :               vi = vi_next (vi);
    1039                 :            :             }
    1040                 :     266827 :           while (vi->offset < fieldoffset + size);
    1041                 :            :         }
    1042                 :            :     }
    1043                 :            : 
    1044                 :            :   return changed;
    1045                 :            : }
    1046                 :            : 
    1047                 :            : /* Insert constraint C into the list of complex constraints for graph
    1048                 :            :    node VAR.  */
    1049                 :            : 
    1050                 :            : static void
    1051                 :   34807100 : insert_into_complex (constraint_graph_t graph,
    1052                 :            :                      unsigned int var, constraint_t c)
    1053                 :            : {
    1054                 :   34807100 :   vec<constraint_t> complex = graph->complex[var];
    1055                 :   34807100 :   unsigned int place = complex.lower_bound (c, constraint_less);
    1056                 :            : 
    1057                 :            :   /* Only insert constraints that do not already exist.  */
    1058                 :   34807100 :   if (place >= complex.length ()
    1059                 :   34807100 :       || !constraint_equal (*c, *complex[place]))
    1060                 :   33592200 :     graph->complex[var].safe_insert (place, c);
    1061                 :   34807100 : }
    1062                 :            : 
    1063                 :            : 
    1064                 :            : /* Condense two variable nodes into a single variable node, by moving
    1065                 :            :    all associated info from FROM to TO. Returns true if TO node's 
    1066                 :            :    constraint set changes after the merge.  */
    1067                 :            : 
    1068                 :            : static bool
    1069                 :   31767200 : merge_node_constraints (constraint_graph_t graph, unsigned int to,
    1070                 :            :                         unsigned int from)
    1071                 :            : {
    1072                 :   31767200 :   unsigned int i;
    1073                 :   31767200 :   constraint_t c;
    1074                 :   31767200 :   bool any_change = false;
    1075                 :            : 
    1076                 :   31767200 :   gcc_checking_assert (find (from) == to);
    1077                 :            : 
    1078                 :            :   /* Move all complex constraints from src node into to node  */
    1079                 :   31978600 :   FOR_EACH_VEC_ELT (graph->complex[from], i, c)
    1080                 :            :     {
    1081                 :            :       /* In complex constraints for node FROM, we may have either
    1082                 :            :          a = *FROM, and *FROM = a, or an offseted constraint which are
    1083                 :            :          always added to the rhs node's constraints.  */
    1084                 :            : 
    1085                 :     211334 :       if (c->rhs.type == DEREF)
    1086                 :      70268 :         c->rhs.var = to;
    1087                 :     141066 :       else if (c->lhs.type == DEREF)
    1088                 :      69806 :         c->lhs.var = to;
    1089                 :            :       else
    1090                 :      71260 :         c->rhs.var = to;
    1091                 :            : 
    1092                 :            :     }
    1093                 :   31767200 :   any_change = constraint_set_union (&graph->complex[to],
    1094                 :            :                                      &graph->complex[from]);
    1095                 :   31767200 :   graph->complex[from].release ();
    1096                 :   31767200 :   return any_change;
    1097                 :            : }
    1098                 :            : 
    1099                 :            : 
    1100                 :            : /* Remove edges involving NODE from GRAPH.  */
    1101                 :            : 
    1102                 :            : static void
    1103                 :   44388300 : clear_edges_for_node (constraint_graph_t graph, unsigned int node)
    1104                 :            : {
    1105                 :          0 :   if (graph->succs[node])
    1106                 :    1461420 :     BITMAP_FREE (graph->succs[node]);
    1107                 :          0 : }
    1108                 :            : 
    1109                 :            : /* Merge GRAPH nodes FROM and TO into node TO.  */
    1110                 :            : 
    1111                 :            : static void
    1112                 :   31767200 : merge_graph_nodes (constraint_graph_t graph, unsigned int to,
    1113                 :            :                    unsigned int from)
    1114                 :            : {
    1115                 :   31767200 :   if (graph->indirect_cycles[from] != -1)
    1116                 :            :     {
    1117                 :            :       /* If we have indirect cycles with the from node, and we have
    1118                 :            :          none on the to node, the to node has indirect cycles from the
    1119                 :            :          from node now that they are unified.
    1120                 :            :          If indirect cycles exist on both, unify the nodes that they
    1121                 :            :          are in a cycle with, since we know they are in a cycle with
    1122                 :            :          each other.  */
    1123                 :         19 :       if (graph->indirect_cycles[to] == -1)
    1124                 :         13 :         graph->indirect_cycles[to] = graph->indirect_cycles[from];
    1125                 :            :     }
    1126                 :            : 
    1127                 :            :   /* Merge all the successor edges.  */
    1128                 :   31767200 :   if (graph->succs[from])
    1129                 :            :     {
    1130                 :    1461420 :       if (!graph->succs[to])
    1131                 :     754151 :         graph->succs[to] = BITMAP_ALLOC (&pta_obstack);
    1132                 :    1461420 :       bitmap_ior_into (graph->succs[to],
    1133                 :    1461420 :                        graph->succs[from]);
    1134                 :            :     }
    1135                 :            : 
    1136                 :   31767200 :   clear_edges_for_node (graph, from);
    1137                 :   31767200 : }
    1138                 :            : 
    1139                 :            : 
    1140                 :            : /* Add an indirect graph edge to GRAPH, going from TO to FROM if
    1141                 :            :    it doesn't exist in the graph already.  */
    1142                 :            : 
    1143                 :            : static void
    1144                 :   98902100 : add_implicit_graph_edge (constraint_graph_t graph, unsigned int to,
    1145                 :            :                          unsigned int from)
    1146                 :            : {
    1147                 :   98902100 :   if (to == from)
    1148                 :            :     return;
    1149                 :            : 
    1150                 :   98902100 :   if (!graph->implicit_preds[to])
    1151                 :   63845200 :     graph->implicit_preds[to] = BITMAP_ALLOC (&predbitmap_obstack);
    1152                 :            : 
    1153                 :   98902100 :   if (bitmap_set_bit (graph->implicit_preds[to], from))
    1154                 :   86631900 :     stats.num_implicit_edges++;
    1155                 :            : }
    1156                 :            : 
    1157                 :            : /* Add a predecessor graph edge to GRAPH, going from TO to FROM if
    1158                 :            :    it doesn't exist in the graph already.
    1159                 :            :    Return false if the edge already existed, true otherwise.  */
    1160                 :            : 
    1161                 :            : static void
    1162                 :   60435600 : add_pred_graph_edge (constraint_graph_t graph, unsigned int to,
    1163                 :            :                      unsigned int from)
    1164                 :            : {
    1165                 :   60435600 :   if (!graph->preds[to])
    1166                 :   44402100 :     graph->preds[to] = BITMAP_ALLOC (&predbitmap_obstack);
    1167                 :   60435600 :   bitmap_set_bit (graph->preds[to], from);
    1168                 :   60435600 : }
    1169                 :            : 
    1170                 :            : /* Add a graph edge to GRAPH, going from FROM to TO if
    1171                 :            :    it doesn't exist in the graph already.
    1172                 :            :    Return false if the edge already existed, true otherwise.  */
    1173                 :            : 
    1174                 :            : static bool
    1175                 :  130847000 : add_graph_edge (constraint_graph_t graph, unsigned int to,
    1176                 :            :                 unsigned int from)
    1177                 :            : {
    1178                 :  130847000 :   if (to == from)
    1179                 :            :     {
    1180                 :            :       return false;
    1181                 :            :     }
    1182                 :            :   else
    1183                 :            :     {
    1184                 :  130591000 :       bool r = false;
    1185                 :            : 
    1186                 :  130591000 :       if (!graph->succs[from])
    1187                 :   32267300 :         graph->succs[from] = BITMAP_ALLOC (&pta_obstack);
    1188                 :  130591000 :       if (bitmap_set_bit (graph->succs[from], to))
    1189                 :            :         {
    1190                 :   90468400 :           r = true;
    1191                 :  180937000 :           if (to < FIRST_REF_NODE && from < FIRST_REF_NODE)
    1192                 :   81370900 :             stats.num_edges++;
    1193                 :            :         }
    1194                 :  130591000 :       return r;
    1195                 :            :     }
    1196                 :            : }
    1197                 :            : 
    1198                 :            : 
    1199                 :            : /* Initialize the constraint graph structure to contain SIZE nodes.  */
    1200                 :            : 
    1201                 :            : static void
    1202                 :    2918700 : init_graph (unsigned int size)
    1203                 :            : {
    1204                 :    2918700 :   unsigned int j;
    1205                 :            : 
    1206                 :    2918700 :   graph = XCNEW (struct constraint_graph);
    1207                 :    2918700 :   graph->size = size;
    1208                 :    2918700 :   graph->succs = XCNEWVEC (bitmap, graph->size);
    1209                 :    2918700 :   graph->indirect_cycles = XNEWVEC (int, graph->size);
    1210                 :    2918700 :   graph->rep = XNEWVEC (unsigned int, graph->size);
    1211                 :            :   /* ??? Macros do not support template types with multiple arguments,
    1212                 :            :      so we use a typedef to work around it.  */
    1213                 :    2918700 :   typedef vec<constraint_t> vec_constraint_t_heap;
    1214                 :    2918700 :   graph->complex = XCNEWVEC (vec_constraint_t_heap, size);
    1215                 :    2918700 :   graph->pe = XCNEWVEC (unsigned int, graph->size);
    1216                 :    2918700 :   graph->pe_rep = XNEWVEC (int, graph->size);
    1217                 :            : 
    1218                 :  206195000 :   for (j = 0; j < graph->size; j++)
    1219                 :            :     {
    1220                 :  203276000 :       graph->rep[j] = j;
    1221                 :  203276000 :       graph->pe_rep[j] = -1;
    1222                 :  203276000 :       graph->indirect_cycles[j] = -1;
    1223                 :            :     }
    1224                 :    2918700 : }
    1225                 :            : 
    1226                 :            : /* Build the constraint graph, adding only predecessor edges right now.  */
    1227                 :            : 
    1228                 :            : static void
    1229                 :    2918700 : build_pred_graph (void)
    1230                 :            : {
    1231                 :    2918700 :   int i;
    1232                 :    2918700 :   constraint_t c;
    1233                 :    2918700 :   unsigned int j;
    1234                 :            : 
    1235                 :    2918700 :   graph->implicit_preds = XCNEWVEC (bitmap, graph->size);
    1236                 :    2918700 :   graph->preds = XCNEWVEC (bitmap, graph->size);
    1237                 :    2918700 :   graph->pointer_label = XCNEWVEC (unsigned int, graph->size);
    1238                 :    2918700 :   graph->loc_label = XCNEWVEC (unsigned int, graph->size);
    1239                 :    2918700 :   graph->pointed_by = XCNEWVEC (bitmap, graph->size);
    1240                 :    2918700 :   graph->points_to = XCNEWVEC (bitmap, graph->size);
    1241                 :    2918700 :   graph->eq_rep = XNEWVEC (int, graph->size);
    1242                 :    2918700 :   graph->direct_nodes = sbitmap_alloc (graph->size);
    1243                 :    2918700 :   graph->address_taken = BITMAP_ALLOC (&predbitmap_obstack);
    1244                 :    2918700 :   bitmap_clear (graph->direct_nodes);
    1245                 :            : 
    1246                 :  203276000 :   for (j = 1; j < FIRST_REF_NODE; j++)
    1247                 :            :     {
    1248                 :   98719400 :       if (!get_varinfo (j)->is_special_var)
    1249                 :  182845000 :         bitmap_set_bit (graph->direct_nodes, j);
    1250                 :            :     }
    1251                 :            : 
    1252                 :  206195000 :   for (j = 0; j < graph->size; j++)
    1253                 :  203276000 :     graph->eq_rep[j] = -1;
    1254                 :            : 
    1255                 :  209114000 :   for (j = 0; j < varmap.length (); j++)
    1256                 :  101638000 :     graph->indirect_cycles[j] = -1;
    1257                 :            : 
    1258                 :  137516000 :   FOR_EACH_VEC_ELT (constraints, i, c)
    1259                 :            :     {
    1260                 :  134597000 :       struct constraint_expr lhs = c->lhs;
    1261                 :  134597000 :       struct constraint_expr rhs = c->rhs;
    1262                 :  134597000 :       unsigned int lhsvar = lhs.var;
    1263                 :  134597000 :       unsigned int rhsvar = rhs.var;
    1264                 :            : 
    1265                 :  134597000 :       if (lhs.type == DEREF)
    1266                 :            :         {
    1267                 :            :           /* *x = y.  */
    1268                 :    7493950 :           if (rhs.offset == 0 && lhs.offset == 0 && rhs.type == SCALAR)
    1269                 :    9024640 :             add_pred_graph_edge (graph, FIRST_REF_NODE + lhsvar, rhsvar);
    1270                 :            :         }
    1271                 :  127103000 :       else if (rhs.type == DEREF)
    1272                 :            :         {
    1273                 :            :           /* x = *y */
    1274                 :   10584500 :           if (rhs.offset == 0 && lhs.offset == 0 && lhs.type == SCALAR)
    1275                 :   10511000 :             add_pred_graph_edge (graph, lhsvar, FIRST_REF_NODE + rhsvar);
    1276                 :            :           else
    1277                 :    5329030 :             bitmap_clear_bit (graph->direct_nodes, lhsvar);
    1278                 :            :         }
    1279                 :  116519000 :       else if (rhs.type == ADDRESSOF)
    1280                 :            :         {
    1281                 :   48234300 :           varinfo_t v;
    1282                 :            : 
    1283                 :            :           /* x = &y */
    1284                 :   48234300 :           if (graph->points_to[lhsvar] == NULL)
    1285                 :   31626500 :             graph->points_to[lhsvar] = BITMAP_ALLOC (&predbitmap_obstack);
    1286                 :   48234300 :           bitmap_set_bit (graph->points_to[lhsvar], rhsvar);
    1287                 :            : 
    1288                 :   48234300 :           if (graph->pointed_by[rhsvar] == NULL)
    1289                 :   14341400 :             graph->pointed_by[rhsvar] = BITMAP_ALLOC (&predbitmap_obstack);
    1290                 :   48234300 :           bitmap_set_bit (graph->pointed_by[rhsvar], lhsvar);
    1291                 :            : 
    1292                 :            :           /* Implicitly, *x = y */
    1293                 :   96468600 :           add_implicit_graph_edge (graph, FIRST_REF_NODE + lhsvar, rhsvar);
    1294                 :            : 
    1295                 :            :           /* All related variables are no longer direct nodes.  */
    1296                 :   48234300 :           bitmap_clear_bit (graph->direct_nodes, rhsvar);
    1297                 :   48234300 :           v = get_varinfo (rhsvar);
    1298                 :   48234300 :           if (!v->is_full_var)
    1299                 :            :             {
    1300                 :    3528580 :               v = get_varinfo (v->head);
    1301                 :   24332300 :               do
    1302                 :            :                 {
    1303                 :   24332300 :                   bitmap_clear_bit (graph->direct_nodes, v->id);
    1304                 :   24332300 :                   v = vi_next (v);
    1305                 :            :                 }
    1306                 :   24332300 :               while (v != NULL);
    1307                 :            :             }
    1308                 :   48234300 :           bitmap_set_bit (graph->address_taken, rhsvar);
    1309                 :            :         }
    1310                 :   68284200 :       else if (lhsvar > anything_id
    1311                 :   68284200 :                && lhsvar != rhsvar && lhs.offset == 0 && rhs.offset == 0)
    1312                 :            :         {
    1313                 :            :           /* x = y */
    1314                 :   50667800 :           add_pred_graph_edge (graph, lhsvar, rhsvar);
    1315                 :            :           /* Implicitly, *x = *y */
    1316                 :   50667800 :           add_implicit_graph_edge (graph, FIRST_REF_NODE + lhsvar,
    1317                 :   50667800 :                                    FIRST_REF_NODE + rhsvar);
    1318                 :            :         }
    1319                 :   17616500 :       else if (lhs.offset != 0 || rhs.offset != 0)
    1320                 :            :         {
    1321                 :   17464900 :           if (rhs.offset != 0)
    1322                 :   17464900 :             bitmap_clear_bit (graph->direct_nodes, lhs.var);
    1323                 :          0 :           else if (lhs.offset != 0)
    1324                 :  134597000 :             bitmap_clear_bit (graph->direct_nodes, rhs.var);
    1325                 :            :         }
    1326                 :            :     }
    1327                 :    2918700 : }
    1328                 :            : 
    1329                 :            : /* Build the constraint graph, adding successor edges.  */
    1330                 :            : 
    1331                 :            : static void
    1332                 :    2918700 : build_succ_graph (void)
    1333                 :            : {
    1334                 :    2918700 :   unsigned i, t;
    1335                 :    2918700 :   constraint_t c;
    1336                 :            : 
    1337                 :  137516000 :   FOR_EACH_VEC_ELT (constraints, i, c)
    1338                 :            :     {
    1339                 :  134597000 :       struct constraint_expr lhs;
    1340                 :  134597000 :       struct constraint_expr rhs;
    1341                 :  134597000 :       unsigned int lhsvar;
    1342                 :  134597000 :       unsigned int rhsvar;
    1343                 :            : 
    1344                 :  134597000 :       if (!c)
    1345                 :    1701240 :         continue;
    1346                 :            : 
    1347                 :  132896000 :       lhs = c->lhs;
    1348                 :  132896000 :       rhs = c->rhs;
    1349                 :  132896000 :       lhsvar = find (lhs.var);
    1350                 :  132896000 :       rhsvar = find (rhs.var);
    1351                 :            : 
    1352                 :  132896000 :       if (lhs.type == DEREF)
    1353                 :            :         {
    1354                 :    7481580 :           if (rhs.offset == 0 && lhs.offset == 0 && rhs.type == SCALAR)
    1355                 :    9017730 :             add_graph_edge (graph, FIRST_REF_NODE + lhsvar, rhsvar);
    1356                 :            :         }
    1357                 :  125414000 :       else if (rhs.type == DEREF)
    1358                 :            :         {
    1359                 :   10583700 :           if (rhs.offset == 0 && lhs.offset == 0 && lhs.type == SCALAR)
    1360                 :   10509700 :             add_graph_edge (graph, lhsvar, FIRST_REF_NODE + rhsvar);
    1361                 :            :         }
    1362                 :  114830000 :       else if (rhs.type == ADDRESSOF)
    1363                 :            :         {
    1364                 :            :           /* x = &y */
    1365                 :   48234300 :           gcc_checking_assert (find (rhs.var) == rhs.var);
    1366                 :   48234300 :           bitmap_set_bit (get_varinfo (lhsvar)->solution, rhsvar);
    1367                 :            :         }
    1368                 :   66596200 :       else if (lhsvar > anything_id
    1369                 :   66596200 :                && lhsvar != rhsvar && lhs.offset == 0 && rhs.offset == 0)
    1370                 :            :         {
    1371                 :   30735300 :           add_graph_edge (graph, lhsvar, rhsvar);
    1372                 :            :         }
    1373                 :            :     }
    1374                 :            : 
    1375                 :            :   /* Add edges from STOREDANYTHING to all non-direct nodes that can
    1376                 :            :      receive pointers.  */
    1377                 :    2918700 :   t = find (storedanything_id);
    1378                 :  162414000 :   for (i = integer_id + 1; i < FIRST_REF_NODE; ++i)
    1379                 :            :     {
    1380                 :   78288400 :       if (!bitmap_bit_p (graph->direct_nodes, i)
    1381                 :  106330000 :           && get_varinfo (i)->may_have_pointers)
    1382                 :   28041500 :         add_graph_edge (graph, find (i), t);
    1383                 :            :     }
    1384                 :            : 
    1385                 :            :   /* Everything stored to ANYTHING also potentially escapes.  */
    1386                 :    2918700 :   add_graph_edge (graph, find (escaped_id), t);
    1387                 :    2918700 : }
    1388                 :            : 
    1389                 :            : 
    1390                 :            : /* Changed variables on the last iteration.  */
    1391                 :            : static bitmap changed;
    1392                 :            : 
    1393                 :            : /* Strongly Connected Component visitation info.  */
    1394                 :            : 
    1395                 :            : class scc_info
    1396                 :            : {
    1397                 :            : public:
    1398                 :            :   scc_info (size_t size);
    1399                 :            :   ~scc_info ();
    1400                 :            : 
    1401                 :            :   auto_sbitmap visited;
    1402                 :            :   auto_sbitmap deleted;
    1403                 :            :   unsigned int *dfs;
    1404                 :            :   unsigned int *node_mapping;
    1405                 :            :   int current_index;
    1406                 :            :   auto_vec<unsigned> scc_stack;
    1407                 :            : };
    1408                 :            : 
    1409                 :            : 
    1410                 :            : /* Recursive routine to find strongly connected components in GRAPH.
    1411                 :            :    SI is the SCC info to store the information in, and N is the id of current
    1412                 :            :    graph node we are processing.
    1413                 :            : 
    1414                 :            :    This is Tarjan's strongly connected component finding algorithm, as
    1415                 :            :    modified by Nuutila to keep only non-root nodes on the stack.
    1416                 :            :    The algorithm can be found in "On finding the strongly connected
    1417                 :            :    connected components in a directed graph" by Esko Nuutila and Eljas
    1418                 :            :    Soisalon-Soininen, in Information Processing Letters volume 49,
    1419                 :            :    number 1, pages 9-14.  */
    1420                 :            : 
    1421                 :            : static void
    1422                 :  168677000 : scc_visit (constraint_graph_t graph, class scc_info *si, unsigned int n)
    1423                 :            : {
    1424                 :  168677000 :   unsigned int i;
    1425                 :  168677000 :   bitmap_iterator bi;
    1426                 :  168677000 :   unsigned int my_dfs;
    1427                 :            : 
    1428                 :  168677000 :   bitmap_set_bit (si->visited, n);
    1429                 :  168677000 :   si->dfs[n] = si->current_index ++;
    1430                 :  168677000 :   my_dfs = si->dfs[n];
    1431                 :            : 
    1432                 :            :   /* Visit all the successors.  */
    1433                 :  225788000 :   EXECUTE_IF_IN_NONNULL_BITMAP (graph->succs[n], 0, i, bi)
    1434                 :            :     {
    1435                 :   57110300 :       unsigned int w;
    1436                 :            : 
    1437                 :  114221000 :       if (i > LAST_REF_NODE)
    1438                 :            :         break;
    1439                 :            : 
    1440                 :   57110300 :       w = find (i);
    1441                 :   57110300 :       if (bitmap_bit_p (si->deleted, w))
    1442                 :   21677200 :         continue;
    1443                 :            : 
    1444                 :   35433200 :       if (!bitmap_bit_p (si->visited, w))
    1445                 :   35261500 :         scc_visit (graph, si, w);
    1446                 :            : 
    1447                 :   35433200 :       unsigned int t = find (w);
    1448                 :   35433200 :       gcc_checking_assert (find (n) == n);
    1449                 :   35433200 :       if (si->dfs[t] < si->dfs[n])
    1450                 :      88196 :         si->dfs[n] = si->dfs[t];
    1451                 :            :     }
    1452                 :            : 
    1453                 :            :   /* See if any components have been identified.  */
    1454                 :  168677000 :   if (si->dfs[n] == my_dfs)
    1455                 :            :     {
    1456                 :  168589000 :       if (si->scc_stack.length () > 0
    1457                 :  168589000 :           && si->dfs[si->scc_stack.last ()] >= my_dfs)
    1458                 :            :         {
    1459                 :      65382 :           bitmap scc = BITMAP_ALLOC (NULL);
    1460                 :      65382 :           unsigned int lowest_node;
    1461                 :      65382 :           bitmap_iterator bi;
    1462                 :            : 
    1463                 :      65382 :           bitmap_set_bit (scc, n);
    1464                 :            : 
    1465                 :     148527 :           while (si->scc_stack.length () != 0
    1466                 :     148527 :                  && si->dfs[si->scc_stack.last ()] >= my_dfs)
    1467                 :            :             {
    1468                 :      83145 :               unsigned int w = si->scc_stack.pop ();
    1469                 :            : 
    1470                 :      83145 :               bitmap_set_bit (scc, w);
    1471                 :            :             }
    1472                 :            : 
    1473                 :      65382 :           lowest_node = bitmap_first_set_bit (scc);
    1474                 :     130764 :           gcc_assert (lowest_node < FIRST_REF_NODE);
    1475                 :            : 
    1476                 :            :           /* Collapse the SCC nodes into a single node, and mark the
    1477                 :            :              indirect cycles.  */
    1478                 :     213909 :           EXECUTE_IF_SET_IN_BITMAP (scc, 0, i, bi)
    1479                 :            :             {
    1480                 :     297054 :               if (i < FIRST_REF_NODE)
    1481                 :            :                 {
    1482                 :      76836 :                   if (unite (lowest_node, i))
    1483                 :      11454 :                     unify_nodes (graph, lowest_node, i, false);
    1484                 :            :                 }
    1485                 :            :               else
    1486                 :            :                 {
    1487                 :      71691 :                   unite (lowest_node, i);
    1488                 :     143382 :                   graph->indirect_cycles[i - FIRST_REF_NODE] = lowest_node;
    1489                 :            :                 }
    1490                 :            :             }
    1491                 :            :         }
    1492                 :  168589000 :       bitmap_set_bit (si->deleted, n);
    1493                 :            :     }
    1494                 :            :   else
    1495                 :      88182 :     si->scc_stack.safe_push (n);
    1496                 :  168677000 : }
    1497                 :            : 
    1498                 :            : /* Unify node FROM into node TO, updating the changed count if
    1499                 :            :    necessary when UPDATE_CHANGED is true.  */
    1500                 :            : 
    1501                 :            : static void
    1502                 :   31767200 : unify_nodes (constraint_graph_t graph, unsigned int to, unsigned int from,
    1503                 :            :              bool update_changed)
    1504                 :            : {
    1505                 :   31767200 :   gcc_checking_assert (to != from && find (to) == to);
    1506                 :            : 
    1507                 :   31767200 :   if (dump_file && (dump_flags & TDF_DETAILS))
    1508                 :        256 :     fprintf (dump_file, "Unifying %s to %s\n",
    1509                 :        256 :              get_varinfo (from)->name,
    1510                 :        256 :              get_varinfo (to)->name);
    1511                 :            : 
    1512                 :   31767200 :   if (update_changed)
    1513                 :      54375 :     stats.unified_vars_dynamic++;
    1514                 :            :   else
    1515                 :   31712900 :     stats.unified_vars_static++;
    1516                 :            : 
    1517                 :   31767200 :   merge_graph_nodes (graph, to, from);
    1518                 :   31767200 :   if (merge_node_constraints (graph, to, from))
    1519                 :            :     {
    1520                 :      70654 :       if (update_changed)
    1521                 :       7299 :         bitmap_set_bit (changed, to);
    1522                 :            :     }
    1523                 :            : 
    1524                 :            :   /* Mark TO as changed if FROM was changed. If TO was already marked
    1525                 :            :      as changed, decrease the changed count.  */
    1526                 :            : 
    1527                 :   31767200 :   if (update_changed
    1528                 :   31767200 :       && bitmap_clear_bit (changed, from))
    1529                 :      10641 :     bitmap_set_bit (changed, to);
    1530                 :   31767200 :   varinfo_t fromvi = get_varinfo (from);
    1531                 :   31767200 :   if (fromvi->solution)
    1532                 :            :     {
    1533                 :            :       /* If the solution changes because of the merging, we need to mark
    1534                 :            :          the variable as changed.  */
    1535                 :   31767200 :       varinfo_t tovi = get_varinfo (to);
    1536                 :   31767200 :       if (bitmap_ior_into (tovi->solution, fromvi->solution))
    1537                 :            :         {
    1538                 :    1228470 :           if (update_changed)
    1539                 :      38577 :             bitmap_set_bit (changed, to);
    1540                 :            :         }
    1541                 :            : 
    1542                 :   31767200 :       BITMAP_FREE (fromvi->solution);
    1543                 :   31767200 :       if (fromvi->oldsolution)
    1544                 :      12778 :         BITMAP_FREE (fromvi->oldsolution);
    1545                 :            : 
    1546                 :   31767200 :       if (stats.iterations > 0
    1547                 :      54375 :           && tovi->oldsolution)
    1548                 :       3829 :         BITMAP_FREE (tovi->oldsolution);
    1549                 :            :     }
    1550                 :   31767200 :   if (graph->succs[to])
    1551                 :    1564460 :     bitmap_clear_bit (graph->succs[to], to);
    1552                 :   31767200 : }
    1553                 :            : 
    1554                 :            : /* Information needed to compute the topological ordering of a graph.  */
    1555                 :            : 
    1556                 :            : struct topo_info
    1557                 :            : {
    1558                 :            :   /* sbitmap of visited nodes.  */
    1559                 :            :   sbitmap visited;
    1560                 :            :   /* Array that stores the topological order of the graph, *in
    1561                 :            :      reverse*.  */
    1562                 :            :   vec<unsigned> topo_order;
    1563                 :            : };
    1564                 :            : 
    1565                 :            : 
    1566                 :            : /* Initialize and return a topological info structure.  */
    1567                 :            : 
    1568                 :            : static struct topo_info *
    1569                 :    5214870 : init_topo_info (void)
    1570                 :            : {
    1571                 :    5214870 :   size_t size = graph->size;
    1572                 :    5214870 :   struct topo_info *ti = XNEW (struct topo_info);
    1573                 :    5214870 :   ti->visited = sbitmap_alloc (size);
    1574                 :    5214870 :   bitmap_clear (ti->visited);
    1575                 :    5214870 :   ti->topo_order.create (1);
    1576                 :    5214870 :   return ti;
    1577                 :            : }
    1578                 :            : 
    1579                 :            : 
    1580                 :            : /* Free the topological sort info pointed to by TI.  */
    1581                 :            : 
    1582                 :            : static void
    1583                 :    5214870 : free_topo_info (struct topo_info *ti)
    1584                 :            : {
    1585                 :    5214870 :   sbitmap_free (ti->visited);
    1586                 :    5214870 :   ti->topo_order.release ();
    1587                 :    5214870 :   free (ti);
    1588                 :    5214870 : }
    1589                 :            : 
    1590                 :            : /* Visit the graph in topological order, and store the order in the
    1591                 :            :    topo_info structure.  */
    1592                 :            : 
    1593                 :            : static void
    1594                 :  199532000 : topo_visit (constraint_graph_t graph, struct topo_info *ti,
    1595                 :            :             unsigned int n)
    1596                 :            : {
    1597                 :  199532000 :   bitmap_iterator bi;
    1598                 :  199532000 :   unsigned int j;
    1599                 :            : 
    1600                 :  199532000 :   bitmap_set_bit (ti->visited, n);
    1601                 :            : 
    1602                 :  199532000 :   if (graph->succs[n])
    1603                 :  295535000 :     EXECUTE_IF_SET_IN_BITMAP (graph->succs[n], 0, j, bi)
    1604                 :            :       {
    1605                 :  229925000 :         if (!bitmap_bit_p (ti->visited, j))
    1606                 :  118120000 :           topo_visit (graph, ti, j);
    1607                 :            :       }
    1608                 :            : 
    1609                 :  199532000 :   ti->topo_order.safe_push (n);
    1610                 :  199532000 : }
    1611                 :            : 
    1612                 :            : /* Process a constraint C that represents x = *(y + off), using DELTA as the
    1613                 :            :    starting solution for y.  */
    1614                 :            : 
    1615                 :            : static void
    1616                 :   11447600 : do_sd_constraint (constraint_graph_t graph, constraint_t c,
    1617                 :            :                   bitmap delta, bitmap *expanded_delta)
    1618                 :            : {
    1619                 :   11447600 :   unsigned int lhs = c->lhs.var;
    1620                 :   11447600 :   bool flag = false;
    1621                 :   11447600 :   bitmap sol = get_varinfo (lhs)->solution;
    1622                 :   11447600 :   unsigned int j;
    1623                 :   11447600 :   bitmap_iterator bi;
    1624                 :   11447600 :   HOST_WIDE_INT roffset = c->rhs.offset;
    1625                 :            : 
    1626                 :            :   /* Our IL does not allow this.  */
    1627                 :   11447600 :   gcc_checking_assert (c->lhs.offset == 0);
    1628                 :            : 
    1629                 :            :   /* If the solution of Y contains anything it is good enough to transfer
    1630                 :            :      this to the LHS.  */
    1631                 :   11447600 :   if (bitmap_bit_p (delta, anything_id))
    1632                 :            :     {
    1633                 :      23668 :       flag |= bitmap_set_bit (sol, anything_id);
    1634                 :      23668 :       goto done;
    1635                 :            :     }
    1636                 :            : 
    1637                 :            :   /* If we do not know at with offset the rhs is dereferenced compute
    1638                 :            :      the reachability set of DELTA, conservatively assuming it is
    1639                 :            :      dereferenced at all valid offsets.  */
    1640                 :   11424000 :   if (roffset == UNKNOWN_OFFSET)
    1641                 :            :     {
    1642                 :    2675980 :       delta = solution_set_expand (delta, expanded_delta);
    1643                 :            :       /* No further offset processing is necessary.  */
    1644                 :    2675980 :       roffset = 0;
    1645                 :            :     }
    1646                 :            : 
    1647                 :            :   /* For each variable j in delta (Sol(y)), add
    1648                 :            :      an edge in the graph from j to x, and union Sol(j) into Sol(x).  */
    1649                 :   52036900 :   EXECUTE_IF_SET_IN_BITMAP (delta, 0, j, bi)
    1650                 :            :     {
    1651                 :   40612900 :       varinfo_t v = get_varinfo (j);
    1652                 :   40612900 :       HOST_WIDE_INT fieldoffset = v->offset + roffset;
    1653                 :   40612900 :       unsigned HOST_WIDE_INT size = v->size;
    1654                 :   40612900 :       unsigned int t;
    1655                 :            : 
    1656                 :   40612900 :       if (v->is_full_var)
    1657                 :            :         ;
    1658                 :   22038300 :       else if (roffset != 0)
    1659                 :            :         {
    1660                 :    1620380 :           if (fieldoffset < 0)
    1661                 :      39203 :             v = get_varinfo (v->head);
    1662                 :            :           else
    1663                 :    1581170 :             v = first_or_preceding_vi_for_offset (v, fieldoffset);
    1664                 :            :         }
    1665                 :            : 
    1666                 :            :       /* We have to include all fields that overlap the current field
    1667                 :            :          shifted by roffset.  */
    1668                 :   41102000 :       do
    1669                 :            :         {
    1670                 :   41102000 :           t = find (v->id);
    1671                 :            : 
    1672                 :            :           /* Adding edges from the special vars is pointless.
    1673                 :            :              They don't have sets that can change.  */
    1674                 :   41102000 :           if (get_varinfo (t)->is_special_var)
    1675                 :    5167080 :             flag |= bitmap_ior_into (sol, get_varinfo (t)->solution);
    1676                 :            :           /* Merging the solution from ESCAPED needlessly increases
    1677                 :            :              the set.  Use ESCAPED as representative instead.  */
    1678                 :   35934900 :           else if (v->id == escaped_id)
    1679                 :    4643780 :             flag |= bitmap_set_bit (sol, escaped_id);
    1680                 :   31291100 :           else if (v->may_have_pointers
    1681                 :   31291100 :                    && add_graph_edge (graph, lhs, t))
    1682                 :   22054200 :             flag |= bitmap_ior_into (sol, get_varinfo (t)->solution);
    1683                 :            : 
    1684                 :   41102000 :           if (v->is_full_var
    1685                 :   41102000 :               || v->next == 0)
    1686                 :            :             break;
    1687                 :            : 
    1688                 :   19112300 :           v = vi_next (v);
    1689                 :            :         }
    1690                 :   19112300 :       while (v->offset < fieldoffset + size);
    1691                 :            :     }
    1692                 :            : 
    1693                 :   11424000 : done:
    1694                 :            :   /* If the LHS solution changed, mark the var as changed.  */
    1695                 :   11447600 :   if (flag)
    1696                 :            :     {
    1697                 :    7835140 :       get_varinfo (lhs)->solution = sol;
    1698                 :    7835140 :       bitmap_set_bit (changed, lhs);
    1699                 :            :     }
    1700                 :   11447600 : }
    1701                 :            : 
    1702                 :            : /* Process a constraint C that represents *(x + off) = y using DELTA
    1703                 :            :    as the starting solution for x.  */
    1704                 :            : 
    1705                 :            : static void
    1706                 :    7851010 : do_ds_constraint (constraint_t c, bitmap delta, bitmap *expanded_delta)
    1707                 :            : {
    1708                 :    7851010 :   unsigned int rhs = c->rhs.var;
    1709                 :    7851010 :   bitmap sol = get_varinfo (rhs)->solution;
    1710                 :    7851010 :   unsigned int j;
    1711                 :    7851010 :   bitmap_iterator bi;
    1712                 :    7851010 :   HOST_WIDE_INT loff = c->lhs.offset;
    1713                 :    7851010 :   bool escaped_p = false;
    1714                 :            : 
    1715                 :            :   /* Our IL does not allow this.  */
    1716                 :    7851010 :   gcc_checking_assert (c->rhs.offset == 0);
    1717                 :            : 
    1718                 :            :   /* If the solution of y contains ANYTHING simply use the ANYTHING
    1719                 :            :      solution.  This avoids needlessly increasing the points-to sets.  */
    1720                 :    7851010 :   if (bitmap_bit_p (sol, anything_id))
    1721                 :      22847 :     sol = get_varinfo (find (anything_id))->solution;
    1722                 :            : 
    1723                 :            :   /* If the solution for x contains ANYTHING we have to merge the
    1724                 :            :      solution of y into all pointer variables which we do via
    1725                 :            :      STOREDANYTHING.  */
    1726                 :    7851010 :   if (bitmap_bit_p (delta, anything_id))
    1727                 :            :     {
    1728                 :      15941 :       unsigned t = find (storedanything_id);
    1729                 :      15941 :       if (add_graph_edge (graph, t, rhs))
    1730                 :            :         {
    1731                 :       8284 :           if (bitmap_ior_into (get_varinfo (t)->solution, sol))
    1732                 :       8147 :             bitmap_set_bit (changed, t);
    1733                 :            :         }
    1734                 :      15941 :       return;
    1735                 :            :     }
    1736                 :            : 
    1737                 :            :   /* If we do not know at with offset the rhs is dereferenced compute
    1738                 :            :      the reachability set of DELTA, conservatively assuming it is
    1739                 :            :      dereferenced at all valid offsets.  */
    1740                 :    7835070 :   if (loff == UNKNOWN_OFFSET)
    1741                 :            :     {
    1742                 :    1286100 :       delta = solution_set_expand (delta, expanded_delta);
    1743                 :    1286100 :       loff = 0;
    1744                 :            :     }
    1745                 :            : 
    1746                 :            :   /* For each member j of delta (Sol(x)), add an edge from y to j and
    1747                 :            :      union Sol(y) into Sol(j) */
    1748                 :   35319600 :   EXECUTE_IF_SET_IN_BITMAP (delta, 0, j, bi)
    1749                 :            :     {
    1750                 :   27484600 :       varinfo_t v = get_varinfo (j);
    1751                 :   27484600 :       unsigned int t;
    1752                 :   27484600 :       HOST_WIDE_INT fieldoffset = v->offset + loff;
    1753                 :   27484600 :       unsigned HOST_WIDE_INT size = v->size;
    1754                 :            : 
    1755                 :   27484600 :       if (v->is_full_var)
    1756                 :            :         ;
    1757                 :   14107100 :       else if (loff != 0)
    1758                 :            :         {
    1759                 :     878595 :           if (fieldoffset < 0)
    1760                 :        186 :             v = get_varinfo (v->head);
    1761                 :            :           else
    1762                 :     878409 :             v = first_or_preceding_vi_for_offset (v, fieldoffset);
    1763                 :            :         }
    1764                 :            : 
    1765                 :            :       /* We have to include all fields that overlap the current field
    1766                 :            :          shifted by loff.  */
    1767                 :   27757900 :       do
    1768                 :            :         {
    1769                 :   27757900 :           if (v->may_have_pointers)
    1770                 :            :             {
    1771                 :            :               /* If v is a global variable then this is an escape point.  */
    1772                 :   26161800 :               if (v->is_global_var
    1773                 :   26161800 :                   && !escaped_p)
    1774                 :            :                 {
    1775                 :    6828080 :                   t = find (escaped_id);
    1776                 :    6828080 :                   if (add_graph_edge (graph, t, rhs)
    1777                 :   10059400 :                       && bitmap_ior_into (get_varinfo (t)->solution, sol))
    1778                 :     732349 :                     bitmap_set_bit (changed, t);
    1779                 :            :                   /* Enough to let rhs escape once.  */
    1780                 :            :                   escaped_p = true;
    1781                 :            :                 }
    1782                 :            : 
    1783                 :   26161800 :               if (v->is_special_var)
    1784                 :            :                 break;
    1785                 :            : 
    1786                 :   21289700 :               t = find (v->id);
    1787                 :   21289700 :               if (add_graph_edge (graph, t, rhs)
    1788                 :   27884700 :                   && bitmap_ior_into (get_varinfo (t)->solution, sol))
    1789                 :    5447070 :                 bitmap_set_bit (changed, t);
    1790                 :            :             }
    1791                 :            : 
    1792                 :   22885800 :           if (v->is_full_var
    1793                 :   22885800 :               || v->next == 0)
    1794                 :            :             break;
    1795                 :            : 
    1796                 :   12148900 :           v = vi_next (v);
    1797                 :            :         }
    1798                 :   12148900 :       while (v->offset < fieldoffset + size);
    1799                 :            :     }
    1800                 :            : }
    1801                 :            : 
    1802                 :            : /* Handle a non-simple (simple meaning requires no iteration),
    1803                 :            :    constraint (IE *x = &y, x = *y, *x = y, and x = y with offsets involved).  */
    1804                 :            : 
    1805                 :            : static void
    1806                 :   39581400 : do_complex_constraint (constraint_graph_t graph, constraint_t c, bitmap delta,
    1807                 :            :                        bitmap *expanded_delta)
    1808                 :            : {
    1809                 :   39581400 :   if (c->lhs.type == DEREF)
    1810                 :            :     {
    1811                 :    7851010 :       if (c->rhs.type == ADDRESSOF)
    1812                 :            :         {
    1813                 :          0 :           gcc_unreachable ();
    1814                 :            :         }
    1815                 :            :       else
    1816                 :            :         {
    1817                 :            :           /* *x = y */
    1818                 :    7851010 :           do_ds_constraint (c, delta, expanded_delta);
    1819                 :            :         }
    1820                 :            :     }
    1821                 :   31730400 :   else if (c->rhs.type == DEREF)
    1822                 :            :     {
    1823                 :            :       /* x = *y */
    1824                 :   11447600 :       if (!(get_varinfo (c->lhs.var)->is_special_var))
    1825                 :   11447600 :         do_sd_constraint (graph, c, delta, expanded_delta);
    1826                 :            :     }
    1827                 :            :   else
    1828                 :            :     {
    1829                 :   20282800 :       bitmap tmp;
    1830                 :   20282800 :       bool flag = false;
    1831                 :            : 
    1832                 :   20282800 :       gcc_checking_assert (c->rhs.type == SCALAR && c->lhs.type == SCALAR
    1833                 :            :                            && c->rhs.offset != 0 && c->lhs.offset == 0);
    1834                 :   20282800 :       tmp = get_varinfo (c->lhs.var)->solution;
    1835                 :            : 
    1836                 :   20282800 :       flag = set_union_with_increment (tmp, delta, c->rhs.offset,
    1837                 :            :                                        expanded_delta);
    1838                 :            : 
    1839                 :   20282800 :       if (flag)
    1840                 :   11001300 :         bitmap_set_bit (changed, c->lhs.var);
    1841                 :            :     }
    1842                 :   39581400 : }
    1843                 :            : 
    1844                 :            : /* Initialize and return a new SCC info structure.  */
    1845                 :            : 
    1846                 :    5837410 : scc_info::scc_info (size_t size) :
    1847                 :    5837410 :   visited (size), deleted (size), current_index (0), scc_stack (1)
    1848                 :            : {
    1849                 :    5837410 :   bitmap_clear (visited);
    1850                 :    5837410 :   bitmap_clear (deleted);
    1851                 :    5837410 :   node_mapping = XNEWVEC (unsigned int, size);
    1852                 :    5837410 :   dfs = XCNEWVEC (unsigned int, size);
    1853                 :            : 
    1854                 :  412390000 :   for (size_t i = 0; i < size; i++)
    1855                 :  406552000 :     node_mapping[i] = i;
    1856                 :    5837410 : }
    1857                 :            : 
    1858                 :            : /* Free an SCC info structure pointed to by SI */
    1859                 :            : 
    1860                 :   11674800 : scc_info::~scc_info ()
    1861                 :            : {
    1862                 :    5837410 :   free (node_mapping);
    1863                 :    5837410 :   free (dfs);
    1864                 :    5837410 : }
    1865                 :            : 
    1866                 :            : 
    1867                 :            : /* Find indirect cycles in GRAPH that occur, using strongly connected
    1868                 :            :    components, and note them in the indirect cycles map.
    1869                 :            : 
    1870                 :            :    This technique comes from Ben Hardekopf and Calvin Lin,
    1871                 :            :    "It Pays to be Lazy: Fast and Accurate Pointer Analysis for Millions of
    1872                 :            :    Lines of Code", submitted to PLDI 2007.  */
    1873                 :            : 
    1874                 :            : static void
    1875                 :    2918700 : find_indirect_cycles (constraint_graph_t graph)
    1876                 :            : {
    1877                 :    2918700 :   unsigned int i;
    1878                 :    2918700 :   unsigned int size = graph->size;
    1879                 :    2918700 :   scc_info si (size);
    1880                 :            : 
    1881                 :  406552000 :   for (i = 0; i < MIN (LAST_REF_NODE, size); i ++ )
    1882                 :  200357000 :     if (!bitmap_bit_p (si.visited, i) && find (i) == i)
    1883                 :  133416000 :       scc_visit (graph, &si, i);
    1884                 :    2918700 : }
    1885                 :            : 
    1886                 :            : /* Compute a topological ordering for GRAPH, and store the result in the
    1887                 :            :    topo_info structure TI.  */
    1888                 :            : 
    1889                 :            : static void
    1890                 :    5214870 : compute_topo_order (constraint_graph_t graph,
    1891                 :            :                     struct topo_info *ti)
    1892                 :            : {
    1893                 :    5214870 :   unsigned int i;
    1894                 :    5214870 :   unsigned int size = graph->size;
    1895                 :            : 
    1896                 :  294516000 :   for (i = 0; i != size; ++i)
    1897                 :  289301000 :     if (!bitmap_bit_p (ti->visited, i) && find (i) == i)
    1898                 :   81412500 :       topo_visit (graph, ti, i);
    1899                 :    5214870 : }
    1900                 :            : 
    1901                 :            : /* Structure used to for hash value numbering of pointer equivalence
    1902                 :            :    classes.  */
    1903                 :            : 
    1904                 :            : typedef struct equiv_class_label
    1905                 :            : {
    1906                 :            :   hashval_t hashcode;
    1907                 :            :   unsigned int equivalence_class;
    1908                 :            :   bitmap labels;
    1909                 :            : } *equiv_class_label_t;
    1910                 :            : typedef const struct equiv_class_label *const_equiv_class_label_t;
    1911                 :            : 
    1912                 :            : /* Equiv_class_label hashtable helpers.  */
    1913                 :            : 
    1914                 :            : struct equiv_class_hasher : nofree_ptr_hash <equiv_class_label>
    1915                 :            : {
    1916                 :            :   static inline hashval_t hash (const equiv_class_label *);
    1917                 :            :   static inline bool equal (const equiv_class_label *,
    1918                 :            :                             const equiv_class_label *);
    1919                 :            : };
    1920                 :            : 
    1921                 :            : /* Hash function for a equiv_class_label_t */
    1922                 :            : 
    1923                 :            : inline hashval_t
    1924                 :  338729000 : equiv_class_hasher::hash (const equiv_class_label *ecl)
    1925                 :            : {
    1926                 :  338729000 :   return ecl->hashcode;
    1927                 :            : }
    1928                 :            : 
    1929                 :            : /* Equality function for two equiv_class_label_t's.  */
    1930                 :            : 
    1931                 :            : inline bool
    1932                 :  487138000 : equiv_class_hasher::equal (const equiv_class_label *eql1,
    1933                 :            :                            const equiv_class_label *eql2)
    1934                 :            : {
    1935                 :  487138000 :   return (eql1->hashcode == eql2->hashcode
    1936                 :  487138000 :           && bitmap_equal_p (eql1->labels, eql2->labels));
    1937                 :            : }
    1938                 :            : 
    1939                 :            : /* A hashtable for mapping a bitmap of labels->pointer equivalence
    1940                 :            :    classes.  */
    1941                 :            : static hash_table<equiv_class_hasher> *pointer_equiv_class_table;
    1942                 :            : 
    1943                 :            : /* A hashtable for mapping a bitmap of labels->location equivalence
    1944                 :            :    classes.  */
    1945                 :            : static hash_table<equiv_class_hasher> *location_equiv_class_table;
    1946                 :            : 
    1947                 :            : struct obstack equiv_class_obstack;
    1948                 :            : 
    1949                 :            : /* Lookup a equivalence class in TABLE by the bitmap of LABELS with
    1950                 :            :    hash HAS it contains.  Sets *REF_LABELS to the bitmap LABELS
    1951                 :            :    is equivalent to.  */
    1952                 :            : 
    1953                 :            : static equiv_class_label *
    1954                 :   79786300 : equiv_class_lookup_or_add (hash_table<equiv_class_hasher> *table,
    1955                 :            :                            bitmap labels)
    1956                 :            : {
    1957                 :   79786300 :   equiv_class_label **slot;
    1958                 :   79786300 :   equiv_class_label ecl;
    1959                 :            : 
    1960                 :   79786300 :   ecl.labels = labels;
    1961                 :   79786300 :   ecl.hashcode = bitmap_hash (labels);
    1962                 :   79786300 :   slot = table->find_slot (&ecl, INSERT);
    1963                 :   79786300 :   if (!*slot)
    1964                 :            :     {
    1965                 :   69244000 :       *slot = XOBNEW (&equiv_class_obstack, struct equiv_class_label);
    1966                 :   69244000 :       (*slot)->labels = labels;
    1967                 :   69244000 :       (*slot)->hashcode = ecl.hashcode;
    1968                 :   69244000 :       (*slot)->equivalence_class = 0;
    1969                 :            :     }
    1970                 :            : 
    1971                 :   79786300 :   return *slot;
    1972                 :            : }
    1973                 :            : 
    1974                 :            : /* Perform offline variable substitution.
    1975                 :            : 
    1976                 :            :    This is a worst case quadratic time way of identifying variables
    1977                 :            :    that must have equivalent points-to sets, including those caused by
    1978                 :            :    static cycles, and single entry subgraphs, in the constraint graph.
    1979                 :            : 
    1980                 :            :    The technique is described in "Exploiting Pointer and Location
    1981                 :            :    Equivalence to Optimize Pointer Analysis. In the 14th International
    1982                 :            :    Static Analysis Symposium (SAS), August 2007."  It is known as the
    1983                 :            :    "HU" algorithm, and is equivalent to value numbering the collapsed
    1984                 :            :    constraint graph including evaluating unions.
    1985                 :            : 
    1986                 :            :    The general method of finding equivalence classes is as follows:
    1987                 :            :    Add fake nodes (REF nodes) and edges for *a = b and a = *b constraints.
    1988                 :            :    Initialize all non-REF nodes to be direct nodes.
    1989                 :            :    For each constraint a = a U {b}, we set pts(a) = pts(a) u {fresh
    1990                 :            :    variable}
    1991                 :            :    For each constraint containing the dereference, we also do the same
    1992                 :            :    thing.
    1993                 :            : 
    1994                 :            :    We then compute SCC's in the graph and unify nodes in the same SCC,
    1995                 :            :    including pts sets.
    1996                 :            : 
    1997                 :            :    For each non-collapsed node x:
    1998                 :            :     Visit all unvisited explicit incoming edges.
    1999                 :            :     Ignoring all non-pointers, set pts(x) = Union of pts(a) for y
    2000                 :            :     where y->x.
    2001                 :            :     Lookup the equivalence class for pts(x).
    2002                 :            :      If we found one, equivalence_class(x) = found class.
    2003                 :            :      Otherwise, equivalence_class(x) = new class, and new_class is
    2004                 :            :     added to the lookup table.
    2005                 :            : 
    2006                 :            :    All direct nodes with the same equivalence class can be replaced
    2007                 :            :    with a single representative node.
    2008                 :            :    All unlabeled nodes (label == 0) are not pointers and all edges
    2009                 :            :    involving them can be eliminated.
    2010                 :            :    We perform these optimizations during rewrite_constraints
    2011                 :            : 
    2012                 :            :    In addition to pointer equivalence class finding, we also perform
    2013                 :            :    location equivalence class finding.  This is the set of variables
    2014                 :            :    that always appear together in points-to sets.  We use this to
    2015                 :            :    compress the size of the points-to sets.  */
    2016                 :            : 
    2017                 :            : /* Current maximum pointer equivalence class id.  */
    2018                 :            : static int pointer_equiv_class;
    2019                 :            : 
    2020                 :            : /* Current maximum location equivalence class id.  */
    2021                 :            : static int location_equiv_class;
    2022                 :            : 
    2023                 :            : /* Recursive routine to find strongly connected components in GRAPH,
    2024                 :            :    and label it's nodes with DFS numbers.  */
    2025                 :            : 
    2026                 :            : static void
    2027                 :  116345000 : condense_visit (constraint_graph_t graph, class scc_info *si, unsigned int n)
    2028                 :            : {
    2029                 :  116345000 :   unsigned int i;
    2030                 :  116345000 :   bitmap_iterator bi;
    2031                 :  116345000 :   unsigned int my_dfs;
    2032                 :            : 
    2033                 :  116345000 :   gcc_checking_assert (si->node_mapping[n] == n);
    2034                 :  116345000 :   bitmap_set_bit (si->visited, n);
    2035                 :  116345000 :   si->dfs[n] = si->current_index ++;
    2036                 :  116345000 :   my_dfs = si->dfs[n];
    2037                 :            : 
    2038                 :            :   /* Visit all the successors.  */
    2039                 :  173545000 :   EXECUTE_IF_IN_NONNULL_BITMAP (graph->preds[n], 0, i, bi)
    2040                 :            :     {
    2041                 :   57200800 :       unsigned int w = si->node_mapping[i];
    2042                 :            : 
    2043                 :   57200800 :       if (bitmap_bit_p (si->deleted, w))
    2044                 :   29348200 :         continue;
    2045                 :            : 
    2046                 :   27852600 :       if (!bitmap_bit_p (si->visited, w))
    2047                 :   27289700 :         condense_visit (graph, si, w);
    2048                 :            : 
    2049                 :   27852600 :       unsigned int t = si->node_mapping[w];
    2050                 :   27852600 :       gcc_checking_assert (si->node_mapping[n] == n);
    2051                 :   27852600 :       if (si->dfs[t] < si->dfs[n])
    2052                 :     976467 :         si->dfs[n] = si->dfs[t];
    2053                 :            :     }
    2054                 :            : 
    2055                 :            :   /* Visit all the implicit predecessors.  */
    2056                 :  141478000 :   EXECUTE_IF_IN_NONNULL_BITMAP (graph->implicit_preds[n], 0, i, bi)
    2057                 :            :     {
    2058                 :   25133000 :       unsigned int w = si->node_mapping[i];
    2059                 :            : 
    2060                 :   25133000 :       if (bitmap_bit_p (si->deleted, w))
    2061                 :    6484900 :         continue;
    2062                 :            : 
    2063                 :   18648100 :       if (!bitmap_bit_p (si->visited, w))
    2064                 :   15704500 :         condense_visit (graph, si, w);
    2065                 :            : 
    2066                 :   18648100 :       unsigned int t = si->node_mapping[w];
    2067                 :   18648100 :       gcc_assert (si->node_mapping[n] == n);
    2068                 :   18648100 :       if (si->dfs[t] < si->dfs[n])
    2069                 :    5312090 :         si->dfs[n] = si->dfs[t];
    2070                 :            :     }
    2071                 :            : 
    2072                 :            :   /* See if any components have been identified.  */
    2073                 :  116345000 :   if (si->dfs[n] == my_dfs)
    2074                 :            :     {
    2075                 :  110097000 :       if (si->scc_stack.length () != 0
    2076                 :  110097000 :           && si->dfs[si->scc_stack.last ()] >= my_dfs)
    2077                 :            :         {
    2078                 :            :           /* Find the first node of the SCC and do non-bitmap work.  */
    2079                 :            :           bool direct_p = true;
    2080                 :            :           unsigned first = si->scc_stack.length ();
    2081                 :    6247300 :           do
    2082                 :            :             {
    2083                 :    6247300 :               --first;
    2084                 :    6247300 :               unsigned int w = si->scc_stack[first];
    2085                 :    6247300 :               si->node_mapping[w] = n;
    2086                 :    6247300 :               if (!bitmap_bit_p (graph->direct_nodes, w))
    2087                 :    5397910 :                 direct_p = false;
    2088                 :            :             }
    2089                 :            :           while (first > 0
    2090                 :    6247300 :                  && si->dfs[si->scc_stack[first - 1]] >= my_dfs);
    2091                 :     799231 :           if (!direct_p)
    2092                 :     473584 :             bitmap_clear_bit (graph->direct_nodes, n);
    2093                 :            : 
    2094                 :            :           /* Want to reduce to node n, push that first.  */
    2095                 :     799231 :           si->scc_stack.reserve (1);
    2096                 :     799231 :           si->scc_stack.quick_push (si->scc_stack[first]);
    2097                 :     799231 :           si->scc_stack[first] = n;
    2098                 :            : 
    2099                 :     799231 :           unsigned scc_size = si->scc_stack.length () - first;
    2100                 :     799231 :           unsigned split = scc_size / 2;
    2101                 :     799231 :           unsigned carry = scc_size - split * 2;
    2102                 :    2762780 :           while (split > 0)
    2103                 :            :             {
    2104                 :    8210850 :               for (unsigned i = 0; i < split; ++i)
    2105                 :            :                 {
    2106                 :    6247300 :                   unsigned a = si->scc_stack[first + i];
    2107                 :    6247300 :                   unsigned b = si->scc_stack[first + split + carry + i];
    2108                 :            : 
    2109                 :            :                   /* Unify our nodes.  */
    2110                 :    6247300 :                   if (graph->preds[b])
    2111                 :            :                     {
    2112                 :    1852270 :                       if (!graph->preds[a])
    2113                 :     470570 :                         std::swap (graph->preds[a], graph->preds[b]);
    2114                 :            :                       else
    2115                 :    1381700 :                         bitmap_ior_into_and_free (graph->preds[a],
    2116                 :            :                                                   &graph->preds[b]);
    2117                 :            :                     }
    2118                 :    6247300 :                   if (graph->implicit_preds[b])
    2119                 :            :                     {
    2120                 :    5489600 :                       if (!graph->implicit_preds[a])
    2121                 :     559887 :                         std::swap (graph->implicit_preds[a],
    2122                 :            :                                    graph->implicit_preds[b]);
    2123                 :            :                       else
    2124                 :    4929710 :                         bitmap_ior_into_and_free (graph->implicit_preds[a],
    2125                 :            :                                                   &graph->implicit_preds[b]);
    2126                 :            :                     }
    2127                 :    6247300 :                   if (graph->points_to[b])
    2128                 :            :                     {
    2129                 :     230999 :                       if (!graph->points_to[a])
    2130                 :    6247300 :                         std::swap (graph->points_to[a], graph->points_to[b]);
    2131                 :            :                       else
    2132                 :     132589 :                         bitmap_ior_into_and_free (graph->points_to[a],
    2133                 :            :                                                   &graph->points_to[b]);
    2134                 :            :                     }
    2135                 :            :                 }
    2136                 :    1963550 :               unsigned remain = split + carry;
    2137                 :    1963550 :               split = remain / 2;
    2138                 :    1963550 :               carry = remain - split * 2;
    2139                 :            :             }
    2140                 :            :           /* Actually pop the SCC.  */
    2141                 :     799231 :           si->scc_stack.truncate (first);
    2142                 :            :         }
    2143                 :  110097000 :       bitmap_set_bit (si->deleted, n);
    2144                 :            :     }
    2145                 :            :   else
    2146                 :    6247300 :     si->scc_stack.safe_push (n);
    2147                 :  116345000 : }
    2148                 :            : 
    2149                 :            : /* Label pointer equivalences.
    2150                 :            : 
    2151                 :            :    This performs a value numbering of the constraint graph to
    2152                 :            :    discover which variables will always have the same points-to sets
    2153                 :            :    under the current set of constraints.
    2154                 :            : 
    2155                 :            :    The way it value numbers is to store the set of points-to bits
    2156                 :            :    generated by the constraints and graph edges.  This is just used as a
    2157                 :            :    hash and equality comparison.  The *actual set of points-to bits* is
    2158                 :            :    completely irrelevant, in that we don't care about being able to
    2159                 :            :    extract them later.
    2160                 :            : 
    2161                 :            :    The equality values (currently bitmaps) just have to satisfy a few
    2162                 :            :    constraints, the main ones being:
    2163                 :            :    1. The combining operation must be order independent.
    2164                 :            :    2. The end result of a given set of operations must be unique iff the
    2165                 :            :       combination of input values is unique
    2166                 :            :    3. Hashable.  */
    2167                 :            : 
    2168                 :            : static void
    2169                 :  102088000 : label_visit (constraint_graph_t graph, class scc_info *si, unsigned int n)
    2170                 :            : {
    2171                 :  102088000 :   unsigned int i, first_pred;
    2172                 :  102088000 :   bitmap_iterator bi;
    2173                 :            : 
    2174                 :  102088000 :   bitmap_set_bit (si->visited, n);
    2175                 :            : 
    2176                 :            :   /* Label and union our incoming edges's points to sets.  */
    2177                 :  102088000 :   first_pred = -1U;
    2178                 :  158945000 :   EXECUTE_IF_IN_NONNULL_BITMAP (graph->preds[n], 0, i, bi)
    2179                 :            :     {
    2180                 :   56857300 :       unsigned int w = si->node_mapping[i];
    2181                 :   56857300 :       if (!bitmap_bit_p (si->visited, w))
    2182                 :   25795900 :         label_visit (graph, si, w);
    2183                 :            : 
    2184                 :            :       /* Skip unused edges  */
    2185                 :   56857300 :       if (w == n || graph->pointer_label[w] == 0)
    2186                 :    2678620 :         continue;
    2187                 :            : 
    2188                 :   54178700 :       if (graph->points_to[w])
    2189                 :            :         {
    2190                 :   54178700 :           if (!graph->points_to[n])
    2191                 :            :             {
    2192                 :   40600700 :               if (first_pred == -1U)
    2193                 :            :                 first_pred = w;
    2194                 :            :               else
    2195                 :            :                 {
    2196                 :    3288760 :                   graph->points_to[n] = BITMAP_ALLOC (&predbitmap_obstack);
    2197                 :    3288760 :                   bitmap_ior (graph->points_to[n],
    2198                 :    3288760 :                               graph->points_to[first_pred],
    2199                 :    3288760 :                               graph->points_to[w]);
    2200                 :            :                 }
    2201                 :            :             }
    2202                 :            :           else
    2203                 :   13578000 :             bitmap_ior_into (graph->points_to[n], graph->points_to[w]);
    2204                 :            :         }
    2205                 :            :     }
    2206                 :            : 
    2207                 :            :   /* Indirect nodes get fresh variables and a new pointer equiv class.  */
    2208                 :  102088000 :   if (!bitmap_bit_p (graph->direct_nodes, n))
    2209                 :            :     {
    2210                 :   49772100 :       if (!graph->points_to[n])
    2211                 :            :         {
    2212                 :   30662200 :           graph->points_to[n] = BITMAP_ALLOC (&predbitmap_obstack);
    2213                 :   30662200 :           if (first_pred != -1U)
    2214                 :   10000200 :             bitmap_copy (graph->points_to[n], graph->points_to[first_pred]);
    2215                 :            :         }
    2216                 :   99544200 :       bitmap_set_bit (graph->points_to[n], FIRST_REF_NODE + n);
    2217                 :   49772100 :       graph->pointer_label[n] = pointer_equiv_class++;
    2218                 :   49772100 :       equiv_class_label_t ecl;
    2219                 :   99544200 :       ecl = equiv_class_lookup_or_add (pointer_equiv_class_table,
    2220                 :   49772100 :                                        graph->points_to[n]);
    2221                 :   49772100 :       ecl->equivalence_class = graph->pointer_label[n];
    2222                 :   86415200 :       return;
    2223                 :            :     }
    2224                 :            : 
    2225                 :            :   /* If there was only a single non-empty predecessor the pointer equiv
    2226                 :            :      class is the same.  */
    2227                 :   52315900 :   if (!graph->points_to[n])
    2228                 :            :     {
    2229                 :   36643100 :       if (first_pred != -1U)
    2230                 :            :         {
    2231                 :   24022900 :           graph->pointer_label[n] = graph->pointer_label[first_pred];
    2232                 :   24022900 :           graph->points_to[n] = graph->points_to[first_pred];
    2233                 :            :         }
    2234                 :   36643100 :       return;
    2235                 :            :     }
    2236                 :            : 
    2237                 :   15672800 :   if (!bitmap_empty_p (graph->points_to[n]))
    2238                 :            :     {
    2239                 :   15672800 :       equiv_class_label_t ecl;
    2240                 :   15672800 :       ecl = equiv_class_lookup_or_add (pointer_equiv_class_table,
    2241                 :            :                                        graph->points_to[n]);
    2242                 :   15672800 :       if (ecl->equivalence_class == 0)
    2243                 :    7181720 :         ecl->equivalence_class = pointer_equiv_class++;
    2244                 :            :       else
    2245                 :            :         {
    2246                 :    8491100 :           BITMAP_FREE (graph->points_to[n]);
    2247                 :    8491100 :           graph->points_to[n] = ecl->labels;
    2248                 :            :         }
    2249                 :   15672800 :       graph->pointer_label[n] = ecl->equivalence_class;
    2250                 :            :     }
    2251                 :            : }
    2252                 :            : 
    2253                 :            : /* Print the pred graph in dot format.  */
    2254                 :            : 
    2255                 :            : static void
    2256                 :          3 : dump_pred_graph (class scc_info *si, FILE *file)
    2257                 :            : {
    2258                 :          3 :   unsigned int i;
    2259                 :            : 
    2260                 :            :   /* Only print the graph if it has already been initialized:  */
    2261                 :          3 :   if (!graph)
    2262                 :            :     return;
    2263                 :            : 
    2264                 :            :   /* Prints the header of the dot file:  */
    2265                 :          3 :   fprintf (file, "strict digraph {\n");
    2266                 :          3 :   fprintf (file, "  node [\n    shape = box\n  ]\n");
    2267                 :          3 :   fprintf (file, "  edge [\n    fontsize = \"12\"\n  ]\n");
    2268                 :          3 :   fprintf (file, "\n  // List of nodes and complex constraints in "
    2269                 :            :            "the constraint graph:\n");
    2270                 :            : 
    2271                 :            :   /* The next lines print the nodes in the graph together with the
    2272                 :            :      complex constraints attached to them.  */
    2273                 :         76 :   for (i = 1; i < graph->size; i++)
    2274                 :            :     {
    2275                 :        146 :       if (i == FIRST_REF_NODE)
    2276                 :          3 :         continue;
    2277                 :         70 :       if (si->node_mapping[i] != i)
    2278                 :          0 :         continue;
    2279                 :         70 :       if (i < FIRST_REF_NODE)
    2280                 :         35 :         fprintf (file, "\"%s\"", get_varinfo (i)->name);
    2281                 :            :       else
    2282                 :         35 :         fprintf (file, "\"*%s\"", get_varinfo (i - FIRST_REF_NODE)->name);
    2283                 :         70 :       if (graph->points_to[i]
    2284                 :         70 :           && !bitmap_empty_p (graph->points_to[i]))
    2285                 :            :         {
    2286                 :         22 :           if (i < FIRST_REF_NODE)
    2287                 :         11 :             fprintf (file, "[label=\"%s = {", get_varinfo (i)->name);
    2288                 :            :           else
    2289                 :          0 :             fprintf (file, "[label=\"*%s = {",
    2290                 :          0 :                      get_varinfo (i - FIRST_REF_NODE)->name);
    2291                 :         11 :           unsigned j;
    2292                 :         11 :           bitmap_iterator bi;
    2293                 :         25 :           EXECUTE_IF_SET_IN_BITMAP (graph->points_to[i], 0, j, bi)
    2294                 :         14 :             fprintf (file, " %d", j);
    2295                 :         11 :           fprintf (file, " }\"]");
    2296                 :            :         }
    2297                 :         70 :       fprintf (file, ";\n");
    2298                 :            :     }
    2299                 :            : 
    2300                 :            :   /* Go over the edges.  */
    2301                 :          3 :   fprintf (file, "\n  // Edges in the constraint graph:\n");
    2302                 :         76 :   for (i = 1; i < graph->size; i++)
    2303                 :            :     {
    2304                 :         73 :       unsigned j;
    2305                 :         73 :       bitmap_iterator bi;
    2306                 :         73 :       if (si->node_mapping[i] != i)
    2307                 :          0 :         continue;
    2308                 :         84 :       EXECUTE_IF_IN_NONNULL_BITMAP (graph->preds[i], 0, j, bi)
    2309                 :            :         {
    2310                 :         11 :           unsigned from = si->node_mapping[j];
    2311                 :         22 :           if (from < FIRST_REF_NODE)
    2312                 :          6 :             fprintf (file, "\"%s\"", get_varinfo (from)->name);
    2313                 :            :           else
    2314                 :          5 :             fprintf (file, "\"*%s\"", get_varinfo (from - FIRST_REF_NODE)->name);
    2315                 :         11 :           fprintf (file, " -> ");
    2316                 :         22 :           if (i < FIRST_REF_NODE)
    2317                 :          7 :             fprintf (file, "\"%s\"", get_varinfo (i)->name);
    2318                 :            :           else
    2319                 :          4 :             fprintf (file, "\"*%s\"", get_varinfo (i - FIRST_REF_NODE)->name);
    2320                 :         11 :           fprintf (file, ";\n");
    2321                 :            :         }
    2322                 :            :     }
    2323                 :            : 
    2324                 :            :   /* Prints the tail of the dot file.  */
    2325                 :          3 :   fprintf (file, "}\n");
    2326                 :            : }
    2327                 :            : 
    2328                 :            : /* Perform offline variable substitution, discovering equivalence
    2329                 :            :    classes, and eliminating non-pointer variables.  */
    2330                 :            : 
    2331                 :            : static class scc_info *
    2332                 :    2918700 : perform_var_substitution (constraint_graph_t graph)
    2333                 :            : {
    2334                 :    2918700 :   unsigned int i;
    2335                 :    2918700 :   unsigned int size = graph->size;
    2336                 :    2918700 :   scc_info *si = new scc_info (size);
    2337                 :            : 
    2338                 :    2918700 :   bitmap_obstack_initialize (&iteration_obstack);
    2339                 :    2918700 :   gcc_obstack_init (&equiv_class_obstack);
    2340                 :    2918700 :   pointer_equiv_class_table = new hash_table<equiv_class_hasher> (511);
    2341                 :    2918700 :   location_equiv_class_table
    2342                 :    2918700 :     = new hash_table<equiv_class_hasher> (511);
    2343                 :    2918700 :   pointer_equiv_class = 1;
    2344                 :    2918700 :   location_equiv_class = 1;
    2345                 :            : 
    2346                 :            :   /* Condense the nodes, which means to find SCC's, count incoming
    2347                 :            :      predecessors, and unite nodes in SCC's.  */
    2348                 :  203276000 :   for (i = 1; i < FIRST_REF_NODE; i++)
    2349                 :   98719400 :     if (!bitmap_bit_p (si->visited, si->node_mapping[i]))
    2350                 :   73350400 :       condense_visit (graph, si, si->node_mapping[i]);
    2351                 :            : 
    2352                 :    2918700 :   if (dump_file && (dump_flags & TDF_GRAPH))
    2353                 :            :     {
    2354                 :          3 :       fprintf (dump_file, "\n\n// The constraint graph before var-substitution "
    2355                 :            :                "in dot format:\n");
    2356                 :          3 :       dump_pred_graph (si, dump_file);
    2357                 :          3 :       fprintf (dump_file, "\n\n");
    2358                 :            :     }
    2359                 :            : 
    2360                 :    2918700 :   bitmap_clear (si->visited);
    2361                 :            :   /* Actually the label the nodes for pointer equivalences  */
    2362                 :  203276000 :   for (i = 1; i < FIRST_REF_NODE; i++)
    2363                 :   98719400 :     if (!bitmap_bit_p (si->visited, si->node_mapping[i]))
    2364                 :   76292100 :       label_visit (graph, si, si->node_mapping[i]);
    2365                 :            : 
    2366                 :            :   /* Calculate location equivalence labels.  */
    2367                 :  203276000 :   for (i = 1; i < FIRST_REF_NODE; i++)
    2368                 :            :     {
    2369                 :   98719400 :       bitmap pointed_by;
    2370                 :   98719400 :       bitmap_iterator bi;
    2371                 :   98719400 :       unsigned int j;
    2372                 :            : 
    2373                 :   98719400 :       if (!graph->pointed_by[i])
    2374                 :   84377900 :         continue;
    2375                 :   14341400 :       pointed_by = BITMAP_ALLOC (&iteration_obstack);
    2376                 :            : 
    2377                 :            :       /* Translate the pointed-by mapping for pointer equivalence
    2378                 :            :          labels.  */
    2379                 :   52381000 :       EXECUTE_IF_SET_IN_BITMAP (graph->pointed_by[i], 0, j, bi)
    2380                 :            :         {
    2381                 :   38039500 :           bitmap_set_bit (pointed_by,
    2382                 :   38039500 :                           graph->pointer_label[si->node_mapping[j]]);
    2383                 :            :         }
    2384                 :            :       /* The original pointed_by is now dead.  */
    2385                 :   14341400 :       BITMAP_FREE (graph->pointed_by[i]);
    2386                 :            : 
    2387                 :            :       /* Look up the location equivalence label if one exists, or make
    2388                 :            :          one otherwise.  */
    2389                 :   14341400 :       equiv_class_label_t ecl;
    2390                 :   14341400 :       ecl = equiv_class_lookup_or_add (location_equiv_class_table, pointed_by);
    2391                 :   14341400 :       if (ecl->equivalence_class == 0)
    2392                 :   12290200 :         ecl->equivalence_class = location_equiv_class++;
    2393                 :            :       else
    2394                 :            :         {
    2395                 :    2051280 :           if (dump_file && (dump_flags & TDF_DETAILS))
    2396                 :        177 :             fprintf (dump_file, "Found location equivalence for node %s\n",
    2397                 :        177 :                      get_varinfo (i)->name);
    2398                 :    2051280 :           BITMAP_FREE (pointed_by);
    2399                 :            :         }
    2400                 :   14341400 :       graph->loc_label[i] = ecl->equivalence_class;
    2401                 :            : 
    2402                 :            :     }
    2403                 :            : 
    2404                 :    2918700 :   if (dump_file && (dump_flags & TDF_DETAILS))
    2405                 :       5382 :     for (i = 1; i < FIRST_REF_NODE; i++)
    2406                 :            :       {
    2407                 :       2551 :         unsigned j = si->node_mapping[i];
    2408                 :       2551 :         if (j != i)
    2409                 :            :           {
    2410                 :          0 :             fprintf (dump_file, "%s node id %d ",
    2411                 :          0 :                      bitmap_bit_p (graph->direct_nodes, i)
    2412                 :            :                      ? "Direct" : "Indirect", i);
    2413                 :          0 :             if (i < FIRST_REF_NODE)
    2414                 :          0 :               fprintf (dump_file, "\"%s\"", get_varinfo (i)->name);
    2415                 :            :             else
    2416                 :          0 :               fprintf (dump_file, "\"*%s\"",
    2417                 :          0 :                        get_varinfo (i - FIRST_REF_NODE)->name);
    2418                 :          0 :             fprintf (dump_file, " mapped to SCC leader node id %d ", j);
    2419                 :          0 :             if (j < FIRST_REF_NODE)
    2420                 :          0 :               fprintf (dump_file, "\"%s\"\n", get_varinfo (j)->name);
    2421                 :            :             else
    2422                 :          0 :               fprintf (dump_file, "\"*%s\"\n",
    2423                 :          0 :                        get_varinfo (j - FIRST_REF_NODE)->name);
    2424                 :            :           }
    2425                 :            :         else
    2426                 :            :           {
    2427                 :       2551 :             fprintf (dump_file,
    2428                 :            :                      "Equivalence classes for %s node id %d ",
    2429                 :       2551 :                      bitmap_bit_p (graph->direct_nodes, i)
    2430                 :            :                      ? "direct" : "indirect", i);
    2431                 :       5102 :             if (i < FIRST_REF_NODE)
    2432                 :       2551 :               fprintf (dump_file, "\"%s\"", get_varinfo (i)->name);
    2433                 :            :             else
    2434                 :          0 :               fprintf (dump_file, "\"*%s\"",
    2435                 :          0 :                        get_varinfo (i - FIRST_REF_NODE)->name);
    2436                 :       2551 :             fprintf (dump_file,
    2437                 :            :                      ": pointer %d, location %d\n",
    2438                 :       2551 :                      graph->pointer_label[i], graph->loc_label[i]);
    2439                 :            :           }
    2440                 :            :       }
    2441                 :            : 
    2442                 :            :   /* Quickly eliminate our non-pointer variables.  */
    2443                 :            : 
    2444                 :  203276000 :   for (i = 1; i < FIRST_REF_NODE; i++)
    2445                 :            :     {
    2446                 :   98719400 :       unsigned int node = si->node_mapping[i];
    2447                 :            : 
    2448                 :   98719400 :       if (graph->pointer_label[node] == 0)
    2449                 :            :         {
    2450                 :   12621000 :           if (dump_file && (dump_flags & TDF_DETAILS))
    2451                 :        304 :             fprintf (dump_file,
    2452                 :            :                      "%s is a non-pointer variable, eliminating edges.\n",
    2453                 :        304 :                      get_varinfo (node)->name);
    2454                 :   12621000 :           stats.nonpointer_vars++;
    2455                 :   98719400 :           clear_edges_for_node (graph, node);
    2456                 :            :         }
    2457                 :            :     }
    2458                 :            : 
    2459                 :    2918700 :   return si;
    2460                 :            : }
    2461                 :            : 
    2462                 :            : /* Free information that was only necessary for variable
    2463                 :            :    substitution.  */
    2464                 :            : 
    2465                 :            : static void
    2466                 :    2918700 : free_var_substitution_info (class scc_info *si)
    2467                 :            : {
    2468                 :    2918700 :   delete si;
    2469                 :    2918700 :   free (graph->pointer_label);
    2470                 :    2918700 :   free (graph->loc_label);
    2471                 :    2918700 :   free (graph->pointed_by);
    2472                 :    2918700 :   free (graph->points_to);
    2473                 :    2918700 :   free (graph->eq_rep);
    2474                 :    2918700 :   sbitmap_free (graph->direct_nodes);
    2475                 :    2918700 :   delete pointer_equiv_class_table;
    2476                 :    2918700 :   pointer_equiv_class_table = NULL;
    2477                 :    2918700 :   delete location_equiv_class_table;
    2478                 :    2918700 :   location_equiv_class_table = NULL;
    2479                 :    2918700 :   obstack_free (&equiv_class_obstack, NULL);
    2480                 :    2918700 :   bitmap_obstack_release (&iteration_obstack);
    2481                 :    2918700 : }
    2482                 :            : 
    2483                 :            : /* Return an existing node that is equivalent to NODE, which has
    2484                 :            :    equivalence class LABEL, if one exists.  Return NODE otherwise.  */
    2485                 :            : 
    2486                 :            : static unsigned int
    2487                 :  265792000 : find_equivalent_node (constraint_graph_t graph,
    2488                 :            :                       unsigned int node, unsigned int label)
    2489                 :            : {
    2490                 :            :   /* If the address version of this variable is unused, we can
    2491                 :            :      substitute it for anything else with the same label.
    2492                 :            :      Otherwise, we know the pointers are equivalent, but not the
    2493                 :            :      locations, and we can unite them later.  */
    2494                 :            : 
    2495                 :  265792000 :   if (!bitmap_bit_p (graph->address_taken, node))
    2496                 :            :     {
    2497                 :  152397000 :       gcc_checking_assert (label < graph->size);
    2498                 :            : 
    2499                 :  152397000 :       if (graph->eq_rep[label] != -1)
    2500                 :            :         {
    2501                 :            :           /* Unify the two variables since we know they are equivalent.  */
    2502                 :  117435000 :           if (unite (graph->eq_rep[label], node))
    2503                 :   30182600 :             unify_nodes (graph, graph->eq_rep[label], node, false);
    2504                 :  117435000 :           return graph->eq_rep[label];
    2505                 :            :         }
    2506                 :            :       else
    2507                 :            :         {
    2508                 :   34961500 :           graph->eq_rep[label] = node;
    2509                 :   34961500 :           graph->pe_rep[label] = node;
    2510                 :            :         }
    2511                 :            :     }
    2512                 :            :   else
    2513                 :            :     {
    2514                 :  113395000 :       gcc_checking_assert (label < graph->size);
    2515                 :  113395000 :       graph->pe[node] = label;
    2516                 :  113395000 :       if (graph->pe_rep[label] == -1)
    2517                 :   14275500 :         graph->pe_rep[label] = node;
    2518                 :            :     }
    2519                 :            : 
    2520                 :            :   return node;
    2521                 :            : }
    2522                 :            : 
    2523                 :            : /* Unite pointer equivalent but not location equivalent nodes in
    2524                 :            :    GRAPH.  This may only be performed once variable substitution is
    2525                 :            :    finished.  */
    2526                 :            : 
    2527                 :            : static void
    2528                 :    2918700 : unite_pointer_equivalences (constraint_graph_t graph)
    2529                 :            : {
    2530                 :    2918700 :   unsigned int i;
    2531                 :            : 
    2532                 :            :   /* Go through the pointer equivalences and unite them to their
    2533                 :            :      representative, if they aren't already.  */
    2534                 :  203276000 :   for (i = 1; i < FIRST_REF_NODE; i++)
    2535                 :            :     {
    2536                 :   98719400 :       unsigned int label = graph->pe[i];
    2537                 :   98719400 :       if (label)
    2538                 :            :         {
    2539                 :   14341400 :           int label_rep = graph->pe_rep[label];
    2540                 :            : 
    2541                 :   14341400 :           if (label_rep == -1)
    2542                 :          0 :             continue;
    2543                 :            : 
    2544                 :   14341400 :           label_rep = find (label_rep);
    2545                 :   14341400 :           if (label_rep >= 0 && unite (label_rep, find (i)))
    2546                 :    1518800 :             unify_nodes (graph, label_rep, i, false);
    2547                 :            :         }
    2548                 :            :     }
    2549                 :    2918700 : }
    2550                 :            : 
    2551                 :            : /* Move complex constraints to the GRAPH nodes they belong to.  */
    2552                 :            : 
    2553                 :            : static void
    2554                 :    2918700 : move_complex_constraints (constraint_graph_t graph)
    2555                 :            : {
    2556                 :    2918700 :   int i;
    2557                 :    2918700 :   constraint_t c;
    2558                 :            : 
    2559                 :  137516000 :   FOR_EACH_VEC_ELT (constraints, i, c)
    2560                 :            :     {
    2561                 :  134597000 :       if (c)
    2562                 :            :         {
    2563                 :  132896000 :           struct constraint_expr lhs = c->lhs;
    2564                 :  132896000 :           struct constraint_expr rhs = c->rhs;
    2565                 :            : 
    2566                 :  132896000 :           if (lhs.type == DEREF)
    2567                 :            :             {
    2568                 :    7481580 :               insert_into_complex (graph, lhs.var, c);
    2569                 :            :             }
    2570                 :  125414000 :           else if (rhs.type == DEREF)
    2571                 :            :             {
    2572                 :   10583700 :               if (!(get_varinfo (lhs.var)->is_special_var))
    2573                 :   10583700 :                 insert_into_complex (graph, rhs.var, c);
    2574                 :            :             }
    2575                 :  114830000 :           else if (rhs.type != ADDRESSOF && lhs.var > anything_id
    2576                 :   66470100 :                    && (lhs.offset != 0 || rhs.offset != 0))
    2577                 :            :             {
    2578                 :   16741800 :               insert_into_complex (graph, rhs.var, c);
    2579                 :            :             }
    2580                 :            :         }
    2581                 :            :     }
    2582                 :    2918700 : }
    2583                 :            : 
    2584                 :            : 
    2585                 :            : /* Optimize and rewrite complex constraints while performing
    2586                 :            :    collapsing of equivalent nodes.  SI is the SCC_INFO that is the
    2587                 :            :    result of perform_variable_substitution.  */
    2588                 :            : 
    2589                 :            : static void
    2590                 :    2918700 : rewrite_constraints (constraint_graph_t graph,
    2591                 :            :                      class scc_info *si)
    2592                 :            : {
    2593                 :    2918700 :   int i;
    2594                 :    2918700 :   constraint_t c;
    2595                 :            : 
    2596                 :    2918700 :   if (flag_checking)
    2597                 :            :     {
    2598                 :  206193000 :       for (unsigned int j = 0; j < graph->size; j++)
    2599                 :  203274000 :         gcc_assert (find (j) == j);
    2600                 :            :     }
    2601                 :            : 
    2602                 :  137516000 :   FOR_EACH_VEC_ELT (constraints, i, c)
    2603                 :            :     {
    2604                 :  134597000 :       struct constraint_expr lhs = c->lhs;
    2605                 :  134597000 :       struct constraint_expr rhs = c->rhs;
    2606                 :  134597000 :       unsigned int lhsvar = find (lhs.var);
    2607                 :  134597000 :       unsigned int rhsvar = find (rhs.var);
    2608                 :  134597000 :       unsigned int lhsnode, rhsnode;
    2609                 :  134597000 :       unsigned int lhslabel, rhslabel;
    2610                 :            : 
    2611                 :  134597000 :       lhsnode = si->node_mapping[lhsvar];
    2612                 :  134597000 :       rhsnode = si->node_mapping[rhsvar];
    2613                 :  134597000 :       lhslabel = graph->pointer_label[lhsnode];
    2614                 :  134597000 :       rhslabel = graph->pointer_label[rhsnode];
    2615                 :            : 
    2616                 :            :       /* See if it is really a non-pointer variable, and if so, ignore
    2617                 :            :          the constraint.  */
    2618                 :  134597000 :       if (lhslabel == 0)
    2619                 :            :         {
    2620                 :     614583 :           if (dump_file && (dump_flags & TDF_DETAILS))
    2621                 :            :             {
    2622                 :            : 
    2623                 :          6 :               fprintf (dump_file, "%s is a non-pointer variable, "
    2624                 :            :                        "ignoring constraint:",
    2625                 :          3 :                        get_varinfo (lhs.var)->name);
    2626                 :          3 :               dump_constraint (dump_file, c);
    2627                 :          3 :               fprintf (dump_file, "\n");
    2628                 :            :             }
    2629                 :     614583 :           constraints[i] = NULL;
    2630                 :    1701240 :           continue;
    2631                 :            :         }
    2632                 :            : 
    2633                 :  133982000 :       if (rhslabel == 0)
    2634                 :            :         {
    2635                 :    1086660 :           if (dump_file && (dump_flags & TDF_DETAILS))
    2636                 :            :             {
    2637                 :            : 
    2638                 :         10 :               fprintf (dump_file, "%s is a non-pointer variable, "
    2639                 :            :                        "ignoring constraint:",
    2640                 :          5 :                        get_varinfo (rhs.var)->name);
    2641                 :          5 :               dump_constraint (dump_file, c);
    2642                 :          5 :               fprintf (dump_file, "\n");
    2643                 :            :             }
    2644                 :    1086660 :           constraints[i] = NULL;
    2645                 :    1086660 :           continue;
    2646                 :            :         }
    2647                 :            : 
    2648                 :  132896000 :       lhsvar = find_equivalent_node (graph, lhsvar, lhslabel);
    2649                 :  132896000 :       rhsvar = find_equivalent_node (graph, rhsvar, rhslabel);
    2650                 :  132896000 :       c->lhs.var = lhsvar;
    2651                 :  132896000 :       c->rhs.var = rhsvar;
    2652                 :            :     }
    2653                 :    2918700 : }
    2654                 :            : 
    2655                 :            : /* Eliminate indirect cycles involving NODE.  Return true if NODE was
    2656                 :            :    part of an SCC, false otherwise.  */
    2657                 :            : 
    2658                 :            : static bool
    2659                 :  197154000 : eliminate_indirect_cycles (unsigned int node)
    2660                 :            : {
    2661                 :  197154000 :   if (graph->indirect_cycles[node] != -1
    2662                 :  197395000 :       && !bitmap_empty_p (get_varinfo (node)->solution))
    2663                 :            :     {
    2664                 :     189875 :       unsigned int i;
    2665                 :     379750 :       auto_vec<unsigned> queue;
    2666                 :     189875 :       int queuepos;
    2667                 :     189875 :       unsigned int to = find (graph->indirect_cycles[node]);
    2668                 :     189875 :       bitmap_iterator bi;
    2669                 :            : 
    2670                 :            :       /* We can't touch the solution set and call unify_nodes
    2671                 :            :          at the same time, because unify_nodes is going to do
    2672                 :            :          bitmap unions into it. */
    2673                 :            : 
    2674                 :     657551 :       EXECUTE_IF_SET_IN_BITMAP (get_varinfo (node)->solution, 0, i, bi)
    2675                 :            :         {
    2676                 :     467676 :           if (find (i) == i && i != to)
    2677                 :            :             {
    2678                 :      54375 :               if (unite (to, i))
    2679                 :      54375 :                 queue.safe_push (i);
    2680                 :            :             }
    2681                 :            :         }
    2682                 :            : 
    2683                 :      54375 :       for (queuepos = 0;
    2684                 :     286399 :            queue.iterate (queuepos, &i);
    2685                 :            :            queuepos++)
    2686                 :            :         {
    2687                 :      54375 :           unify_nodes (graph, to, i, true);
    2688                 :            :         }
    2689                 :     189875 :       return true;
    2690                 :            :     }
    2691                 :            :   return false;
    2692                 :            : }
    2693                 :            : 
    2694                 :            : /* Solve the constraint graph GRAPH using our worklist solver.
    2695                 :            :    This is based on the PW* family of solvers from the "Efficient Field
    2696                 :            :    Sensitive Pointer Analysis for C" paper.
    2697                 :            :    It works by iterating over all the graph nodes, processing the complex
    2698                 :            :    constraints and propagating the copy constraints, until everything stops
    2699                 :            :    changed.  This corresponds to steps 6-8 in the solving list given above.  */
    2700                 :            : 
    2701                 :            : static void
    2702                 :    2918700 : solve_graph (constraint_graph_t graph)
    2703                 :            : {
    2704                 :    2918700 :   unsigned int size = graph->size;
    2705                 :    2918700 :   unsigned int i;
    2706                 :    2918700 :   bitmap pts;
    2707                 :            : 
    2708                 :    2918700 :   changed = BITMAP_ALLOC (NULL);
    2709                 :            : 
    2710                 :            :   /* Mark all initial non-collapsed nodes as changed.  */
    2711                 :  101638000 :   for (i = 1; i < size; i++)
    2712                 :            :     {
    2713                 :   98719400 :       varinfo_t ivi = get_varinfo (i);
    2714                 :  165726000 :       if (find (i) == i && !bitmap_empty_p (ivi->solution)
    2715                 :  122521000 :           && ((graph->succs[i] && !bitmap_empty_p (graph->succs[i]))
    2716                 :   18399100 :               || graph->complex[i].length () > 0))
    2717                 :   10270700 :         bitmap_set_bit (changed, i);
    2718                 :            :     }
    2719                 :            : 
    2720                 :            :   /* Allocate a bitmap to be used to store the changed bits.  */
    2721                 :    2918700 :   pts = BITMAP_ALLOC (&pta_obstack);
    2722                 :            : 
    2723                 :    8133580 :   while (!bitmap_empty_p (changed))
    2724                 :            :     {
    2725                 :    5214870 :       unsigned int i;
    2726                 :    5214870 :       struct topo_info *ti = init_topo_info ();
    2727                 :    5214870 :       stats.iterations++;
    2728                 :            : 
    2729                 :    5214870 :       bitmap_obstack_initialize (&iteration_obstack);
    2730                 :            : 
    2731                 :    5214870 :       compute_topo_order (graph, ti);
    2732                 :            : 
    2733                 :  204747000 :       while (ti->topo_order.length () != 0)
    2734                 :            :         {
    2735                 :            : 
    2736                 :  199532000 :           i = ti->topo_order.pop ();
    2737                 :            : 
    2738                 :            :           /* If this variable is not a representative, skip it.  */
    2739                 :  199532000 :           if (find (i) != i)
    2740                 :    2378570 :             continue;
    2741                 :            : 
    2742                 :            :           /* In certain indirect cycle cases, we may merge this
    2743                 :            :              variable to another.  */
    2744                 :  197154000 :           if (eliminate_indirect_cycles (i) && find (i) != i)
    2745                 :          5 :             continue;
    2746                 :            : 
    2747                 :            :           /* If the node has changed, we need to process the
    2748                 :            :              complex constraints and outgoing edges again.  */
    2749                 :  197154000 :           if (bitmap_clear_bit (changed, i))
    2750                 :            :             {
    2751                 :   44276800 :               unsigned int j;
    2752                 :   44276800 :               constraint_t c;
    2753                 :   44276800 :               bitmap solution;
    2754                 :   44276800 :               vec<constraint_t> complex = graph->complex[i];
    2755                 :   44276800 :               varinfo_t vi = get_varinfo (i);
    2756                 :   44276800 :               bool solution_empty;
    2757                 :            : 
    2758                 :            :               /* Compute the changed set of solution bits.  If anything
    2759                 :            :                  is in the solution just propagate that.  */
    2760                 :   44276800 :               if (bitmap_bit_p (vi->solution, anything_id))
    2761                 :            :                 {
    2762                 :            :                   /* If anything is also in the old solution there is
    2763                 :            :                      nothing to do.
    2764                 :            :                      ???  But we shouldn't ended up with "changed" set ...  */
    2765                 :     188271 :                   if (vi->oldsolution
    2766                 :     156867 :                       && bitmap_bit_p (vi->oldsolution, anything_id))
    2767                 :      31404 :                     continue;
    2768                 :     125463 :                   bitmap_copy (pts, get_varinfo (find (anything_id))->solution);
    2769                 :            :                 }
    2770                 :   44119900 :               else if (vi->oldsolution)
    2771                 :    7604690 :                 bitmap_and_compl (pts, vi->solution, vi->oldsolution);
    2772                 :            :               else
    2773                 :   36515200 :                 bitmap_copy (pts, vi->solution);
    2774                 :            : 
    2775                 :   44245400 :               if (bitmap_empty_p (pts))
    2776                 :          0 :                 continue;
    2777                 :            : 
    2778                 :   44245400 :               if (vi->oldsolution)
    2779                 :    7650170 :                 bitmap_ior_into (vi->oldsolution, pts);
    2780                 :            :               else
    2781                 :            :                 {
    2782                 :   36595200 :                   vi->oldsolution = BITMAP_ALLOC (&oldpta_obstack);
    2783                 :   36595200 :                   bitmap_copy (vi->oldsolution, pts);
    2784                 :            :                 }
    2785                 :            : 
    2786                 :   44245400 :               solution = vi->solution;
    2787                 :   44245400 :               solution_empty = bitmap_empty_p (solution);
    2788                 :            : 
    2789                 :            :               /* Process the complex constraints */
    2790                 :   44245400 :               bitmap expanded_pts = NULL;
    2791                 :   83826800 :               FOR_EACH_VEC_ELT (complex, j, c)
    2792                 :            :                 {
    2793                 :            :                   /* XXX: This is going to unsort the constraints in
    2794                 :            :                      some cases, which will occasionally add duplicate
    2795                 :            :                      constraints during unification.  This does not
    2796                 :            :                      affect correctness.  */
    2797                 :   39581400 :                   c->lhs.var = find (c->lhs.var);
    2798                 :   39581400 :                   c->rhs.var = find (c->rhs.var);
    2799                 :            : 
    2800                 :            :                   /* The only complex constraint that can change our
    2801                 :            :                      solution to non-empty, given an empty solution,
    2802                 :            :                      is a constraint where the lhs side is receiving
    2803                 :            :                      some set from elsewhere.  */
    2804                 :   39581400 :                   if (!solution_empty || c->lhs.type != DEREF)
    2805                 :   39581400 :                     do_complex_constraint (graph, c, pts, &expanded_pts);
    2806                 :            :                 }
    2807                 :   44245400 :               BITMAP_FREE (expanded_pts);
    2808                 :            : 
    2809                 :   44245400 :               solution_empty = bitmap_empty_p (solution);
    2810                 :            : 
    2811                 :   44245400 :               if (!solution_empty)
    2812                 :            :                 {
    2813                 :   44245400 :                   bitmap_iterator bi;
    2814                 :   44245400 :                   unsigned eff_escaped_id = find (escaped_id);
    2815                 :            : 
    2816                 :            :                   /* Propagate solution to all successors.  */
    2817                 :   44245400 :                   unsigned to_remove = ~0U;
    2818                 :   82063000 :                   EXECUTE_IF_IN_NONNULL_BITMAP (graph->succs[i],
    2819                 :            :                                                 0, j, bi)
    2820                 :            :                     {
    2821                 :   37817600 :                       if (to_remove != ~0U)
    2822                 :            :                         {
    2823                 :     985996 :                           bitmap_clear_bit (graph->succs[i], to_remove);
    2824                 :     985996 :                           to_remove = ~0U;
    2825                 :            :                         }
    2826                 :   37817600 :                       unsigned int to = find (j);
    2827                 :   37817600 :                       if (to != j)
    2828                 :            :                         {
    2829                 :            :                           /* Update the succ graph, avoiding duplicate
    2830                 :            :                              work.  */
    2831                 :    1213170 :                           to_remove = j;
    2832                 :    1213170 :                           if (! bitmap_set_bit (graph->succs[i], to))
    2833                 :     237580 :                             continue;
    2834                 :            :                           /* We eventually end up processing 'to' twice
    2835                 :            :                              as it is undefined whether bitmap iteration
    2836                 :            :                              iterates over bits set during iteration.
    2837                 :            :                              Play safe instead of doing tricks.  */
    2838                 :            :                         }
    2839                 :            :                       /* Don't try to propagate to ourselves.  */
    2840                 :   37580100 :                       if (to == i)
    2841                 :     164959 :                         continue;
    2842                 :            : 
    2843                 :   37415100 :                       bitmap tmp = get_varinfo (to)->solution;
    2844                 :   37415100 :                       bool flag = false;
    2845                 :            : 
    2846                 :            :                       /* If we propagate from ESCAPED use ESCAPED as
    2847                 :            :                          placeholder.  */
    2848                 :   37415100 :                       if (i == eff_escaped_id)
    2849                 :     114562 :                         flag = bitmap_set_bit (tmp, escaped_id);
    2850                 :            :                       else
    2851                 :   37300500 :                         flag = bitmap_ior_into (tmp, pts);
    2852                 :            : 
    2853                 :   37415100 :                       if (flag)
    2854                 :   13838300 :                         bitmap_set_bit (changed, to);
    2855                 :            :                     }
    2856                 :   19796300 :                   if (to_remove != ~0U)
    2857                 :     227174 :                     bitmap_clear_bit (graph->succs[i], to_remove);
    2858                 :            :                 }
    2859                 :            :             }
    2860                 :            :         }
    2861                 :    5214870 :       free_topo_info (ti);
    2862                 :    5214870 :       bitmap_obstack_release (&iteration_obstack);
    2863                 :            :     }
    2864                 :            : 
    2865                 :    2918700 :   BITMAP_FREE (pts);
    2866                 :    2918700 :   BITMAP_FREE (changed);
    2867                 :    2918700 :   bitmap_obstack_release (&oldpta_obstack);
    2868                 :    2918700 : }
    2869                 :            : 
    2870                 :            : /* Map from trees to variable infos.  */
    2871                 :            : static hash_map<tree, varinfo_t> *vi_for_tree;
    2872                 :            : 
    2873                 :            : 
    2874                 :            : /* Insert ID as the variable id for tree T in the vi_for_tree map.  */
    2875                 :            : 
    2876                 :            : static void
    2877                 :   62082100 : insert_vi_for_tree (tree t, varinfo_t vi)
    2878                 :            : {
    2879                 :   62082100 :   gcc_assert (vi);
    2880                 :   62082100 :   gcc_assert (!vi_for_tree->put (t, vi));
    2881                 :   62082100 : }
    2882                 :            : 
    2883                 :            : /* Find the variable info for tree T in VI_FOR_TREE.  If T does not
    2884                 :            :    exist in the map, return NULL, otherwise, return the varinfo we found.  */
    2885                 :            : 
    2886                 :            : static varinfo_t
    2887                 :   35749800 : lookup_vi_for_tree (tree t)
    2888                 :            : {
    2889                 :   35749800 :   varinfo_t *slot = vi_for_tree->get (t);
    2890                 :   34178800 :   if (slot == NULL)
    2891                 :            :     return NULL;
    2892                 :            : 
    2893                 :   34178800 :   return *slot;
    2894                 :            : }
    2895                 :            : 
    2896                 :            : /* Return a printable name for DECL  */
    2897                 :            : 
    2898                 :            : static const char *
    2899                 :   61418100 : alias_get_name (tree decl)
    2900                 :            : {
    2901                 :   61418100 :   const char *res = "NULL";
    2902                 :   61418100 :   if (dump_file)
    2903                 :            :     {
    2904                 :       4197 :       char *temp = NULL;
    2905                 :       4197 :       if (TREE_CODE (decl) == SSA_NAME)
    2906                 :            :         {
    2907                 :       2178 :           res = get_name (decl);
    2908                 :       3586 :           temp = xasprintf ("%s_%u", res ? res : "", SSA_NAME_VERSION (decl));
    2909                 :            :         }
    2910                 :       2019 :       else if (HAS_DECL_ASSEMBLER_NAME_P (decl)
    2911                 :       2019 :                && DECL_ASSEMBLER_NAME_SET_P (decl))
    2912                 :       1056 :         res = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME_RAW (decl));
    2913                 :        963 :       else if (DECL_P (decl))
    2914                 :            :         {
    2915                 :        963 :           res = get_name (decl);
    2916                 :        963 :           if (!res)
    2917                 :          4 :             temp = xasprintf ("D.%u", DECL_UID (decl));
    2918                 :            :         }
    2919                 :            : 
    2920                 :       3238 :       if (temp)
    2921                 :            :         {
    2922                 :       2182 :           res = ggc_strdup (temp);
    2923                 :       2182 :           free (temp);
    2924                 :            :         }
    2925                 :            :     }
    2926                 :            : 
    2927                 :   61418100 :   return res;
    2928                 :            : }
    2929                 :            : 
    2930                 :            : /* Find the variable id for tree T in the map.
    2931                 :            :    If T doesn't exist in the map, create an entry for it and return it.  */
    2932                 :            : 
    2933                 :            : static varinfo_t
    2934                 :  148388000 : get_vi_for_tree (tree t)
    2935                 :            : {
    2936                 :  148388000 :   varinfo_t *slot = vi_for_tree->get (t);
    2937                 :   93149800 :   if (slot == NULL)
    2938                 :            :     {
    2939                 :   55237800 :       unsigned int id = create_variable_info_for (t, alias_get_name (t), false);
    2940                 :   55237800 :       return get_varinfo (id);
    2941                 :            :     }
    2942                 :            : 
    2943                 :   93149800 :   return *slot;
    2944                 :            : }
    2945                 :            : 
    2946                 :            : /* Get a scalar constraint expression for a new temporary variable.  */
    2947                 :            : 
    2948                 :            : static struct constraint_expr
    2949                 :    1440110 : new_scalar_tmp_constraint_exp (const char *name, bool add_id)
    2950                 :            : {
    2951                 :    1440110 :   struct constraint_expr tmp;
    2952                 :    1440110 :   varinfo_t vi;
    2953                 :            : 
    2954                 :    1440110 :   vi = new_var_info (NULL_TREE, name, add_id);
    2955                 :    1440110 :   vi->offset = 0;
    2956                 :    1440110 :   vi->size = -1;
    2957                 :    1440110 :   vi->fullsize = -1;
    2958                 :    1440110 :   vi->is_full_var = 1;
    2959                 :    1440110 :   vi->is_reg_var = 1;
    2960                 :            : 
    2961                 :    1440110 :   tmp.var = vi->id;
    2962                 :    1440110 :   tmp.type = SCALAR;
    2963                 :    1440110 :   tmp.offset = 0;
    2964                 :            : 
    2965                 :    1440110 :   return tmp;
    2966                 :            : }
    2967                 :            : 
    2968                 :            : /* Get a constraint expression vector from an SSA_VAR_P node.
    2969                 :            :    If address_p is true, the result will be taken its address of.  */
    2970                 :            : 
    2971                 :            : static void
    2972                 :  130929000 : get_constraint_for_ssa_var (tree t, vec<ce_s> *results, bool address_p)
    2973                 :            : {
    2974                 :  130929000 :   struct constraint_expr cexpr;
    2975                 :  130929000 :   varinfo_t vi;
    2976                 :            : 
    2977                 :            :   /* We allow FUNCTION_DECLs here even though it doesn't make much sense.  */
    2978                 :  130929000 :   gcc_assert (TREE_CODE (t) == SSA_NAME || DECL_P (t));
    2979                 :            : 
    2980                 :  130929000 :   if (TREE_CODE (t) == SSA_NAME
    2981                 :  130929000 :       && SSA_NAME_IS_DEFAULT_DEF (t))
    2982                 :            :     {
    2983                 :            :       /* For parameters, get at the points-to set for the actual parm
    2984                 :            :          decl.  */
    2985                 :    9545180 :       if (TREE_CODE (SSA_NAME_VAR (t)) == PARM_DECL
    2986                 :    9819130 :           || TREE_CODE (SSA_NAME_VAR (t)) == RESULT_DECL)
    2987                 :            :         {
    2988                 :    9370810 :           get_constraint_for_ssa_var (SSA_NAME_VAR (t), results, address_p);
    2989                 :   22267300 :           return;
    2990                 :            :         }
    2991                 :            :       /* For undefined SSA names return nothing.  */
    2992                 :     174371 :       else if (!ssa_defined_default_def_p (t))
    2993                 :            :         {
    2994                 :     174371 :           cexpr.var = nothing_id;
    2995                 :     174371 :           cexpr.type = SCALAR;
    2996                 :     174371 :           cexpr.offset = 0;
    2997                 :     174371 :           results->safe_push (cexpr);
    2998                 :     174371 :           return;
    2999                 :            :         }
    3000                 :            :     }
    3001                 :            : 
    3002                 :            :   /* For global variables resort to the alias target.  */
    3003                 :  142457000 :   if (VAR_P (t) && (TREE_STATIC (t) || DECL_EXTERNAL (t)))
    3004                 :            :     {
    3005                 :    6701270 :       varpool_node *node = varpool_node::get (t);
    3006                 :    6701270 :       if (node && node->alias && node->analyzed)
    3007                 :            :         {
    3008                 :       6174 :           node = node->ultimate_alias_target ();
    3009                 :            :           /* Canonicalize the PT uid of all aliases to the ultimate target.
    3010                 :            :              ???  Hopefully the set of aliases can't change in a way that
    3011                 :            :              changes the ultimate alias target.  */
    3012                 :      12348 :           gcc_assert ((! DECL_PT_UID_SET_P (node->decl)
    3013                 :            :                        || DECL_PT_UID (node->decl) == DECL_UID (node->decl))
    3014                 :            :                       && (! DECL_PT_UID_SET_P (t)
    3015                 :            :                           || DECL_PT_UID (t) == DECL_UID (node->decl)));
    3016                 :       6174 :           DECL_PT_UID (t) = DECL_UID (node->decl);
    3017                 :       6174 :           t = node->decl;
    3018                 :            :         }
    3019                 :            : 
    3020                 :            :       /* If this is decl may bind to NULL note that.  */
    3021                 :    6701270 :       if (address_p
    3022                 :    6701270 :           && (! node || ! node->nonzero_address ()))
    3023                 :            :         {
    3024                 :       4181 :           cexpr.var = nothing_id;
    3025                 :       4181 :           cexpr.type = SCALAR;
    3026                 :       4181 :           cexpr.offset = 0;
    3027                 :       4181 :           results->safe_push (cexpr);
    3028                 :            :         }
    3029                 :            :     }
    3030                 :            : 
    3031                 :  121384000 :   vi = get_vi_for_tree (t);
    3032                 :  121384000 :   cexpr.var = vi->id;
    3033                 :  121384000 :   cexpr.type = SCALAR;
    3034                 :  121384000 :   cexpr.offset = 0;
    3035                 :            : 
    3036                 :            :   /* If we are not taking the address of the constraint expr, add all
    3037                 :            :      sub-fiels of the variable as well.  */
    3038                 :  121384000 :   if (!address_p
    3039                 :   99296400 :       && !vi->is_full_var)
    3040                 :            :     {
    3041                 :   11745700 :       for (; vi; vi = vi_next (vi))
    3042                 :            :         {
    3043                 :    8394350 :           cexpr.var = vi->id;
    3044                 :    8394350 :           results->safe_push (cexpr);
    3045                 :            :         }
    3046                 :            :       return;
    3047                 :            :     }
    3048                 :            : 
    3049                 :  118033000 :   results->safe_push (cexpr);
    3050                 :            : }
    3051                 :            : 
    3052                 :            : /* Process constraint T, performing various simplifications and then
    3053                 :            :    adding it to our list of overall constraints.  */
    3054                 :            : 
    3055                 :            : static void
    3056                 :  133366000 : process_constraint (constraint_t t)
    3057                 :            : {
    3058                 :  133366000 :   struct constraint_expr rhs = t->rhs;
    3059                 :  133366000 :   struct constraint_expr lhs = t->lhs;
    3060                 :            : 
    3061                 :  266731000 :   gcc_assert (rhs.var < varmap.length ());
    3062                 :  133366000 :   gcc_assert (lhs.var < varmap.length ());
    3063                 :            : 
    3064                 :            :   /* If we didn't get any useful constraint from the lhs we get
    3065                 :            :      &ANYTHING as fallback from get_constraint_for.  Deal with
    3066                 :            :      it here by turning it into *ANYTHING.  */
    3067                 :  133366000 :   if (lhs.type == ADDRESSOF
    3068                 :  133366000 :       && lhs.var == anything_id)
    3069                 :          0 :     lhs.type = DEREF;
    3070                 :            : 
    3071                 :            :   /* ADDRESSOF on the lhs is invalid.  */
    3072                 :  133366000 :   gcc_assert (lhs.type != ADDRESSOF);
    3073                 :            : 
    3074                 :            :   /* We shouldn't add constraints from things that cannot have pointers.
    3075                 :            :      It's not completely trivial to avoid in the callers, so do it here.  */
    3076                 :  133366000 :   if (rhs.type != ADDRESSOF
    3077                 :  133366000 :       && !get_varinfo (rhs.var)->may_have_pointers)
    3078                 :  133366000 :     return;
    3079                 :            : 
    3080                 :            :   /* Likewise adding to the solution of a non-pointer var isn't useful.  */
    3081                 :  133115000 :   if (!get_varinfo (lhs.var)->may_have_pointers)
    3082                 :            :     return;
    3083                 :            : 
    3084                 :            :   /* This can happen in our IR with things like n->a = *p */
    3085                 :  133112000 :   if (rhs.type == DEREF && lhs.type == DEREF && rhs.var != anything_id)
    3086                 :            :     {
    3087                 :            :       /* Split into tmp = *rhs, *lhs = tmp */
    3088                 :     153489 :       struct constraint_expr tmplhs;
    3089                 :     153489 :       tmplhs = new_scalar_tmp_constraint_exp ("doubledereftmp", true);
    3090                 :     153489 :       process_constraint (new_constraint (tmplhs, rhs));
    3091                 :     153489 :       process_constraint (new_constraint (lhs, tmplhs));
    3092                 :            :     }
    3093                 :  132958000 :   else if ((rhs.type != SCALAR || rhs.offset != 0) && lhs.type == DEREF)
    3094                 :            :     {
    3095                 :            :       /* Split into tmp = &rhs, *lhs = tmp */
    3096                 :    1280160 :       struct constraint_expr tmplhs;
    3097                 :    1280160 :       tmplhs = new_scalar_tmp_constraint_exp ("derefaddrtmp", true);
    3098                 :    1280160 :       process_constraint (new_constraint (tmplhs, rhs));
    3099                 :    1280160 :       process_constraint (new_constraint (lhs, tmplhs));
    3100                 :            :     }
    3101                 :            :   else
    3102                 :            :     {
    3103                 :  131678000 :       gcc_assert (rhs.type != ADDRESSOF || rhs.offset == 0);
    3104                 :  131678000 :       constraints.safe_push (t);
    3105                 :            :     }
    3106                 :            : }
    3107                 :            : 
    3108                 :            : 
    3109                 :            : /* Return the position, in bits, of FIELD_DECL from the beginning of its
    3110                 :            :    structure.  */
    3111                 :            : 
    3112                 :            : static HOST_WIDE_INT
    3113                 :   28583400 : bitpos_of_field (const tree fdecl)
    3114                 :            : {
    3115                 :   28583400 :   if (!tree_fits_shwi_p (DECL_FIELD_OFFSET (fdecl))
    3116                 :   28583400 :       || !tree_fits_shwi_p (DECL_FIELD_BIT_OFFSET (fdecl)))
    3117                 :            :     return -1;
    3118                 :            : 
    3119                 :   28583400 :   return (tree_to_shwi (DECL_FIELD_OFFSET (fdecl)) * BITS_PER_UNIT
    3120                 :   28583400 :           + tree_to_shwi (DECL_FIELD_BIT_OFFSET (fdecl)));
    3121                 :            : }
    3122                 :            : 
    3123                 :            : 
    3124                 :            : /* Get constraint expressions for offsetting PTR by OFFSET.  Stores the
    3125                 :            :    resulting constraint expressions in *RESULTS.  */
    3126                 :            : 
    3127                 :            : static void
    3128                 :   23061100 : get_constraint_for_ptr_offset (tree ptr, tree offset,
    3129                 :            :                                vec<ce_s> *results)
    3130                 :            : {
    3131                 :   23061100 :   struct constraint_expr c;
    3132                 :   23061100 :   unsigned int j, n;
    3133                 :   23061100 :   HOST_WIDE_INT rhsoffset;
    3134                 :            : 
    3135                 :            :   /* If we do not do field-sensitive PTA adding offsets to pointers
    3136                 :            :      does not change the points-to solution.  */
    3137                 :   23061100 :   if (!use_field_sensitive)
    3138                 :            :     {
    3139                 :    1084040 :       get_constraint_for_rhs (ptr, results);
    3140                 :    1084040 :       return;
    3141                 :            :     }
    3142                 :            : 
    3143                 :            :   /* If the offset is not a non-negative integer constant that fits
    3144                 :            :      in a HOST_WIDE_INT, we have to fall back to a conservative
    3145                 :            :      solution which includes all sub-fields of all pointed-to
    3146                 :            :      variables of ptr.  */
    3147                 :   21977100 :   if (offset == NULL_TREE
    3148                 :    7274800 :       || TREE_CODE (offset) != INTEGER_CST)
    3149                 :            :     rhsoffset = UNKNOWN_OFFSET;
    3150                 :            :   else
    3151                 :            :     {
    3152                 :            :       /* Sign-extend the offset.  */
    3153                 :    6212120 :       offset_int soffset = offset_int::from (wi::to_wide (offset), SIGNED);
    3154                 :    6212120 :       if (!wi::fits_shwi_p (soffset))
    3155                 :            :         rhsoffset = UNKNOWN_OFFSET;
    3156                 :            :       else
    3157                 :            :         {
    3158                 :            :           /* Make sure the bit-offset also fits.  */
    3159                 :    6212120 :           HOST_WIDE_INT rhsunitoffset = soffset.to_shwi ();
    3160                 :    6212120 :           rhsoffset = rhsunitoffset * (unsigned HOST_WIDE_INT) BITS_PER_UNIT;
    3161                 :    6212120 :           if (rhsunitoffset != rhsoffset / BITS_PER_UNIT)
    3162                 :        246 :             rhsoffset = UNKNOWN_OFFSET;
    3163                 :            :         }
    3164                 :            :     }
    3165                 :            : 
    3166                 :   21977100 :   get_constraint_for_rhs (ptr, results);
    3167                 :   21977100 :   if (rhsoffset == 0)
    3168                 :            :     return;
    3169                 :            : 
    3170                 :            :   /* As we are eventually appending to the solution do not use
    3171                 :            :      vec::iterate here.  */
    3172                 :   18669500 :   n = results->length ();
    3173                 :   37339500 :   for (j = 0; j < n; j++)
    3174                 :            :     {
    3175                 :   18669900 :       varinfo_t curr;
    3176                 :   18669900 :       c = (*results)[j];
    3177                 :   18669900 :       curr = get_varinfo (c.var);
    3178                 :            : 
    3179                 :   18669900 :       if (c.type == ADDRESSOF
    3180                 :            :           /* If this varinfo represents a full variable just use it.  */
    3181                 :    5974990 :           && curr->is_full_var)
    3182                 :            :         ;
    3183                 :   13713600 :       else if (c.type == ADDRESSOF
    3184                 :            :                /* If we do not know the offset add all subfields.  */
    3185                 :    1018620 :                && rhsoffset == UNKNOWN_OFFSET)
    3186                 :            :         {
    3187                 :       7770 :           varinfo_t temp = get_varinfo (curr->head);
    3188                 :      49424 :           do
    3189                 :            :             {
    3190                 :      49424 :               struct constraint_expr c2;
    3191                 :      49424 :               c2.var = temp->id;
    3192                 :      49424 :               c2.type = ADDRESSOF;
    3193                 :      49424 :               c2.offset = 0;
    3194                 :      49424 :               if (c2.var != c.var)
    3195                 :      41654 :                 results->safe_push (c2);
    3196                 :      49424 :               temp = vi_next (temp);
    3197                 :            :             }
    3198                 :      49424 :           while (temp);
    3199                 :            :         }
    3200                 :   13705800 :       else if (c.type == ADDRESSOF)
    3201                 :            :         {
    3202                 :    1010860 :           varinfo_t temp;
    3203                 :    1010860 :           unsigned HOST_WIDE_INT offset = curr->offset + rhsoffset;
    3204                 :            : 
    3205                 :            :           /* If curr->offset + rhsoffset is less than zero adjust it.  */
    3206                 :    1010860 :           if (rhsoffset < 0
    3207                 :          0 :               && curr->offset < offset)
    3208                 :          0 :             offset = 0;
    3209                 :            : 
    3210                 :            :           /* We have to include all fields that overlap the current
    3211                 :            :              field shifted by rhsoffset.  And we include at least
    3212                 :            :              the last or the first field of the variable to represent
    3213                 :            :              reachability of off-bound addresses, in particular &object + 1,
    3214                 :            :              conservatively correct.  */
    3215                 :    1010860 :           temp = first_or_preceding_vi_for_offset (curr, offset);
    3216                 :    1010860 :           c.var = temp->id;
    3217                 :    1010860 :           c.offset = 0;
    3218                 :    1010860 :           temp = vi_next (temp);
    3219                 :    1055600 :           while (temp
    3220                 :    1055600 :                  && temp->offset < offset + curr->size)
    3221                 :            :             {
    3222                 :      44743 :               struct constraint_expr c2;
    3223                 :      44743 :               c2.var = temp->id;
    3224                 :      44743 :               c2.type = ADDRESSOF;
    3225                 :      44743 :               c2.offset = 0;
    3226                 :      44743 :               results->safe_push (c2);
    3227                 :      44743 :               temp = vi_next (temp);
    3228                 :            :             }
    3229                 :            :         }
    3230                 :   12694900 :       else if (c.type == SCALAR)
    3231                 :            :         {
    3232                 :   12694900 :           gcc_assert (c.offset == 0);
    3233                 :            :           c.offset = rhsoffset;
    3234                 :            :         }
    3235                 :            :       else
    3236                 :            :         /* We shouldn't get any DEREFs here.  */
    3237                 :          0 :         gcc_unreachable ();
    3238                 :            : 
    3239                 :   18669900 :       (*results)[j] = c;
    3240                 :            :     }
    3241                 :            : }
    3242                 :            : 
    3243                 :            : 
    3244                 :            : /* Given a COMPONENT_REF T, return the constraint_expr vector for it.
    3245                 :            :    If address_p is true the result will be taken its address of.
    3246                 :            :    If lhs_p is true then the constraint expression is assumed to be used
    3247                 :            :    as the lhs.  */
    3248                 :            : 
    3249                 :            : static void
    3250                 :   21810700 : get_constraint_for_component_ref (tree t, vec<ce_s> *results,
    3251                 :            :                                   bool address_p, bool lhs_p)
    3252                 :            : {
    3253                 :   21810700 :   tree orig_t = t;
    3254                 :   21810700 :   poly_int64 bitsize = -1;
    3255                 :   21810700 :   poly_int64 bitmaxsize = -1;
    3256                 :   21810700 :   poly_int64 bitpos;
    3257                 :   21810700 :   bool reverse;
    3258                 :   21810700 :   tree forzero;
    3259                 :            : 
    3260                 :            :   /* Some people like to do cute things like take the address of
    3261                 :            :      &0->a.b */
    3262                 :   21810700 :   forzero = t;
    3263                 :  134836000 :   while (handled_component_p (forzero)
    3264                 :   31403700 :          || INDIRECT_REF_P (forzero)
    3265                 :   94025100 :          || TREE_CODE (forzero) == MEM_REF)
    3266                 :   40810700 :     forzero = TREE_OPERAND (forzero, 0);
    3267                 :            : 
    3268                 :   21810700 :   if (CONSTANT_CLASS_P (forzero) && integer_zerop (forzero))
    3269                 :            :     {
    3270                 :       1774 :       struct constraint_expr temp;
    3271                 :            : 
    3272                 :       1774 :       temp.offset = 0;
    3273                 :       1774 :       temp.var = integer_id;
    3274                 :       1774 :       temp.type = SCALAR;
    3275                 :       1774 :       results->safe_push (temp);
    3276                 :       1774 :       return;
    3277                 :            :     }
    3278                 :            : 
    3279                 :   21809000 :   t = get_ref_base_and_extent (t, &bitpos, &bitsize, &bitmaxsize, &reverse);
    3280                 :            : 
    3281                 :            :   /* We can end up here for component references on a
    3282                 :            :      VIEW_CONVERT_EXPR <>(&foobar) or things like a
    3283                 :            :      BIT_FIELD_REF <&MEM[(void *)&b + 4B], ...>.  So for
    3284                 :            :      symbolic constants simply give up.  */
    3285                 :   21809000 :   if (TREE_CODE (t) == ADDR_EXPR)
    3286                 :            :     {
    3287                 :         10 :       constraint_expr result;
    3288                 :         10 :       result.type = SCALAR;
    3289                 :         10 :       result.var = anything_id;
    3290                 :         10 :       result.offset = 0;
    3291                 :         10 :       results->safe_push (result);
    3292                 :         10 :       return;
    3293                 :            :     }
    3294                 :            : 
    3295                 :            :   /* Avoid creating pointer-offset constraints, so handle MEM_REF
    3296                 :            :      offsets directly.  Pretend to take the address of the base,
    3297                 :            :      we'll take care of adding the required subset of sub-fields below.  */
    3298                 :   21808900 :   if (TREE_CODE (t) == MEM_REF
    3299                 :   21808900 :       && !integer_zerop (TREE_OPERAND (t, 0)))
    3300                 :            :     {
    3301                 :    7904640 :       poly_offset_int off = mem_ref_offset (t);
    3302                 :    7904640 :       off <<= LOG2_BITS_PER_UNIT;
    3303                 :    7904640 :       off += bitpos;
    3304                 :    7904640 :       poly_int64 off_hwi;
    3305                 :    7904640 :       if (off.to_shwi (&off_hwi))
    3306                 :    7904630 :         bitpos = off_hwi;
    3307                 :            :       else
    3308                 :            :         {
    3309                 :         15 :           bitpos = 0;
    3310                 :         15 :           bitmaxsize = -1;
    3311                 :            :         }
    3312                 :    7904640 :       get_constraint_for_1 (TREE_OPERAND (t, 0), results, false, lhs_p);
    3313                 :    7904640 :       do_deref (results);
    3314                 :            :     }
    3315                 :            :   else
    3316                 :   13904300 :     get_constraint_for_1 (t, results, true, lhs_p);
    3317                 :            : 
    3318                 :            :   /* Strip off nothing_id.  */
    3319                 :   21808900 :   if (results->length () == 2)
    3320                 :            :     {
    3321                 :       1345 :       gcc_assert ((*results)[0].var == nothing_id);
    3322                 :       1345 :       results->unordered_remove (0);
    3323                 :            :     }
    3324                 :   21808900 :   gcc_assert (results->length () == 1);
    3325                 :   21808900 :   struct constraint_expr &result = results->last ();
    3326                 :            : 
    3327                 :   21808900 :   if (result.type == SCALAR
    3328                 :   21808900 :       && get_varinfo (result.var)->is_full_var)
    3329                 :            :     /* For single-field vars do not bother about the offset.  */
    3330                 :    5508640 :     result.offset = 0;
    3331                 :   16300300 :   else if (result.type == SCALAR)
    3332                 :            :     {
    3333                 :            :       /* In languages like C, you can access one past the end of an
    3334                 :            :          array.  You aren't allowed to dereference it, so we can
    3335                 :            :          ignore this constraint. When we handle pointer subtraction,
    3336                 :            :          we may have to do something cute here.  */
    3337                 :            : 
    3338                 :    8395780 :       if (maybe_lt (poly_uint64 (bitpos), get_varinfo (result.var)->fullsize)
    3339                 :    8395780 :           && maybe_ne (bitmaxsize, 0))
    3340                 :            :         {
    3341                 :            :           /* It's also not true that the constraint will actually start at the
    3342                 :            :              right offset, it may start in some padding.  We only care about
    3343                 :            :              setting the constraint to the first actual field it touches, so
    3344                 :            :              walk to find it.  */
    3345                 :    8395730 :           struct constraint_expr cexpr = result;
    3346                 :    8395730 :           varinfo_t curr;
    3347                 :    8395730 :           results->pop ();
    3348                 :    8395730 :           cexpr.offset = 0;
    3349                 :   47309300 :           for (curr = get_varinfo (cexpr.var); curr; curr = vi_next (curr))
    3350                 :            :             {
    3351                 :   39271700 :               if (ranges_maybe_overlap_p (poly_int64 (curr->offset),
    3352                 :   39271700 :                                           curr->size, bitpos, bitmaxsize))
    3353                 :            :                 {
    3354                 :    8511390 :                   cexpr.var = curr->id;
    3355                 :    8511390 :                   results->safe_push (cexpr);
    3356                 :    8511390 :                   if (address_p)
    3357                 :            :                     break;
    3358                 :            :                 }
    3359                 :            :             }
    3360                 :            :           /* If we are going to take the address of this field then
    3361                 :            :              to be able to compute reachability correctly add at least
    3362                 :            :              the last field of the variable.  */
    3363                 :    8395730 :           if (address_p && results->length () == 0)
    3364                 :            :             {
    3365                 :         12 :               curr = get_varinfo (cexpr.var);
    3366                 :         32 :               while (curr->next != 0)
    3367                 :         20 :                 curr = vi_next (curr);
    3368                 :         12 :               cexpr.var = curr->id;
    3369                 :         12 :               results->safe_push (cexpr);
    3370                 :            :             }
    3371                 :    8395720 :           else if (results->length () == 0)
    3372                 :            :             /* Assert that we found *some* field there. The user couldn't be
    3373                 :            :                accessing *only* padding.  */
    3374                 :            :             /* Still the user could access one past the end of an array
    3375                 :            :                embedded in a struct resulting in accessing *only* padding.  */
    3376                 :            :             /* Or accessing only padding via type-punning to a type
    3377                 :            :                that has a filed just in padding space.  */
    3378                 :            :             {
    3379                 :         18 :               cexpr.type = SCALAR;
    3380                 :         18 :               cexpr.var = anything_id;
    3381                 :         18 :               cexpr.offset = 0;
    3382                 :         18 :               results->safe_push (cexpr);
    3383                 :            :             }
    3384                 :            :         }
    3385                 :         55 :       else if (known_eq (bitmaxsize, 0))
    3386                 :            :         {
    3387                 :         13 :           if (dump_file && (dump_flags & TDF_DETAILS))
    3388                 :          0 :             fprintf (dump_file, "Access to zero-sized part of variable, "
    3389                 :            :                      "ignoring\n");
    3390                 :            :         }
    3391                 :            :       else
    3392                 :         42 :         if (dump_file && (dump_flags & TDF_DETAILS))
    3393                 :          0 :           fprintf (dump_file, "Access to past the end of variable, ignoring\n");
    3394                 :            :     }
    3395                 :    7904520 :   else if (result.type == DEREF)
    3396                 :            :     {
    3397                 :            :       /* If we do not know exactly where the access goes say so.  Note
    3398                 :            :          that only for non-structure accesses we know that we access
    3399                 :            :          at most one subfiled of any variable.  */
    3400                 :    7904490 :       HOST_WIDE_INT const_bitpos;
    3401                 :    7904490 :       if (!bitpos.is_constant (&const_bitpos)
    3402                 :    7904490 :           || const_bitpos == -1
    3403                 :    7904490 :           || maybe_ne (bitsize, bitmaxsize)
    3404                 :    7438880 :           || AGGREGATE_TYPE_P (TREE_TYPE (orig_t))
    3405                 :    6320630 :           || result.offset == UNKNOWN_OFFSET)
    3406                 :    1583860 :         result.offset = UNKNOWN_OFFSET;
    3407                 :            :       else
    3408                 :    6320630 :         result.offset += const_bitpos;
    3409                 :            :     }
    3410                 :         33 :   else if (result.type == ADDRESSOF)
    3411                 :            :     {
    3412                 :            :       /* We can end up here for component references on constants like
    3413                 :            :          VIEW_CONVERT_EXPR <>({ 0, 1, 2, 3 })[i].  */
    3414                 :         33 :       result.type = SCALAR;
    3415                 :         33 :       result.var = anything_id;
    3416                 :         33 :       result.offset = 0;
    3417                 :            :     }
    3418                 :            :   else
    3419                 :          0 :     gcc_unreachable ();
    3420                 :            : }
    3421                 :            : 
    3422                 :            : 
    3423                 :            : /* Dereference the constraint expression CONS, and return the result.
    3424                 :            :    DEREF (ADDRESSOF) = SCALAR
    3425                 :            :    DEREF (SCALAR) = DEREF
    3426                 :            :    DEREF (DEREF) = (temp = DEREF1; result = DEREF(temp))
    3427                 :            :    This is needed so that we can handle dereferencing DEREF constraints.  */
    3428                 :            : 
    3429                 :            : static void
    3430                 :   14315900 : do_deref (vec<ce_s> *constraints)
    3431                 :            : {
    3432                 :   14315900 :   struct constraint_expr *c;
    3433                 :   14315900 :   unsigned int i = 0;
    3434                 :            : 
    3435                 :   28686100 :   FOR_EACH_VEC_ELT (*constraints, i, c)
    3436                 :            :     {
    3437                 :   14370200 :       if (c->type == SCALAR)
    3438                 :   11356900 :         c->type = DEREF;
    3439                 :    3013260 :       else if (c->type == ADDRESSOF)
    3440                 :    3013250 :         c->type = SCALAR;
    3441                 :          8 :       else if (c->type == DEREF)
    3442                 :            :         {
    3443                 :          8 :           struct constraint_expr tmplhs;
    3444                 :          8 :           tmplhs = new_scalar_tmp_constraint_exp ("dereftmp", true);
    3445                 :          8 :           process_constraint (new_constraint (tmplhs, *c));
    3446                 :          8 :           c->var = tmplhs.var;
    3447                 :            :         }
    3448                 :            :       else
    3449                 :          0 :         gcc_unreachable ();
    3450                 :            :     }
    3451                 :   14315900 : }
    3452                 :            : 
    3453                 :            : /* Given a tree T, return the constraint expression for taking the
    3454                 :            :    address of it.  */
    3455                 :            : 
    3456                 :            : static void
    3457                 :   13023700 : get_constraint_for_address_of (tree t, vec<ce_s> *results)
    3458                 :            : {
    3459                 :   13023700 :   struct constraint_expr *c;
    3460                 :   13023700 :   unsigned int i;
    3461                 :            : 
    3462                 :   13023700 :   get_constraint_for_1 (t, results, true, true);
    3463                 :            : 
    3464                 :   26051200 :   FOR_EACH_VEC_ELT (*results, i, c)
    3465                 :            :     {
    3466                 :   13027600 :       if (c->type == DEREF)
    3467                 :    1182420 :         c->type = SCALAR;
    3468                 :            :       else
    3469                 :   11845100 :         c->type = ADDRESSOF;
    3470                 :            :     }
    3471                 :   13023700 : }
    3472                 :            : 
    3473                 :            : /* Given a tree T, return the constraint expression for it.  */
    3474                 :            : 
    3475                 :            : static void
    3476                 :  183831000 : get_constraint_for_1 (tree t, vec<ce_s> *results, bool address_p,
    3477                 :            :                       bool lhs_p)
    3478                 :            : {
    3479                 :  183831000 :   struct constraint_expr temp;
    3480                 :            : 
    3481                 :            :   /* x = integer is all glommed to a single variable, which doesn't
    3482                 :            :      point to anything by itself.  That is, of course, unless it is an
    3483                 :            :      integer constant being treated as a pointer, in which case, we
    3484                 :            :      will return that this is really the addressof anything.  This
    3485                 :            :      happens below, since it will fall into the default case. The only
    3486                 :            :      case we know something about an integer treated like a pointer is
    3487                 :            :      when it is the NULL pointer, and then we just say it points to
    3488                 :            :      NULL.
    3489                 :            : 
    3490                 :            :      Do not do that if -fno-delete-null-pointer-checks though, because
    3491                 :            :      in that case *NULL does not fail, so it _should_ alias *anything.
    3492                 :            :      It is not worth adding a new option or renaming the existing one,
    3493                 :            :      since this case is relatively obscure.  */
    3494                 :  183831000 :   if ((TREE_CODE (t) == INTEGER_CST
    3495                 :   17574900 :        && integer_zerop (t))
    3496                 :            :       /* The only valid CONSTRUCTORs in gimple with pointer typed
    3497                 :            :          elements are zero-initializer.  But in IPA mode we also
    3498                 :            :          process global initializers, so verify at least.  */
    3499                 :  195823000 :       || (TREE_CODE (t) == CONSTRUCTOR
    3500                 :     283574 :           && CONSTRUCTOR_NELTS (t) == 0))
    3501                 :            :     {
    3502                 :    5858240 :       if (flag_delete_null_pointer_checks)
    3503                 :    5844000 :         temp.var = nothing_id;
    3504                 :            :       else
    3505                 :      14237 :         temp.var = nonlocal_id;
    3506                 :    5858240 :       temp.type = ADDRESSOF;
    3507                 :    5858240 :       temp.offset = 0;
    3508                 :    5858240 :       results->safe_push (temp);
    3509                 :  189665000 :       return;
    3510                 :            :     }
    3511                 :            : 
    3512                 :            :   /* String constants are read-only, ideally we'd have a CONST_DECL
    3513                 :            :      for those.  */
    3514                 :  177973000 :   if (TREE_CODE (t) == STRING_CST)
    3515                 :            :     {
    3516                 :    2238570 :       temp.var = string_id;
    3517                 :    2238570 :       temp.type = SCALAR;
    3518                 :    2238570 :       temp.offset = 0;
    3519                 :    2238570 :       results->safe_push (temp);
    3520                 :    2238570 :       return;
    3521                 :            :     }
    3522                 :            : 
    3523                 :  175734000 :   switch (TREE_CODE_CLASS (TREE_CODE (t)))
    3524                 :            :     {
    3525                 :   12891700 :     case tcc_expression:
    3526                 :   12891700 :       {
    3527                 :   12891700 :         switch (TREE_CODE (t))
    3528                 :            :           {
    3529                 :   12873200 :           case ADDR_EXPR:
    3530                 :   12873200 :             get_constraint_for_address_of (TREE_OPERAND (t, 0), results);
    3531                 :   12873200 :             return;
    3532                 :            :           default:;
    3533                 :            :           }
    3534                 :            :         break;
    3535                 :            :       }
    3536                 :   28445300 :     case tcc_reference:
    3537                 :   28445300 :       {
    3538                 :   28445300 :         switch (TREE_CODE (t))
    3539                 :            :           {
    3540                 :    6016450 :           case MEM_REF:
    3541                 :    6016450 :             {
    3542                 :    6016450 :               struct constraint_expr cs;
    3543                 :    6016450 :               varinfo_t vi, curr;
    3544                 :    6016450 :               get_constraint_for_ptr_offset (TREE_OPERAND (t, 0),
    3545                 :    6016450 :                                              TREE_OPERAND (t, 1), results);
    3546                 :    6016450 :               do_deref (results);
    3547                 :            : 
    3548                 :            :               /* If we are not taking the address then make sure to process
    3549                 :            :                  all subvariables we might access.  */
    3550                 :    6016450 :               if (address_p)
    3551                 :            :                 return;
    3552                 :            : 
    3553                 :    5645030 :               cs = results->last ();
    3554                 :    5645030 :               if (cs.type == DEREF
    3555                 :    5645030 :                   && type_can_have_subvars (TREE_TYPE (t)))
    3556                 :            :                 {
    3557                 :            :                   /* For dereferences this means we have to defer it
    3558                 :            :                      to solving time.  */
    3559                 :     418035 :                   results->last ().offset = UNKNOWN_OFFSET;
    3560                 :     418035 :                   return;
    3561                 :            :                 }
    3562                 :    5227000 :               if (cs.type != SCALAR)
    3563                 :            :                 return;
    3564                 :            : 
    3565                 :    2503220 :               vi = get_varinfo (cs.var);
    3566                 :    2503220 :               curr = vi_next (vi);
    3567                 :    2503220 :               if (!vi->is_full_var
    3568                 :    1832790 :                   && curr)
    3569                 :            :                 {
    3570                 :    1294830 :                   unsigned HOST_WIDE_INT size;
    3571                 :    1294830 :                   if (tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (t))))
    3572                 :    1294830 :                     size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (t)));
    3573                 :            :                   else
    3574                 :    1294830 :                     size = -1;
    3575                 :    1370720 :                   for (; curr; curr = vi_next (curr))
    3576                 :            :                     {
    3577                 :    1357930 :                       if (curr->offset - vi->offset < size)
    3578                 :            :                         {
    3579                 :      75897 :                           cs.var = curr->id;
    3580                 :      75897 :                           results->safe_push (cs);
    3581                 :            :                         }
    3582                 :            :                       else
    3583                 :            :                         break;
    3584                 :            :                     }
    3585                 :            :                 }
    3586                 :            :               return;
    3587                 :            :             }
    3588                 :   21810700 :           case ARRAY_REF:
    3589                 :   21810700 :           case ARRAY_RANGE_REF:
    3590                 :   21810700 :           case COMPONENT_REF:
    3591                 :   21810700 :           case IMAGPART_EXPR:
    3592                 :   21810700 :           case REALPART_EXPR:
    3593                 :   21810700 :           case BIT_FIELD_REF:
    3594                 :   21810700 :             get_constraint_for_component_ref (t, results, address_p, lhs_p);
    3595                 :   21810700 :             return;
    3596                 :     618166 :           case VIEW_CONVERT_EXPR:
    3597                 :     618166 :             get_constraint_for_1 (TREE_OPERAND (t, 0), results, address_p,
    3598                 :            :                                   lhs_p);
    3599                 :     618166 :             return;
    3600                 :            :           /* We are missing handling for TARGET_MEM_REF here.  */
    3601                 :            :           default:;
    3602                 :            :           }
    3603                 :            :         break;
    3604                 :            :       }
    3605                 :   92937600 :     case tcc_exceptional:
    3606                 :   92937600 :       {
    3607                 :   92937600 :         switch (TREE_CODE (t))
    3608                 :            :           {
    3609                 :   92929300 :           case SSA_NAME:
    3610                 :   92929300 :             {
    3611                 :   92929300 :               get_constraint_for_ssa_var (t, results, address_p);
    3612                 :   92929300 :               return;
    3613                 :            :             }
    3614                 :       8325 :           case CONSTRUCTOR:
    3615                 :       8325 :             {
    3616                 :       8325 :               unsigned int i;
    3617                 :       8325 :               tree val;
    3618                 :      16650 :               auto_vec<ce_s> tmp;
    3619                 :     145002 :               FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (t), i, val)
    3620                 :            :                 {
    3621                 :      64176 :                   struct constraint_expr *rhsp;
    3622                 :      64176 :                   unsigned j;
    3623                 :      64176 :                   get_constraint_for_1 (val, &tmp, address_p, lhs_p);
    3624                 :     128352 :                   FOR_EACH_VEC_ELT (tmp, j, rhsp)
    3625                 :      64176 :                     results->safe_push (*rhsp);
    3626                 :      64176 :                   tmp.truncate (0);
    3627                 :            :                 }
    3628                 :            :               /* We do not know whether the constructor was complete,
    3629                 :            :                  so technically we have to add &NOTHING or &ANYTHING
    3630                 :            :                  like we do for an empty constructor as well.  */
    3631                 :       8325 :               return;
    3632                 :            :             }
    3633                 :            :           default:;
    3634                 :            :           }
    3635                 :            :         break;
    3636                 :            :       }
    3637                 :   28629000 :     case tcc_declaration:
    3638                 :   28629000 :       {
    3639                 :   28629000 :         get_constraint_for_ssa_var (t, results, address_p);
    3640                 :   28629000 :         return;
    3641                 :            :       }
    3642                 :   12824900 :     case tcc_constant:
    3643                 :   12824900 :       {
    3644                 :            :         /* We cannot refer to automatic variables through constants.  */ 
    3645                 :   12824900 :         temp.type = ADDRESSOF;
    3646                 :   12824900 :         temp.var = nonlocal_id;
    3647                 :   12824900 :         temp.offset = 0;
    3648                 :   12824900 :         results->safe_push (temp);
    3649                 :   12824900 :         return;
    3650                 :            :       }
    3651                 :      24045 :     default:;
    3652                 :            :     }
    3653                 :            : 
    3654                 :            :   /* The default fallback is a constraint from anything.  */
    3655                 :      24045 :   temp.type = ADDRESSOF;
    3656                 :      24045 :   temp.var = anything_id;
    3657                 :      24045 :   temp.offset = 0;
    3658                 :      24045 :   results->safe_push (temp);
    3659                 :            : }
    3660                 :            : 
    3661                 :            : /* Given a gimple tree T, return the constraint expression vector for it.  */
    3662                 :            : 
    3663                 :            : static void
    3664                 :   57165800 : get_constraint_for (tree t, vec<ce_s> *results)
    3665                 :            : {
    3666                 :   57165800 :   gcc_assert (results->length () == 0);
    3667                 :            : 
    3668                 :   57165800 :   get_constraint_for_1 (t, results, false, true);
    3669                 :   57165800 : }
    3670                 :            : 
    3671                 :            : /* Given a gimple tree T, return the constraint expression vector for it
    3672                 :            :    to be used as the rhs of a constraint.  */
    3673                 :            : 
    3674                 :            : static void
    3675                 :   91150100 : get_constraint_for_rhs (tree t, vec<ce_s> *results)
    3676                 :            : {
    3677                 :   91150100 :   gcc_assert (results->length () == 0);
    3678                 :            : 
    3679                 :   91150100 :   get_constraint_for_1 (t, results, false, false);
    3680                 :   91150100 : }
    3681                 :            : 
    3682                 :            : 
    3683                 :            : /* Efficiently generates constraints from all entries in *RHSC to all
    3684                 :            :    entries in *LHSC.  */
    3685                 :            : 
    3686                 :            : static void
    3687                 :   60624200 : process_all_all_constraints (vec<ce_s> lhsc,
    3688                 :            :                              vec<ce_s> rhsc)
    3689                 :            : {
    3690                 :   60624200 :   struct constraint_expr *lhsp, *rhsp;
    3691                 :   60624200 :   unsigned i, j;
    3692                 :            : 
    3693                 :   60624200 :   if (lhsc.length () <= 1 || rhsc.length () <= 1)
    3694                 :            :     {
    3695                 :  184554000 :       FOR_EACH_VEC_ELT (lhsc, i, lhsp)
    3696                 :  193124000 :         FOR_EACH_VEC_ELT (rhsc, j, rhsp)
    3697                 :   69187700 :           process_constraint (new_constraint (*lhsp, *rhsp));
    3698                 :            :     }
    3699                 :            :   else
    3700                 :            :     {
    3701                 :       6452 :       struct constraint_expr tmp;
    3702                 :       6452 :       tmp = new_scalar_tmp_constraint_exp ("allalltmp", true);
    3703                 :      19366 :       FOR_EACH_VEC_ELT (rhsc, i, rhsp)
    3704                 :      12914 :         process_constraint (new_constraint (tmp, *rhsp));
    3705                 :      20900 :       FOR_EACH_VEC_ELT (lhsc, i, lhsp)
    3706                 :      14448 :         process_constraint (new_constraint (*lhsp, tmp));
    3707                 :            :     }
    3708                 :   60624200 : }
    3709                 :            : 
    3710                 :            : /* Handle aggregate copies by expanding into copies of the respective
    3711                 :            :    fields of the structures.  */
    3712                 :            : 
    3713                 :            : static void
    3714                 :    1743440 : do_structure_copy (tree lhsop, tree rhsop)
    3715                 :            : {
    3716                 :    1743440 :   struct constraint_expr *lhsp, *rhsp;
    3717                 :    3482850 :   auto_vec<ce_s> lhsc;
    3718                 :    1739410 :   auto_vec<ce_s> rhsc;
    3719                 :    1743440 :   unsigned j;
    3720                 :            : 
    3721                 :    1743440 :   get_constraint_for (lhsop, &lhsc);
    3722                 :    1743440 :   get_constraint_for_rhs (rhsop, &rhsc);
    3723                 :    1743440 :   lhsp = &lhsc[0];
    3724                 :    1743440 :   rhsp = &rhsc[0];
    3725                 :    1743440 :   if (lhsp->type == DEREF
    3726                 :    1315230 :       || (lhsp->type == ADDRESSOF && lhsp->var == anything_id)
    3727                 :    1315230 :       || rhsp->type == DEREF)
    3728                 :            :     {
    3729                 :     729753 :       if (lhsp->type == DEREF)
    3730                 :            :         {
    3731                 :     428212 :           gcc_assert (lhsc.length () == 1);
    3732                 :     428212 :           lhsp->offset = UNKNOWN_OFFSET;
    3733                 :            :         }
    3734                 :     729753 :       if (rhsp->type == DEREF)
    3735                 :            :         {
    3736                 :     364561 :           gcc_assert (rhsc.length () == 1);
    3737                 :     364561 :           rhsp->offset = UNKNOWN_OFFSET;
    3738                 :            :         }
    3739                 :     729753 :       process_all_all_constraints (lhsc, rhsc);
    3740                 :            :     }
    3741                 :    1013690 :   else if (lhsp->type == SCALAR
    3742                 :    1013690 :            && (rhsp->type == SCALAR
    3743                 :     234091 :                || rhsp->type == ADDRESSOF))
    3744                 :            :     {
    3745                 :    1013690 :       HOST_WIDE_INT lhssize, lhsoffset;
    3746                 :    1013690 :       HOST_WIDE_INT rhssize, rhsoffset;
    3747                 :    1013690 :       bool reverse;
    3748                 :    1013690 :       unsigned k = 0;
    3749                 :    1013690 :       if (!get_ref_base_and_extent_hwi (lhsop, &lhsoffset, &lhssize, &reverse)
    3750                 :    1013690 :           || !get_ref_base_and_extent_hwi (rhsop, &rhsoffset, &rhssize,
    3751                 :            :                                            &reverse))
    3752                 :            :         {
    3753                 :       4038 :           process_all_all_constraints (lhsc, rhsc);
    3754                 :       4038 :           return;
    3755                 :            :         }
    3756                 :    4128150 :       for (j = 0; lhsc.iterate (j, &lhsp);)
    3757                 :            :         {
    3758                 :    3161680 :           varinfo_t lhsv, rhsv;
    3759                 :    3161680 :           rhsp = &rhsc[k];
    3760                 :    3161680 :           lhsv = get_varinfo (lhsp->var);
    3761                 :    3161680 :           rhsv = get_varinfo (rhsp->var);
    3762                 :    3161680 :           if (lhsv->may_have_pointers
    3763                 :    6323350 :               && (lhsv->is_full_var
    3764                 :    3161680 :                   || rhsv->is_full_var
    3765                 :    7717670 :                   || ranges_overlap_p (lhsv->offset + rhsoffset, lhsv->size,
    3766                 :    5404240 :                                        rhsv->offset + lhsoffset, rhsv->size)))
    3767                 :    2313430 :             process_constraint (new_constraint (*lhsp, *rhsp));
    3768                 :    3161680 :           if (!rhsv->is_full_var
    3769                 :    2362750 :               && (lhsv->is_full_var
    3770                 :    2242560 :                   || (lhsv->offset + rhsoffset + lhsv->size
    3771                 :    2362750 :                       > rhsv->offset + lhsoffset + rhsv->size)))
    3772                 :            :             {
    3773                 :     974169 :               ++k;
    3774                 :    1948340 :               if (k >= rhsc.length ())
    3775                 :            :                 break;
    3776                 :            :             }
    3777                 :            :           else
    3778                 :    2187510 :             ++j;
    3779                 :    1009650 :         }
    3780                 :            :     }
    3781                 :            :   else
    3782                 :          0 :     gcc_unreachable ();
    3783                 :            : }
    3784                 :            : 
    3785                 :            : /* Create constraints ID = { rhsc }.  */
    3786                 :            : 
    3787                 :            : static void
    3788                 :   21091000 : make_constraints_to (unsigned id, vec<ce_s> rhsc)
    3789                 :            : {
    3790                 :   21091000 :   struct constraint_expr *c;
    3791                 :   21091000 :   struct constraint_expr includes;
    3792                 :   21091000 :   unsigned int j;
    3793                 :            : 
    3794                 :   21091000 :   includes.var = id;
    3795                 :   21091000 :   includes.offset = 0;
    3796                 :   21091000 :   includes.type = SCALAR;
    3797                 :            : 
    3798                 :   43327600 :   FOR_EACH_VEC_ELT (rhsc, j, c)
    3799                 :   22236600 :     process_constraint (new_constraint (includes, *c));
    3800                 :   21091000 : }
    3801                 :            : 
    3802                 :            : /* Create a constraint ID = OP.  */
    3803                 :            : 
    3804                 :            : static void
    3805                 :   19818100 : make_constraint_to (unsigned id, tree op)
    3806                 :            : {
    3807                 :   19818100 :   auto_vec<ce_s> rhsc;
    3808                 :   19818100 :   get_constraint_for_rhs (op, &rhsc);
    3809                 :   19818100 :   make_constraints_to (id, rhsc);
    3810                 :   19818100 : }
    3811                 :            : 
    3812                 :            : /* Create a constraint ID = &FROM.  */
    3813                 :            : 
    3814                 :            : static void
    3815                 :    7651890 : make_constraint_from (varinfo_t vi, int from)
    3816                 :            : {
    3817                 :    7651890 :   struct constraint_expr lhs, rhs;
    3818                 :            : 
    3819                 :    7651890 :   lhs.var = vi->id;
    3820                 :    7651890 :   lhs.offset = 0;
    3821                 :    7651890 :   lhs.type = SCALAR;
    3822                 :            : 
    3823                 :    7651890 :   rhs.var = from;
    3824                 :    7651890 :   rhs.offset = 0;
    3825                 :    7651890 :   rhs.type = ADDRESSOF;
    3826                 :    7651890 :   process_constraint (new_constraint (lhs, rhs));
    3827                 :    7651890 : }
    3828                 :            : 
    3829                 :            : /* Create a constraint ID = FROM.  */
    3830                 :            : 
    3831                 :            : static void
    3832                 :    7756510 : make_copy_constraint (varinfo_t vi, int from)
    3833                 :            : {
    3834                 :    7756510 :   struct constraint_expr lhs, rhs;
    3835                 :            : 
    3836                 :    7756510 :   lhs.var = vi->id;
    3837                 :    7756510 :   lhs.offset = 0;
    3838                 :    7756510 :   lhs.type = SCALAR;
    3839                 :            : 
    3840                 :    7756510 :   rhs.var = from;
    3841                 :    7756510 :   rhs.offset = 0;
    3842                 :    7756510 :   rhs.type = SCALAR;
    3843                 :    7756510 :   process_constraint (new_constraint (lhs, rhs));
    3844                 :    7756510 : }
    3845                 :            : 
    3846                 :            : /* Make constraints necessary to make OP escape.  */
    3847                 :            : 
    3848                 :            : static void
    3849                 :   17880600 : make_escape_constraint (tree op)
    3850                 :            : {
    3851                 :      59238 :   make_constraint_to (escaped_id, op);
    3852                 :   17880600 : }
    3853                 :            : 
    3854                 :            : /* Add constraints to that the solution of VI is transitively closed.  */
    3855                 :            : 
    3856                 :            : static void
    3857                 :     749280 : make_transitive_closure_constraints (varinfo_t vi)
    3858                 :            : {
    3859                 :     749280 :   struct constraint_expr lhs, rhs;
    3860                 :            : 
    3861                 :            :   /* VAR = *(VAR + UNKNOWN);  */
    3862                 :     749280 :   lhs.type = SCALAR;
    3863                 :     749280 :   lhs.var = vi->id;
    3864                 :     749280 :   lhs.offset = 0;
    3865                 :     749280 :   rhs.type = DEREF;
    3866                 :     749280 :   rhs.var = vi->id;
    3867                 :     749280 :   rhs.offset = UNKNOWN_OFFSET;
    3868                 :     749280 :   process_constraint (new_constraint (lhs, rhs));
    3869                 :     749280 : }
    3870                 :            : 
    3871                 :            : /* Add constraints to that the solution of VI has all subvariables added.  */
    3872                 :            : 
    3873                 :            : static void
    3874                 :    1343620 : make_any_offset_constraints (varinfo_t vi)
    3875                 :            : {
    3876                 :    1343620 :   struct constraint_expr lhs, rhs;
    3877                 :            : 
    3878                 :            :   /* VAR = VAR + UNKNOWN;  */
    3879                 :    1343620 :   lhs.type = SCALAR;
    3880                 :    1343620 :   lhs.var = vi->id;
    3881                 :    1343620 :   lhs.offset = 0;
    3882                 :    1343620 :   rhs.type = SCALAR;
    3883                 :    1343620 :   rhs.var = vi->id;
    3884                 :    1343620 :   rhs.offset = UNKNOWN_OFFSET;
    3885                 :    1343620 :   process_constraint (new_constraint (lhs, rhs));
    3886                 :    1343620 : }
    3887                 :            : 
    3888                 :            : /* Temporary storage for fake var decls.  */
    3889                 :            : struct obstack fake_var_decl_obstack;
    3890                 :            : 
    3891                 :            : /* Build a fake VAR_DECL acting as referrer to a DECL_UID.  */
    3892                 :            : 
    3893                 :            : static tree
    3894                 :     624112 : build_fake_var_decl (tree type)
    3895                 :            : {
    3896                 :     624112 :   tree decl = (tree) XOBNEW (&fake_var_decl_obstack, struct tree_var_decl);
    3897                 :     624112 :   memset (decl, 0, sizeof (struct tree_var_decl));
    3898                 :     624112 :   TREE_SET_CODE (decl, VAR_DECL);
    3899                 :     624112 :   TREE_TYPE (decl) = type;
    3900                 :     624112 :   DECL_UID (decl) = allocate_decl_uid ();
    3901                 :     624112 :   SET_DECL_PT_UID (decl, -1);
    3902                 :     624112 :   layout_decl (decl, 0);
    3903                 :     624112 :   return decl;
    3904                 :            : }
    3905                 :            : 
    3906                 :            : /* Create a new artificial heap variable with NAME.
    3907                 :            :    Return the created variable.  */
    3908                 :            : 
    3909                 :            : static varinfo_t
    3910                 :     215796 : make_heapvar (const char *name, bool add_id)
    3911                 :            : {
    3912                 :     215796 :   varinfo_t vi;
    3913                 :     215796 :   tree heapvar;
    3914                 :            :   
    3915                 :     215796 :   heapvar = build_fake_var_decl (ptr_type_node);
    3916                 :     215796 :   DECL_EXTERNAL (heapvar) = 1;
    3917                 :            : 
    3918                 :     215796 :   vi = new_var_info (heapvar, name, add_id);
    3919                 :     215796 :   vi->is_heap_var = true;
    3920                 :     215796 :   vi->is_unknown_size_var = true;
    3921                 :     215796 :   vi->offset = 0;
    3922                 :     215796 :   vi->fullsize = ~0;
    3923                 :     215796 :   vi->size = ~0;
    3924                 :     215796 :   vi->is_full_var = true;
    3925                 :     215796 :   insert_vi_for_tree (heapvar, vi);
    3926                 :            : 
    3927                 :     215796 :   return vi;
    3928                 :            : }
    3929                 :            : 
    3930                 :            : /* Create a new artificial heap variable with NAME and make a
    3931                 :            :    constraint from it to LHS.  Set flags according to a tag used
    3932                 :            :    for tracking restrict pointers.  */
    3933                 :            : 
    3934                 :            : static varinfo_t
    3935                 :       5589 : make_constraint_from_restrict (varinfo_t lhs, const char *name, bool add_id)
    3936                 :            : {
    3937                 :       5589 :   varinfo_t vi = make_heapvar (name, add_id);
    3938                 :       5589 :   vi->is_restrict_var = 1;
    3939                 :       5589 :   vi->is_global_var = 1;
    3940                 :       5589 :   vi->may_have_pointers = 1;
    3941                 :       5589 :   make_constraint_from (lhs, vi->id);
    3942                 :       5589 :   return vi;
    3943                 :            : }
    3944                 :            : 
    3945                 :            : /* Create a new artificial heap variable with NAME and make a
    3946                 :            :    constraint from it to LHS.  Set flags according to a tag used
    3947                 :            :    for tracking restrict pointers and make the artificial heap
    3948                 :            :    point to global memory.  */
    3949                 :            : 
    3950                 :            : static varinfo_t
    3951                 :       5589 : make_constraint_from_global_restrict (varinfo_t lhs, const char *name,
    3952                 :            :                                       bool add_id)
    3953                 :            : {
    3954                 :          0 :   varinfo_t vi = make_constraint_from_restrict (lhs, name, add_id);
    3955                 :       5589 :   make_copy_constraint (vi, nonlocal_id);
    3956                 :       5589 :   return vi;
    3957                 :            : }
    3958                 :            : 
    3959                 :            : /* In IPA mode there are varinfos for different aspects of reach
    3960                 :            :    function designator.  One for the points-to set of the return
    3961                 :            :    value, one for the variables that are clobbered by the function,
    3962                 :            :    one for its uses and one for each parameter (including a single
    3963                 :            :    glob for remaining variadic arguments).  */
    3964                 :            : 
    3965                 :            : enum { fi_clobbers = 1, fi_uses = 2,
    3966                 :            :        fi_static_chain = 3, fi_result = 4, fi_parm_base = 5 };
    3967                 :            : 
    3968                 :            : /* Get a constraint for the requested part of a function designator FI
    3969                 :            :    when operating in IPA mode.  */
    3970                 :            : 
    3971                 :            : static struct constraint_expr
    3972                 :    1164220 : get_function_part_constraint (varinfo_t fi, unsigned part)
    3973                 :            : {
    3974                 :    1164220 :   struct constraint_expr c;
    3975                 :            : 
    3976                 :    1164220 :   gcc_assert (in_ipa_mode);
    3977                 :            : 
    3978                 :    1164220 :   if (fi->id == anything_id)
    3979                 :            :     {
    3980                 :            :       /* ???  We probably should have a ANYFN special variable.  */
    3981                 :            :       c.var = anything_id;
    3982                 :            :       c.offset = 0;
    3983                 :            :       c.type = SCALAR;
    3984                 :            :     }
    3985                 :     396607 :   else if (fi->decl && TREE_CODE (fi->decl) == FUNCTION_DECL)
    3986                 :            :     {
    3987                 :     392618 :       varinfo_t ai = first_vi_for_offset (fi, part);
    3988                 :     392618 :       if (ai)
    3989                 :     392618 :         c.var = ai->id;
    3990                 :            :       else
    3991                 :            :         c.var = anything_id;
    3992                 :            :       c.offset = 0;
    3993                 :            :       c.type = SCALAR;
    3994                 :            :     }
    3995                 :            :   else
    3996                 :            :     {
    3997                 :       3989 :       c.var = fi->id;
    3998                 :       3989 :       c.offset = part;
    3999                 :       3989 :       c.type = DEREF;
    4000                 :            :     }
    4001                 :            : 
    4002                 :    1164220 :   return c;
    4003                 :            : }
    4004                 :            : 
    4005                 :            : /* For non-IPA mode, generate constraints necessary for a call on the
    4006                 :            :    RHS.  */
    4007                 :            : 
    4008                 :            : static void
    4009                 :    9627420 : handle_rhs_call (gcall *stmt, vec<ce_s> *results)
    4010                 :            : {
    4011                 :    9627420 :   struct constraint_expr rhsc;
    4012                 :    9627420 :   unsigned i;
    4013                 :    9627420 :   bool returns_uses = false;
    4014                 :            : 
    4015                 :   27095100 :   for (i = 0; i < gimple_call_num_args (stmt); ++i)
    4016                 :            :     {
    4017                 :   17467700 :       tree arg = gimple_call_arg (stmt, i);
    4018                 :   17467700 :       int flags = gimple_call_arg_flags (stmt, i);
    4019                 :            : 
    4020                 :            :       /* If the argument is not used we can ignore it.  */
    4021                 :   17467700 :       if (flags & EAF_UNUSED)
    4022                 :          0 :         continue;
    4023                 :            : 
    4024                 :            :       /* As we compute ESCAPED context-insensitive we do not gain
    4025                 :            :          any precision with just EAF_NOCLOBBER but not EAF_NOESCAPE
    4026                 :            :          set.  The argument would still get clobbered through the
    4027                 :            :          escape solution.  */
    4028                 :   17467700 :       if ((flags & EAF_NOCLOBBER)
    4029                 :   17467700 :            && (flags & EAF_NOESCAPE))
    4030                 :            :         {
    4031                 :     467564 :           varinfo_t uses = get_call_use_vi (stmt);
    4032                 :     467564 :           varinfo_t tem = new_var_info (NULL_TREE, "callarg", true);
    4033                 :     467564 :           tem->is_reg_var = true;
    4034                 :     467564 :           make_constraint_to (tem->id, arg);
    4035                 :     467564 :           make_any_offset_constraints (tem);
    4036                 :     467564 :           if (!(flags & EAF_DIRECT))
    4037                 :     123547 :             make_transitive_closure_constraints (tem);
    4038                 :     467564 :           make_copy_constraint (uses, tem->id);
    4039                 :     467564 :           returns_uses = true;
    4040                 :            :         }
    4041                 :   17000100 :       else if (flags & EAF_NOESCAPE)
    4042                 :            :         {
    4043                 :     387431 :           struct constraint_expr lhs, rhs;
    4044                 :     387431 :           varinfo_t uses = get_call_use_vi (stmt);
    4045                 :     387431 :           varinfo_t clobbers = get_call_clobber_vi (stmt);
    4046                 :     387431 :           varinfo_t tem = new_var_info (NULL_TREE, "callarg", true);
    4047                 :     387431 :           tem->is_reg_var = true;
    4048                 :     387431 :           make_constraint_to (tem->id, arg);
    4049                 :     387431 :           make_any_offset_constraints (tem);
    4050                 :     387431 :           if (!(flags & EAF_DIRECT))
    4051                 :     350768 :             make_transitive_closure_constraints (tem);
    4052                 :     387431 :           make_copy_constraint (uses, tem->id);
    4053                 :     387431 :           make_copy_constraint (clobbers, tem->id);
    4054                 :            :           /* Add *tem = nonlocal, do not add *tem = callused as
    4055                 :            :              EAF_NOESCAPE parameters do not escape to other parameters
    4056                 :            :              and all other uses appear in NONLOCAL as well.  */
    4057                 :     387431 :           lhs.type = DEREF;
    4058                 :     387431 :           lhs.var = tem->id;
    4059                 :     387431 :           lhs.offset = 0;
    4060                 :     387431 :           rhs.type = SCALAR;
    4061                 :     387431 :           rhs.var = nonlocal_id;
    4062                 :     387431 :           rhs.offset = 0;
    4063                 :     387431 :           process_constraint (new_constraint (lhs, rhs));
    4064                 :     387431 :           returns_uses = true;
    4065                 :            :         }
    4066                 :            :       else
    4067                 :   34080300 :         make_escape_constraint (arg);
    4068                 :            :     }
    4069                 :            : 
    4070                 :            :   /* If we added to the calls uses solution make sure we account for
    4071                 :            :      pointers to it to be returned.  */
    4072                 :    9627420 :   if (returns_uses)
    4073                 :            :     {
    4074                 :     490646 :       rhsc.var = get_call_use_vi (stmt)->id;
    4075                 :     490646 :       rhsc.offset = UNKNOWN_OFFSET;
    4076                 :     490646 :       rhsc.type = SCALAR;
    4077                 :     490646 :       results->safe_push (rhsc);
    4078                 :            :     }
    4079                 :            : 
    4080                 :            :   /* The static chain escapes as well.  */
    4081                 :    9627420 :   if (gimple_call_chain (stmt))
    4082                 :      59238 :     make_escape_constraint (gimple_call_chain (stmt));
    4083                 :            : 
    4084                 :            :   /* And if we applied NRV the address of the return slot escapes as well.  */
    4085                 :    9627420 :   if (gimple_call_return_slot_opt_p (stmt)
    4086                 :     498199 :       && gimple_call_lhs (stmt) != NULL_TREE
    4087                 :   10125600 :       && TREE_ADDRESSABLE (TREE_TYPE (gimple_call_lhs (stmt))))
    4088                 :            :     {
    4089                 :      85120 :       auto_vec<ce_s> tmpc;
    4090                 :      42560 :       struct constraint_expr lhsc, *c;
    4091                 :      42560 :       get_constraint_for_address_of (gimple_call_lhs (stmt), &tmpc);
    4092                 :      42560 :       lhsc.var = escaped_id;
    4093                 :      42560 :       lhsc.offset = 0;
    4094                 :      42560 :       lhsc.type = SCALAR;
    4095                 :     127680 :       FOR_EACH_VEC_ELT (tmpc, i, c)
    4096                 :      42560 :         process_constraint (new_constraint (lhsc, *c));
    4097                 :            :     }
    4098                 :            : 
    4099                 :            :   /* Regular functions return nonlocal memory.  */
    4100                 :    9627420 :   rhsc.var = nonlocal_id;
    4101                 :    9627420 :   rhsc.offset = 0;
    4102                 :    9627420 :   rhsc.type = SCALAR;
    4103                 :    9627420 :   results->safe_push (rhsc);
    4104                 :    9627420 : }
    4105                 :            : 
    4106                 :            : /* For non-IPA mode, generate constraints necessary for a call
    4107                 :            :    that returns a pointer and assigns it to LHS.  This simply makes
    4108                 :            :    the LHS point to global and escaped variables.  */
    4109                 :            : 
    4110                 :            : static void
    4111                 :    4145310 : handle_lhs_call (gcall *stmt, tree lhs, int flags, vec<ce_s> rhsc,
    4112                 :            :                  tree fndecl)
    4113                 :            : {
    4114                 :    4145310 :   auto_vec<ce_s> lhsc;
    4115                 :            : 
    4116                 :    4145310 :   get_constraint_for (lhs, &lhsc);
    4117                 :            :   /* If the store is to a global decl make sure to
    4118                 :            :      add proper escape constraints.  */
    4119                 :    4145310 :   lhs = get_base_address (lhs);
    4120                 :    4145310 :   if (lhs
    4121                 :    4145310 :       && DECL_P (lhs)
    4122                 :    4892870 :       && is_global_var (lhs))
    4123                 :            :     {
    4124                 :        865 :       struct constraint_expr tmpc;
    4125                 :        865 :       tmpc.var = escaped_id;
    4126                 :        865 :       tmpc.offset = 0;
    4127                 :        865 :       tmpc.type = SCALAR;
    4128                 :        865 :       lhsc.safe_push (tmpc);
    4129                 :            :     }
    4130                 :            : 
    4131                 :            :   /* If the call returns an argument unmodified override the rhs
    4132                 :            :      constraints.  */
    4133                 :    4145310 :   if (flags & ERF_RETURNS_ARG
    4134                 :    4145310 :       && (flags & ERF_RETURN_ARG_MASK) < gimple_call_num_args (stmt))
    4135                 :            :     {
    4136                 :        141 :       tree arg;
    4137                 :        141 :       rhsc.create (0);
    4138                 :        141 :       arg = gimple_call_arg (stmt, flags & ERF_RETURN_ARG_MASK);
    4139                 :        141 :       get_constraint_for (arg, &rhsc);
    4140                 :        141 :       process_all_all_constraints (lhsc, rhsc);
    4141                 :    4145450 :       rhsc.release ();
    4142                 :            :     }
    4143                 :    4145170 :   else if (flags & ERF_NOALIAS)
    4144                 :            :     {
    4145                 :     185544 :       varinfo_t vi;
    4146                 :     185544 :       struct constraint_expr tmpc;
    4147                 :     185544 :       rhsc.create (0);
    4148                 :     185544 :       vi = make_heapvar ("HEAP", true);
    4149                 :            :       /* We are marking allocated storage local, we deal with it becoming
    4150                 :            :          global by escaping and setting of vars_contains_escaped_heap.  */
    4151                 :     185544 :       DECL_EXTERNAL (vi->decl) = 0;
    4152                 :     185544 :       vi->is_global_var = 0;
    4153                 :            :       /* If this is not a real malloc call assume the memory was
    4154                 :            :          initialized and thus may point to global memory.  All
    4155                 :            :          builtin functions with the malloc attribute behave in a sane way.  */
    4156                 :     185544 :       if (!fndecl
    4157                 :     185544 :           || !fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
    4158                 :     103444 :         make_constraint_from (vi, nonlocal_id);
    4159                 :     185544 :       tmpc.var = vi->id;
    4160                 :     185544 :       tmpc.offset = 0;
    4161                 :     185544 :       tmpc.type = ADDRESSOF;
    4162                 :     185544 :       rhsc.safe_push (tmpc);
    4163                 :     185544 :       process_all_all_constraints (lhsc, rhsc);
    4164                 :     371088 :       rhsc.release ();
    4165                 :            :     }
    4166                 :            :   else
    4167                 :    3959620 :     process_all_all_constraints (lhsc, rhsc);
    4168                 :    4145310 : }
    4169                 :            : 
    4170                 :            : /* For non-IPA mode, generate constraints necessary for a call of a
    4171                 :            :    const function that returns a pointer in the statement STMT.  */
    4172                 :            : 
    4173                 :            : static void
    4174                 :     658282 : handle_const_call (gcall *stmt, vec<ce_s> *results)
    4175                 :            : {
    4176                 :     658282 :   struct constraint_expr rhsc;
    4177                 :     658282 :   unsigned int k;
    4178                 :     658282 :   bool need_uses = false;
    4179                 :            : 
    4180                 :            :   /* Treat nested const functions the same as pure functions as far
    4181                 :            :      as the static chain is concerned.  */
    4182                 :     658282 :   if (gimple_call_chain (stmt))
    4183                 :            :     {
    4184                 :          2 :       varinfo_t uses = get_call_use_vi (stmt);
    4185                 :          2 :       make_constraint_to (uses->id, gimple_call_chain (stmt));
    4186                 :          2 :       need_uses = true;
    4187                 :            :     }
    4188                 :            : 
    4189                 :            :   /* And if we applied NRV the address of the return slot escapes as well.  */
    4190                 :     658282 :   if (gimple_call_return_slot_opt_p (stmt)
    4191                 :        747 :       && gimple_call_lhs (stmt) != NULL_TREE
    4192                 :     659029 :       && TREE_ADDRESSABLE (TREE_TYPE (gimple_call_lhs (stmt))))
    4193                 :            :     {
    4194                 :         46 :       varinfo_t uses = get_call_use_vi (stmt);
    4195                 :         46 :       auto_vec<ce_s> tmpc;
    4196                 :         46 :       get_constraint_for_address_of (gimple_call_lhs (stmt), &tmpc);
    4197                 :         46 :       make_constraints_to (uses->id, tmpc);
    4198                 :         46 :       need_uses = true;
    4199                 :            :     }
    4200                 :            : 
    4201                 :     658282 :   if (need_uses)
    4202                 :            :     {
    4203                 :         48 :       varinfo_t uses = get_call_use_vi (stmt);
    4204                 :         48 :       make_any_offset_constraints (uses);
    4205                 :         48 :       make_transitive_closure_constraints (uses);
    4206                 :         48 :       rhsc.var = uses->id;
    4207                 :         48 :       rhsc.offset = 0;
    4208                 :         48 :       rhsc.type = SCALAR;
    4209                 :         48 :       results->safe_push (rhsc);
    4210                 :            :     }
    4211                 :            : 
    4212                 :            :   /* May return offsetted arguments.  */
    4213                 :     658282 :   varinfo_t tem = NULL;
    4214                 :     658282 :   if (gimple_call_num_args (stmt) != 0)
    4215                 :            :     {
    4216                 :     551854 :       tem = new_var_info (NULL_TREE, "callarg", true);
    4217                 :     551854 :       tem->is_reg_var = true;
    4218                 :            :     }
    4219                 :    1931070 :   for (k = 0; k < gimple_call_num_args (stmt); ++k)
    4220                 :            :     {
    4221                 :    1272790 :       tree arg = gimple_call_arg (stmt, k);
    4222                 :    2545580 :       auto_vec<ce_s> argc;
    4223                 :    1272790 :       get_constraint_for_rhs (arg, &argc);
    4224                 :    1272790 :       make_constraints_to (tem->id, argc);
    4225                 :            :     }
    4226                 :     658282 :   if (tem)
    4227                 :            :     {
    4228                 :     551854 :       ce_s ce;
    4229                 :     551854 :       ce.type = SCALAR;
    4230                 :     551854 :       ce.var = tem->id;
    4231                 :     551854 :       ce.offset = UNKNOWN_OFFSET;
    4232                 :     551854 :       results->safe_push (ce);
    4233                 :            :     }
    4234                 :            : 
    4235                 :            :   /* May return addresses of globals.  */
    4236                 :     658282 :   rhsc.var = nonlocal_id;
    4237                 :     658282 :   rhsc.offset = 0;
    4238                 :     658282 :   rhsc.type = ADDRESSOF;
    4239                 :     658282 :   results->safe_push (rhsc);
    4240                 :     658282 : }
    4241                 :            : 
    4242                 :            : /* For non-IPA mode, generate constraints necessary for a call to a
    4243                 :            :    pure function in statement STMT.  */
    4244                 :            : 
    4245                 :            : static void
    4246                 :     322640 : handle_pure_call (gcall *stmt, vec<ce_s> *results)
    4247                 :            : {
    4248                 :     322640 :   struct constraint_expr rhsc;
    4249                 :     322640 :   unsigned i;
    4250                 :     322640 :   varinfo_t uses = NULL;
    4251                 :            : 
    4252                 :            :   /* Memory reached from pointer arguments is call-used.  */
    4253                 :     991216 :   for (i = 0; i < gimple_call_num_args (stmt); ++i)
    4254                 :            :     {
    4255                 :     668576 :       tree arg = gimple_call_arg (stmt, i);
    4256                 :     668576 :       if (!uses)
    4257                 :            :         {
    4258                 :     274645 :           uses = get_call_use_vi (stmt);
    4259                 :     274645 :           make_any_offset_constraints (uses);
    4260                 :     274645 :           make_transitive_closure_constraints (uses);
    4261                 :            :         }
    4262                 :     668576 :       make_constraint_to (uses->id, arg);
    4263                 :            :     }
    4264                 :            : 
    4265                 :            :   /* The static chain is used as well.  */
    4266                 :     322640 :   if (gimple_call_chain (stmt))
    4267                 :            :     {
    4268                 :        628 :       if (!uses)
    4269                 :            :         {
    4270                 :        272 :           uses = get_call_use_vi (stmt);
    4271                 :        272 :           make_any_offset_constraints (uses);
    4272                 :        272 :           make_transitive_closure_constraints (uses);
    4273                 :            :         }
    4274                 :        628 :       make_constraint_to (uses->id, gimple_call_chain (stmt));
    4275                 :            :     }
    4276                 :            : 
    4277                 :            :   /* And if we applied NRV the address of the return slot.  */
    4278                 :     322640 :   if (gimple_call_return_slot_opt_p (stmt)
    4279                 :        876 :       && gimple_call_lhs (stmt) != NULL_TREE
    4280                 :     323443 :       && TREE_ADDRESSABLE (TREE_TYPE (gimple_call_lhs (stmt))))
    4281                 :            :     {
    4282                 :         71 :       if (!uses)
    4283                 :            :         {
    4284                 :          0 :           uses = get_call_use_vi (stmt);
    4285                 :          0 :           make_any_offset_constraints (uses);
    4286                 :          0 :           make_transitive_closure_constraints (uses);
    4287                 :            :         }
    4288                 :        142 :       auto_vec<ce_s> tmpc;
    4289                 :         71 :       get_constraint_for_address_of (gimple_call_lhs (stmt), &tmpc);
    4290                 :         71 :       make_constraints_to (uses->id, tmpc);
    4291                 :            :     }
    4292                 :            : 
    4293                 :            :   /* Pure functions may return call-used and nonlocal memory.  */
    4294                 :     322640 :   if (uses)
    4295                 :            :     {
    4296                 :     274917 :       rhsc.var = uses->id;
    4297                 :     274917 :       rhsc.offset = 0;
    4298                 :     274917 :       rhsc.type = SCALAR;
    4299                 :     274917 :       results->safe_push (rhsc);
    4300                 :            :     }
    4301                 :     322640 :   rhsc.var = nonlocal_id;
    4302                 :     322640 :   rhsc.offset = 0;
    4303                 :     322640 :   rhsc.type = SCALAR;
    4304                 :     322640 :   results->safe_push (rhsc);
    4305                 :     322640 : }
    4306                 :            : 
    4307                 :            : 
    4308                 :            : /* Return the varinfo for the callee of CALL.  */
    4309                 :            : 
    4310                 :            : static varinfo_t
    4311                 :   11119700 : get_fi_for_callee (gcall *call)
    4312                 :            : {
    4313                 :   11119700 :   tree decl, fn = gimple_call_fn (call);
    4314                 :            : 
    4315                 :   11119700 :   if (fn && TREE_CODE (fn) == OBJ_TYPE_REF)
    4316                 :      88860 :     fn = OBJ_TYPE_REF_EXPR (fn);
    4317                 :            : 
    4318                 :            :   /* If we can directly resolve the function being called, do so.
    4319                 :            :      Otherwise, it must be some sort of indirect expression that
    4320                 :            :      we should still be able to handle.  */
    4321                 :   11119700 :   decl = gimple_call_addr_fndecl (fn);
    4322                 :   11119700 :   if (decl)
    4323                 :    9984280 :     return get_vi_for_tree (decl);
    4324                 :            : 
    4325                 :            :   /* If the function is anything other than a SSA name pointer we have no
    4326                 :            :      clue and should be getting ANYFN (well, ANYTHING for now).  */
    4327                 :    1135420 :   if (!fn || TREE_CODE (fn) != SSA_NAME)
    4328                 :     768424 :     return get_varinfo (anything_id);
    4329                 :            : 
    4330                 :     366998 :   if (SSA_NAME_IS_DEFAULT_DEF (fn)
    4331                 :      16068 :       && (TREE_CODE (SSA_NAME_VAR (fn)) == PARM_DECL
    4332                 :     367028 :           || TREE_CODE (SSA_NAME_VAR (fn)) == RESULT_DECL))
    4333                 :       8019 :     fn = SSA_NAME_VAR (fn);
    4334                 :            : 
    4335                 :     366998 :   return get_vi_for_tree (fn);
    4336                 :            : }
    4337                 :            : 
    4338                 :            : /* Create constraints for assigning call argument ARG to the incoming parameter
    4339                 :            :    INDEX of function FI.  */
    4340                 :            : 
    4341                 :            : static void
    4342                 :     658100 : find_func_aliases_for_call_arg (varinfo_t fi, unsigned index, tree arg)
    4343                 :            : {
    4344                 :     658100 :   struct constraint_expr lhs;
    4345                 :     658100 :   lhs = get_function_part_constraint (fi, fi_parm_base + index);
    4346                 :            : 
    4347                 :     658100 :   auto_vec<ce_s, 2> rhsc;
    4348                 :     658100 :   get_constraint_for_rhs (arg, &rhsc);
    4349                 :            : 
    4350                 :     658100 :   unsigned j;
    4351                 :     658100 :   struct constraint_expr *rhsp;
    4352                 :    1974300 :   FOR_EACH_VEC_ELT (rhsc, j, rhsp)
    4353                 :     658101 :     process_constraint (new_constraint (lhs, *rhsp));
    4354                 :     658100 : }
    4355                 :            : 
    4356                 :            : /* Return true if FNDECL may be part of another lto partition.  */
    4357                 :            : 
    4358                 :            : static bool
    4359                 :      33210 : fndecl_maybe_in_other_partition (tree fndecl)
    4360                 :            : {
    4361                 :      11070 :   cgraph_node *fn_node = cgraph_node::get (fndecl);
    4362                 :      33210 :   if (fn_node == NULL)
    4363                 :            :     return true;
    4364                 :            : 
    4365                 :          0 :   return fn_node->in_other_partition;
    4366                 :            : }
    4367                 :            : 
    4368                 :            : /* Create constraints for the builtin call T.  Return true if the call
    4369                 :            :    was handled, otherwise false.  */
    4370                 :            : 
    4371                 :            : static bool
    4372                 :    2796010 : find_func_aliases_for_builtin_call (struct function *fn, gcall *t)
    4373                 :            : {
    4374                 :    2796010 :   tree fndecl = gimple_call_fndecl (t);
    4375                 :    2796010 :   auto_vec<ce_s, 2> lhsc;
    4376                 :    2796010 :   auto_vec<ce_s, 4> rhsc;
    4377                 :    2796010 :   varinfo_t fi;
    4378                 :            : 
    4379                 :    2796010 :   if (gimple_call_builtin_p (t, BUILT_IN_NORMAL))
    4380                 :            :     /* ???  All builtins that are handled here need to be handled
    4381                 :            :        in the alias-oracle query functions explicitly!  */
    4382                 :    2430170 :     switch (DECL_FUNCTION_CODE (fndecl))
    4383                 :            :       {
    4384                 :            :       /* All the following functions return a pointer to the same object
    4385                 :            :          as their first argument points to.  The functions do not add
    4386                 :            :          to the ESCAPED solution.  The functions make the first argument
    4387                 :            :          pointed to memory point to what the second argument pointed to
    4388                 :            :          memory points to.  */
    4389                 :     164246 :       case BUILT_IN_STRCPY:
    4390                 :     164246 :       case BUILT_IN_STRNCPY:
    4391                 :     164246 :       case BUILT_IN_BCOPY:
    4392                 :     164246 :       case BUILT_IN_MEMCPY:
    4393                 :     164246 :       case BUILT_IN_MEMMOVE:
    4394                 :     164246 :       case BUILT_IN_MEMPCPY:
    4395                 :     164246 :       case BUILT_IN_STPCPY:
    4396                 :     164246 :       case BUILT_IN_STPNCPY:
    4397                 :     164246 :       case BUILT_IN_STRCAT:
    4398                 :     164246 :       case BUILT_IN_STRNCAT:
    4399                 :     164246 :       case BUILT_IN_STRCPY_CHK:
    4400                 :     164246 :       case BUILT_IN_STRNCPY_CHK:
    4401                 :     164246 :       case BUILT_IN_MEMCPY_CHK:
    4402                 :     164246 :       case BUILT_IN_MEMMOVE_CHK:
    4403                 :     164246 :       case BUILT_IN_MEMPCPY_CHK:
    4404                 :     164246 :       case BUILT_IN_STPCPY_CHK:
    4405                 :     164246 :       case BUILT_IN_STPNCPY_CHK:
    4406                 :     164246 :       case BUILT_IN_STRCAT_CHK:
    4407                 :     164246 :       case BUILT_IN_STRNCAT_CHK:
    4408                 :     164246 :       case BUILT_IN_TM_MEMCPY:
    4409                 :     164246 :       case BUILT_IN_TM_MEMMOVE:
    4410                 :     164246 :         {
    4411                 :     164246 :           tree res = gimple_call_lhs (t);
    4412                 :     164246 :           tree dest = gimple_call_arg (t, (DECL_FUNCTION_CODE (fndecl)
    4413                 :            :                                            == BUILT_IN_BCOPY ? 1 : 0));
    4414                 :     328492 :           tree src = gimple_call_arg (t, (DECL_FUNCTION_CODE (fndecl)
    4415                 :     164246 :                                           == BUILT_IN_BCOPY ? 0 : 1));
    4416                 :     164246 :           if (res != NULL_TREE)
    4417                 :            :             {
    4418                 :      18283 :               get_constraint_for (res, &lhsc);
    4419                 :      18283 :               if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_MEMPCPY
    4420                 :      15242 :                   || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPCPY
    4421                 :      14163 :                   || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPNCPY
    4422                 :      12904 :                   || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_MEMPCPY_CHK
    4423                 :      12570 :                   || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPCPY_CHK
    4424                 :      30587 :                   || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPNCPY_CHK)
    4425                 :       6018 :                 get_constraint_for_ptr_offset (dest, NULL_TREE, &rhsc);
    4426                 :            :               else
    4427                 :      12265 :                 get_constraint_for (dest, &rhsc);
    4428                 :      18283 :               process_all_all_constraints (lhsc, rhsc);
    4429                 :      18283 :               lhsc.truncate (0);
    4430                 :      18283 :               rhsc.truncate (0);
    4431                 :            :             }
    4432                 :     164246 :           get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
    4433                 :     164246 :           get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
    4434                 :     164246 :           do_deref (&lhsc);
    4435                 :     164246 :           do_deref (&rhsc);
    4436                 :     164246 :           process_all_all_constraints (lhsc, rhsc);
    4437                 :     164246 :           return true;
    4438                 :            :         }
    4439                 :      46255 :       case BUILT_IN_MEMSET:
    4440                 :      46255 :       case BUILT_IN_MEMSET_CHK:
    4441                 :      46255 :       case BUILT_IN_TM_MEMSET:
    4442                 :      46255 :         {
    4443                 :      46255 :           tree res = gimple_call_lhs (t);
    4444                 :      46255 :           tree dest = gimple_call_arg (t, 0);
    4445                 :      46255 :           unsigned i;
    4446                 :      46255 :           ce_s *lhsp;
    4447                 :      46255 :           struct constraint_expr ac;
    4448                 :      46255 :           if (res != NULL_TREE)
    4449                 :            :             {
    4450                 :       3873 :               get_constraint_for (res, &lhsc);
    4451                 :       3873 :               get_constraint_for (dest, &rhsc);
    4452                 :       3873 :               process_all_all_constraints (lhsc, rhsc);
    4453                 :       3873 :               lhsc.truncate (0);
    4454                 :            :             }
    4455                 :      46255 :           get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
    4456                 :      46255 :           do_deref (&lhsc);
    4457                 :      46255 :           if (flag_delete_null_pointer_checks
    4458                 :      92254 :               && integer_zerop (gimple_call_arg (t, 1)))
    4459                 :            :             {
    4460                 :            :               ac.type = ADDRESSOF;
    4461                 :            :               ac.var = nothing_id;
    4462                 :            :             }
    4463                 :            :           else
    4464                 :            :             {
    4465                 :            :               ac.type = SCALAR;
    4466                 :            :               ac.var = integer_id;
    4467                 :            :             }
    4468                 :      46255 :           ac.offset = 0;
    4469                 :      95265 :           FOR_EACH_VEC_ELT (lhsc, i, lhsp)
    4470                 :      49010 :               process_constraint (new_constraint (*lhsp, ac));
    4471                 :            :           return true;
    4472                 :            :         }
    4473                 :      11785 :       case BUILT_IN_STACK_SAVE:
    4474                 :      11785 :       case BUILT_IN_STACK_RESTORE:
    4475                 :            :         /* Nothing interesting happens.  */
    4476                 :      11785 :         return true;
    4477                 :      24539 :       case BUILT_IN_ALLOCA:
    4478                 :      24539 :       case BUILT_IN_ALLOCA_WITH_ALIGN:
    4479                 :      24539 :       case BUILT_IN_ALLOCA_WITH_ALIGN_AND_MAX:
    4480                 :      24539 :         {
    4481                 :      24539 :           tree ptr = gimple_call_lhs (t);
    4482                 :      24539 :           if (ptr == NULL_TREE)
    4483                 :            :             return true;
    4484                 :      24538 :           get_constraint_for (ptr, &lhsc);
    4485                 :      24538 :           varinfo_t vi = make_heapvar ("HEAP", true);
    4486                 :            :           /* Alloca storage is never global.  To exempt it from escaped
    4487                 :            :              handling make it a non-heap var.  */
    4488                 :      24538 :           DECL_EXTERNAL (vi->decl) = 0;
    4489                 :      24538 :           vi->is_global_var = 0;
    4490                 :      24538 :           vi->is_heap_var = 0;
    4491                 :      24538 :           struct constraint_expr tmpc;
    4492                 :      24538 :           tmpc.var = vi->id;
    4493                 :      24538 :           tmpc.offset = 0;
    4494                 :      24538 :           tmpc.type = ADDRESSOF;
    4495                 :      24538 :           rhsc.safe_push (tmpc);
    4496                 :      24538 :           process_all_all_constraints (lhsc, rhsc);
    4497                 :      24538 :           return true;
    4498                 :            :         }
    4499                 :        125 :       case BUILT_IN_POSIX_MEMALIGN:
    4500                 :        125 :         {
    4501                 :        125 :           tree ptrptr = gimple_call_arg (t, 0);
    4502                 :        125 :           get_constraint_for (ptrptr, &lhsc);
    4503                 :        125 :           do_deref (&lhsc);
    4504                 :        125 :           varinfo_t vi = make_heapvar ("HEAP", true);
    4505                 :            :           /* We are marking allocated storage local, we deal with it becoming
    4506                 :            :              global by escaping and setting of vars_contains_escaped_heap.  */
    4507                 :        125 :           DECL_EXTERNAL (vi->decl) = 0;
    4508                 :        125 :           vi->is_global_var = 0;
    4509                 :        125 :           struct constraint_expr tmpc;
    4510                 :        125 :           tmpc.var = vi->id;
    4511                 :        125 :           tmpc.offset = 0;
    4512                 :        125 :           tmpc.type = ADDRESSOF;
    4513                 :        125 :           rhsc.safe_push (tmpc);
    4514                 :        125 :           process_all_all_constraints (lhsc, rhsc);
    4515                 :        125 :           return true;
    4516                 :            :         }
    4517                 :       1520 :       case BUILT_IN_ASSUME_ALIGNED:
    4518                 :       1520 :         {
    4519                 :       1520 :           tree res = gimple_call_lhs (t);
    4520                 :       1520 :           tree dest = gimple_call_arg (t, 0);
    4521                 :       1520 :           if (res != NULL_TREE)
    4522                 :            :             {
    4523                 :       1520 :               get_constraint_for (res, &lhsc);
    4524                 :       1520 :               get_constraint_for (dest, &rhsc);
    4525                 :       1520 :               process_all_all_constraints (lhsc, rhsc);
    4526                 :            :             }
    4527                 :       1520 :           return true;
    4528                 :            :         }
    4529                 :            :       /* All the following functions do not return pointers, do not
    4530                 :            :          modify the points-to sets of memory reachable from their
    4531                 :            :          arguments and do not add to the ESCAPED solution.  */
    4532                 :      76221 :       case BUILT_IN_SINCOS:
    4533                 :      76221 :       case BUILT_IN_SINCOSF:
    4534                 :      76221 :       case BUILT_IN_SINCOSL:
    4535                 :      76221 :       case BUILT_IN_FREXP:
    4536                 :      76221 :       case BUILT_IN_FREXPF:
    4537                 :      76221 :       case BUILT_IN_FREXPL:
    4538                 :      76221 :       case BUILT_IN_GAMMA_R:
    4539                 :      76221 :       case BUILT_IN_GAMMAF_R:
    4540                 :      76221 :       case BUILT_IN_GAMMAL_R:
    4541                 :      76221 :       case BUILT_IN_LGAMMA_R:
    4542                 :      76221 :       case BUILT_IN_LGAMMAF_R:
    4543                 :      76221 :       case BUILT_IN_LGAMMAL_R:
    4544                 :      76221 :       case BUILT_IN_MODF:
    4545                 :      76221 :       case BUILT_IN_MODFF:
    4546                 :      76221 :       case BUILT_IN_MODFL:
    4547                 :      76221 :       case BUILT_IN_REMQUO:
    4548                 :      76221 :       case BUILT_IN_REMQUOF:
    4549                 :      76221 :       case BUILT_IN_REMQUOL:
    4550                 :      76221 :       case BUILT_IN_FREE:
    4551                 :      76221 :         return true;
    4552                 :       1055 :       case BUILT_IN_STRDUP:
    4553                 :       1055 :       case BUILT_IN_STRNDUP:
    4554                 :       1055 :       case BUILT_IN_REALLOC:
    4555                 :       1055 :         if (gimple_call_lhs (t))
    4556                 :            :           {
    4557                 :       1053 :             handle_lhs_call (t, gimple_call_lhs (t),
    4558                 :       1053 :                              gimple_call_return_flags (t) | ERF_NOALIAS,
    4559                 :            :                              vNULL, fndecl);
    4560                 :       1053 :             get_constraint_for_ptr_offset (gimple_call_lhs (t),
    4561                 :            :                                            NULL_TREE, &lhsc);
    4562                 :       1053 :             get_constraint_for_ptr_offset (gimple_call_arg (t, 0),
    4563                 :            :                                            NULL_TREE, &rhsc);
    4564                 :       1053 :             do_deref (&lhsc);
    4565                 :       1053 :             do_deref (&rhsc);
    4566                 :       1053 :             process_all_all_constraints (lhsc, rhsc);
    4567                 :       1053 :             lhsc.truncate (0);
    4568                 :       1053 :             rhsc.truncate (0);
    4569                 :            :             /* For realloc the resulting pointer can be equal to the
    4570                 :            :                argument as well.  But only doing this wouldn't be
    4571                 :            :                correct because with ptr == 0 realloc behaves like malloc.  */
    4572                 :       1053 :             if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_REALLOC)
    4573                 :            :               {
    4574                 :        192 :                 get_constraint_for (gimple_call_lhs (t), &lhsc);
    4575                 :        192 :                 get_constraint_for (gimple_call_arg (t, 0), &rhsc);
    4576                 :        192 :                 process_all_all_constraints (lhsc, rhsc);
    4577                 :            :               }
    4578                 :       1053 :             return true;
    4579                 :            :           }
    4580                 :            :         break;
    4581                 :            :       /* String / character search functions return a pointer into the
    4582                 :            :          source string or NULL.  */
    4583                 :       4175 :       case BUILT_IN_INDEX:
    4584                 :       4175 :       case BUILT_IN_STRCHR:
    4585                 :       4175 :       case BUILT_IN_STRRCHR:
    4586                 :       4175 :       case BUILT_IN_MEMCHR:
    4587                 :       4175 :       case BUILT_IN_STRSTR:
    4588                 :       4175 :       case BUILT_IN_STRPBRK:
    4589                 :       4175 :         if (gimple_call_lhs (t))
    4590                 :            :           {
    4591                 :       4175 :             tree src = gimple_call_arg (t, 0);
    4592                 :       4175 :             get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
    4593                 :       4175 :             constraint_expr nul;
    4594                 :       4175 :             nul.var = nothing_id;
    4595                 :       4175 :             nul.offset = 0;
    4596                 :       4175 :             nul.type = ADDRESSOF;
    4597                 :       4175 :             rhsc.safe_push (nul);
    4598                 :       4175 :             get_constraint_for (gimple_call_lhs (t), &lhsc);
    4599                 :       4175 :             process_all_all_constraints (lhsc, rhsc);
    4600                 :            :           }
    4601                 :       4175 :         return true;
    4602                 :            :       /* Pure functions that return something not based on any object and
    4603                 :            :          that use the memory pointed to by their arguments (but not
    4604                 :            :          transitively).  */
    4605                 :     181783 :       case BUILT_IN_STRCMP:
    4606                 :     181783 :       case BUILT_IN_STRCMP_EQ:
    4607                 :     181783 :       case BUILT_IN_STRNCMP:
    4608                 :     181783 :       case BUILT_IN_STRNCMP_EQ:
    4609                 :     181783 :       case BUILT_IN_STRCASECMP:
    4610                 :     181783 :       case BUILT_IN_STRNCASECMP:
    4611                 :     181783 :       case BUILT_IN_MEMCMP:
    4612                 :     181783 :       case BUILT_IN_BCMP:
    4613                 :     181783 :       case BUILT_IN_STRSPN:
    4614                 :     181783 :       case BUILT_IN_STRCSPN:
    4615                 :     181783 :         {
    4616                 :     181783 :           varinfo_t uses = get_call_use_vi (t);
    4617                 :     181783 :           make_any_offset_constraints (uses);
    4618                 :     181783 :           make_constraint_to (uses->id, gimple_call_arg (t, 0));
    4619                 :     181783 :           make_constraint_to (uses->id, gimple_call_arg (t, 1));
    4620                 :            :           /* No constraints are necessary for the return value.  */
    4621                 :     181783 :           return true;
    4622                 :            :         }
    4623                 :      31881 :       case BUILT_IN_STRLEN:
    4624                 :      31881 :         {
    4625                 :      31881 :           varinfo_t uses = get_call_use_vi (t);
    4626                 :      31881 :           make_any_offset_constraints (uses);
    4627                 :      31881 :           make_constraint_to (uses->id, gimple_call_arg (t, 0));
    4628                 :            :           /* No constraints are necessary for the return value.  */
    4629                 :      31881 :           return true;
    4630                 :            :         }
    4631                 :      15005 :       case BUILT_IN_OBJECT_SIZE:
    4632                 :      15005 :       case BUILT_IN_CONSTANT_P:
    4633                 :      15005 :         {
    4634                 :            :           /* No constraints are necessary for the return value or the
    4635                 :            :              arguments.  */
    4636                 :      15005 :           return true;
    4637                 :            :         }
    4638                 :            :       /* Trampolines are special - they set up passing the static
    4639                 :            :          frame.  */
    4640                 :        546 :       case BUILT_IN_INIT_TRAMPOLINE:
    4641                 :        546 :         {
    4642                 :        546 :           tree tramp = gimple_call_arg (t, 0);
    4643                 :        546 :           tree nfunc = gimple_call_arg (t, 1);
    4644                 :        546 :           tree frame = gimple_call_arg (t, 2);
    4645                 :        546 :           unsigned i;
    4646                 :        546 :           struct constraint_expr lhs, *rhsp;
    4647                 :        546 :           if (in_ipa_mode)
    4648                 :            :             {
    4649                 :          7 :               varinfo_t nfi = NULL;
    4650                 :          7 :               gcc_assert (TREE_CODE (nfunc) == ADDR_EXPR);
    4651                 :          7 :               nfi = lookup_vi_for_tree (TREE_OPERAND (nfunc, 0));
    4652                 :          7 :               if (nfi)
    4653                 :            :                 {
    4654                 :          7 :                   lhs = get_function_part_constraint (nfi, fi_static_chain);
    4655                 :          7 :                   get_constraint_for (frame, &rhsc);
    4656                 :         14 :                   FOR_EACH_VEC_ELT (rhsc, i, rhsp)
    4657                 :          7 :                     process_constraint (new_constraint (lhs, *rhsp));
    4658                 :          7 :                   rhsc.truncate (0);
    4659                 :            : 
    4660                 :            :                   /* Make the frame point to the function for
    4661                 :            :                      the trampoline adjustment call.  */
    4662                 :          7 :                   get_constraint_for (tramp, &lhsc);
    4663                 :          7 :                   do_deref (&lhsc);
    4664                 :          7 :                   get_constraint_for (nfunc, &rhsc);
    4665                 :          7 :                   process_all_all_constraints (lhsc, rhsc);
    4666                 :            : 
    4667                 :          7 :                   return true;
    4668                 :            :                 }
    4669                 :            :             }
    4670                 :            :           /* Else fallthru to generic handling which will let
    4671                 :            :              the frame escape.  */
    4672                 :        539 :           break;
    4673                 :            :         }
    4674                 :        577 :       case BUILT_IN_ADJUST_TRAMPOLINE:
    4675                 :        577 :         {
    4676                 :        577 :           tree tramp = gimple_call_arg (t, 0);
    4677                 :        577 :           tree res = gimple_call_lhs (t);
    4678                 :        577 :           if (in_ipa_mode && res)
    4679                 :            :             {
    4680                 :          7 :               get_constraint_for (res, &lhsc);
    4681                 :          7 :               get_constraint_for (tramp, &rhsc);
    4682                 :          7 :               do_deref (&rhsc);
    4683                 :          7 :               process_all_all_constraints (lhsc, rhsc);
    4684                 :            :             }
    4685                 :        577 :           return true;
    4686                 :            :         }
    4687                 :          4 :       CASE_BUILT_IN_TM_STORE (1):
    4688                 :          4 :       CASE_BUILT_IN_TM_STORE (2):
    4689                 :          4 :       CASE_BUILT_IN_TM_STORE (4):
    4690                 :          4 :       CASE_BUILT_IN_TM_STORE (8):
    4691                 :          4 :       CASE_BUILT_IN_TM_STORE (FLOAT):
    4692                 :          4 :       CASE_BUILT_IN_TM_STORE (DOUBLE):
    4693                 :          4 :       CASE_BUILT_IN_TM_STORE (LDOUBLE):
    4694                 :          4 :       CASE_BUILT_IN_TM_STORE (M64):
    4695                 :          4 :       CASE_BUILT_IN_TM_STORE (M128):
    4696                 :          4 :       CASE_BUILT_IN_TM_STORE (M256):
    4697                 :          4 :         {
    4698                 :          4 :           tree addr = gimple_call_arg (t, 0);
    4699                 :          4 :           tree src = gimple_call_arg (t, 1);
    4700                 :            : 
    4701                 :          4 :           get_constraint_for (addr, &lhsc);
    4702                 :          4 :           do_deref (&lhsc);
    4703                 :          4 :           get_constraint_for (src, &rhsc);
    4704                 :          4 :           process_all_all_constraints (lhsc, rhsc);
    4705                 :          4 :           return true;
    4706                 :            :         }
    4707                 :         10 :       CASE_BUILT_IN_TM_LOAD (1):
    4708                 :         10 :       CASE_BUILT_IN_TM_LOAD (2):
    4709                 :         10 :       CASE_BUILT_IN_TM_LOAD (4):
    4710                 :         10 :       CASE_BUILT_IN_TM_LOAD (8):
    4711                 :         10 :       CASE_BUILT_IN_TM_LOAD (FLOAT):
    4712                 :         10 :       CASE_BUILT_IN_TM_LOAD (DOUBLE):
    4713                 :         10 :       CASE_BUILT_IN_TM_LOAD (LDOUBLE):
    4714                 :         10 :       CASE_BUILT_IN_TM_LOAD (M64):
    4715                 :         10 :       CASE_BUILT_IN_TM_LOAD (M128):
    4716                 :         10 :       CASE_BUILT_IN_TM_LOAD (M256):
    4717                 :         10 :         {
    4718                 :         10 :           tree dest = gimple_call_lhs (t);
    4719                 :         10 :           tree addr = gimple_call_arg (t, 0);
    4720                 :            : 
    4721                 :         10 :           get_constraint_for (dest, &lhsc);
    4722                 :         10 :           get_constraint_for (addr, &rhsc);
    4723                 :         10 :           do_deref (&rhsc);
    4724                 :         10 :           process_all_all_constraints (lhsc, rhsc);
    4725                 :         10 :           return true;
    4726                 :            :         }
    4727                 :            :       /* Variadic argument handling needs to be handled in IPA
    4728                 :            :          mode as well.  */
    4729                 :      17836 :       case BUILT_IN_VA_START:
    4730                 :      17836 :         {
    4731                 :      17836 :           tree valist = gimple_call_arg (t, 0);
    4732                 :      17836 :           struct constraint_expr rhs, *lhsp;
    4733                 :      17836 :           unsigned i;
    4734                 :      17836 :           get_constraint_for_ptr_offset (valist, NULL_TREE, &lhsc);
    4735                 :      17836 :           do_deref (&lhsc);
    4736                 :            :           /* The va_list gets access to pointers in variadic
    4737                 :            :              arguments.  Which we know in the case of IPA analysis
    4738                 :            :              and otherwise are just all nonlocal variables.  */
    4739                 :      17836 :           if (in_ipa_mode)
    4740                 :            :             {
    4741                 :          1 :               fi = lookup_vi_for_tree (fn->decl);
    4742                 :          1 :               rhs = get_function_part_constraint (fi, ~0);
    4743                 :          1 :               rhs.type = ADDRESSOF;
    4744                 :            :             }
    4745                 :            :           else
    4746                 :            :             {
    4747                 :            :               rhs.var = nonlocal_id;
    4748                 :            :               rhs.type = ADDRESSOF;
    4749                 :            :               rhs.offset = 0;
    4750                 :            :             }
    4751                 :      35826 :           FOR_EACH_VEC_ELT (lhsc, i, lhsp)
    4752                 :      17990 :             process_constraint (new_constraint (*lhsp, rhs));
    4753                 :            :           /* va_list is clobbered.  */
    4754                 :      17836 :           make_constraint_to (get_call_clobber_vi (t)->id, valist);
    4755                 :      17836 :           return true;
    4756                 :            :         }
    4757                 :            :       /* va_end doesn't have any effect that matters.  */
    4758                 :       7387 :       case BUILT_IN_VA_END:
    4759                 :       7387 :         return true;
    4760                 :            :       /* Alternate return.  Simply give up for now.  */
    4761                 :        265 :       case BUILT_IN_RETURN:
    4762                 :        265 :         {
    4763                 :        265 :           fi = NULL;
    4764                 :        265 :           if (!in_ipa_mode
    4765                 :        265 :               || !(fi = get_vi_for_tree (fn->decl)))
    4766                 :        265 :             make_constraint_from (get_varinfo (escaped_id), anything_id);
    4767                 :          0 :           else if (in_ipa_mode
    4768                 :          0 :                    && fi != NULL)
    4769                 :            :             {
    4770                 :          0 :               struct constraint_expr lhs, rhs;
    4771                 :          0 :               lhs = get_function_part_constraint (fi, fi_result);
    4772                 :          0 :               rhs.var = anything_id;
    4773                 :          0 :               rhs.offset = 0;
    4774                 :          0 :               rhs.type = SCALAR;
    4775                 :          0 :               process_constraint (new_constraint (lhs, rhs));
    4776                 :            :             }
    4777                 :        265 :           return true;
    4778                 :            :         }
    4779                 :      43179 :       case BUILT_IN_GOMP_PARALLEL:
    4780                 :      43179 :       case BUILT_IN_GOACC_PARALLEL:
    4781                 :      43179 :         {
    4782                 :      43179 :           if (in_ipa_mode)
    4783                 :            :             {
    4784                 :      11070 :               unsigned int fnpos, argpos;
    4785                 :      11070 :               switch (DECL_FUNCTION_CODE (fndecl))
    4786                 :            :                 {
    4787                 :            :                 case BUILT_IN_GOMP_PARALLEL:
    4788                 :            :                   /* __builtin_GOMP_parallel (fn, data, num_threads, flags).  */
    4789                 :            :                   fnpos = 0;
    4790                 :            :                   argpos = 1;
    4791                 :            :                   break;
    4792                 :      11058 :                 case BUILT_IN_GOACC_PARALLEL:
    4793                 :            :                   /* __builtin_GOACC_parallel (flags_m, fn, mapnum, hostaddrs,
    4794                 :            :                                                sizes, kinds, ...).  */
    4795                 :      11058 :                   fnpos = 1;
    4796                 :      11058 :                   argpos = 3;
    4797                 :      11058 :                   break;
    4798                 :          0 :                 default:
    4799                 :          0 :                   gcc_unreachable ();
    4800                 :            :                 }
    4801                 :            : 
    4802                 :      11070 :               tree fnarg = gimple_call_arg (t, fnpos);
    4803                 :      11070 :               gcc_assert (TREE_CODE (fnarg) == ADDR_EXPR);
    4804                 :      11070 :               tree fndecl = TREE_OPERAND (fnarg, 0);
    4805                 :    2818150 :               if (fndecl_maybe_in_other_partition (fndecl))
    4806                 :            :                 /* Fallthru to general call handling.  */
    4807                 :            :                 break;
    4808                 :            : 
    4809                 :      11027 :               tree arg = gimple_call_arg (t, argpos);
    4810                 :            : 
    4811                 :      11027 :               varinfo_t fi = get_vi_for_tree (fndecl);
    4812                 :      11027 :               find_func_aliases_for_call_arg (fi, 0, arg);
    4813                 :      11027 :               return true;
    4814                 :            :             }
    4815                 :            :           /* Else fallthru to generic call handling.  */
    4816                 :            :           break;
    4817                 :            :         }
    4818                 :            :       /* printf-style functions may have hooks to set pointers to
    4819                 :            :          point to somewhere into the generated string.  Leave them
    4820                 :            :          for a later exercise...  */
    4821                 :         43 :       default:
    4822                 :            :         /* Fallthru to general call handling.  */;
    4823                 :            :       }
    4824                 :            : 
    4825                 :            :   return false;
    4826                 :            : }
    4827                 :            : 
    4828                 :            : /* Create constraints for the call T.  */
    4829                 :            : 
    4830                 :            : static void
    4831                 :   11385500 : find_func_aliases_for_call (struct function *fn, gcall *t)
    4832                 :            : {
    4833                 :   11385500 :   tree fndecl = gimple_call_fndecl (t);
    4834                 :   11385500 :   varinfo_t fi;
    4835                 :            : 
    4836                 :   11385500 :   if (fndecl != NULL_TREE
    4837                 :   10535600 :       && fndecl_built_in_p (fndecl)
    4838                 :   14181500 :       && find_func_aliases_for_builtin_call (fn, t))
    4839                 :            :     return;
    4840                 :            : 
    4841                 :   10789800 :   fi = get_fi_for_callee (t);
    4842                 :   10789800 :   if (!in_ipa_mode
    4843                 :     188650 :       || (fi->decl && fndecl && !fi->is_fn_info))
    4844                 :            :     {
    4845                 :   10640800 :       auto_vec<ce_s, 16> rhsc;
    4846                 :   10640800 :       int flags = gimple_call_flags (t);
    4847                 :            : 
    4848                 :            :       /* Const functions can return their arguments and addresses
    4849                 :            :          of global memory but not of escaped memory.  */
    4850                 :   10640800 :       if (flags & (ECF_CONST|ECF_NOVOPS))
    4851                 :            :         {
    4852                 :     690770 :           if (gimple_call_lhs (t))
    4853                 :     658282 :             handle_const_call (t, &rhsc);
    4854                 :            :         }
    4855                 :            :       /* Pure functions can return addresses in and of memory
    4856                 :            :          reachable from their arguments, but they are not an escape
    4857                 :            :          point for reachable memory of their arguments.  */
    4858                 :    9950060 :       else if (flags & (ECF_PURE|ECF_LOOPING_CONST_OR_PURE))
    4859                 :     322640 :         handle_pure_call (t, &rhsc);
    4860                 :            :       else
    4861                 :    9627420 :         handle_rhs_call (t, &rhsc);
    4862                 :   10640800 :       if (gimple_call_lhs (t))
    4863                 :    4144260 :         handle_lhs_call (t, gimple_call_lhs (t),
    4864                 :   10640800 :                          gimple_call_return_flags (t), rhsc, fndecl);
    4865                 :            :     }
    4866                 :            :   else
    4867                 :            :     {
    4868                 :     297950 :       auto_vec<ce_s, 2> rhsc;
    4869                 :     148975 :       tree lhsop;
    4870                 :     148975 :       unsigned j;
    4871                 :            : 
    4872                 :            :       /* Assign all the passed arguments to the appropriate incoming
    4873                 :            :          parameters of the function.  */
    4874                 :     796048 :       for (j = 0; j < gimple_call_num_args (t); j++)
    4875                 :            :         {
    4876                 :     647073 :           tree arg = gimple_call_arg (t, j);
    4877                 :     647073 :           find_func_aliases_for_call_arg (fi, j, arg);
    4878                 :            :         }
    4879                 :            : 
    4880                 :            :       /* If we are returning a value, assign it to the result.  */
    4881                 :     148975 :       lhsop = gimple_call_lhs (t);
    4882                 :     148975 :       if (lhsop)
    4883                 :            :         {
    4884                 :     262998 :           auto_vec<ce_s, 2> lhsc;
    4885                 :     131499 :           struct constraint_expr rhs;
    4886                 :     131499 :           struct constraint_expr *lhsp;
    4887                 :     132246 :           bool aggr_p = aggregate_value_p (lhsop, gimple_call_fntype (t));
    4888                 :            : 
    4889                 :     131499 :           get_constraint_for (lhsop, &lhsc);
    4890                 :     131499 :           rhs = get_function_part_constraint (fi, fi_result);
    4891                 :     131499 :           if (aggr_p)
    4892                 :            :             {
    4893                 :         16 :               auto_vec<ce_s, 2> tem;
    4894                 :          8 :               tem.quick_push (rhs);
    4895                 :          8 :               do_deref (&tem);
    4896                 :          8 :               gcc_checking_assert (tem.length () == 1);
    4897                 :          8 :               rhs = tem[0];
    4898                 :            :             }
    4899                 :     263002 :           FOR_EACH_VEC_ELT (lhsc, j, lhsp)
    4900                 :     131503 :             process_constraint (new_constraint (*lhsp, rhs));
    4901                 :            : 
    4902                 :            :           /* If we pass the result decl by reference, honor that.  */
    4903                 :     131499 :           if (aggr_p)
    4904                 :            :             {
    4905                 :          8 :               struct constraint_expr lhs;
    4906                 :          8 :               struct constraint_expr *rhsp;
    4907                 :            : 
    4908                 :          8 :               get_constraint_for_address_of (lhsop, &rhsc);
    4909                 :          8 :               lhs = get_function_part_constraint (fi, fi_result);
    4910                 :         16 :               FOR_EACH_VEC_ELT (rhsc, j, rhsp)
    4911                 :          8 :                   process_constraint (new_constraint (lhs, *rhsp));
    4912                 :          8 :               rhsc.truncate (0);
    4913                 :            :             }
    4914                 :            :         }
    4915                 :            : 
    4916                 :            :       /* If we use a static chain, pass it along.  */
    4917                 :     148975 :       if (gimple_call_chain (t))
    4918                 :            :         {
    4919                 :        284 :           struct constraint_expr lhs;
    4920                 :        284 :           struct constraint_expr *rhsp;
    4921                 :            : 
    4922                 :        284 :           get_constraint_for (gimple_call_chain (t), &rhsc);
    4923                 :        284 :           lhs = get_function_part_constraint (fi, fi_static_chain);
    4924                 :        852 :           FOR_EACH_VEC_ELT (rhsc, j, rhsp)
    4925                 :        284 :             process_constraint (new_constraint (lhs, *rhsp));
    4926                 :            :         }
    4927                 :            :     }
    4928                 :            : }
    4929                 :            : 
    4930                 :            : /* Walk statement T setting up aliasing constraints according to the
    4931                 :            :    references found in T.  This function is the main part of the
    4932                 :            :    constraint builder.  AI points to auxiliary alias information used
    4933                 :            :    when building alias sets and computing alias grouping heuristics.  */
    4934                 :            : 
    4935                 :            : static void
    4936                 :  164899000 : find_func_aliases (struct function *fn, gimple *origt)
    4937                 :            : {
    4938                 :  164899000 :   gimple *t = origt;
    4939                 :  164899000 :   auto_vec<ce_s, 16> lhsc;
    4940                 :  164899000 :   auto_vec<ce_s, 16> rhsc;
    4941                 :  164899000 :   varinfo_t fi;
    4942                 :            : 
    4943                 :            :   /* Now build constraints expressions.  */
    4944                 :  164899000 :   if (gimple_code (t) == GIMPLE_PHI)
    4945                 :            :     {
    4946                 :            :       /* For a phi node, assign all the arguments to
    4947                 :            :          the result.  */
    4948                 :    3661470 :       get_constraint_for (gimple_phi_result (t), &lhsc);
    4949                 :   12062800 :       for (unsigned i = 0; i < gimple_phi_num_args (t); i++)
    4950                 :            :         {
    4951                 :    8401340 :           get_constraint_for_rhs (gimple_phi_arg_def (t, i), &rhsc);
    4952                 :    8401340 :           process_all_all_constraints (lhsc, rhsc);
    4953                 :    8401340 :           rhsc.truncate (0);
    4954                 :            :         }
    4955                 :            :     }
    4956                 :            :   /* In IPA mode, we need to generate constraints to pass call
    4957                 :            :      arguments through their calls.   There are two cases,
    4958                 :            :      either a GIMPLE_CALL returning a value, or just a plain
    4959                 :            :      GIMPLE_CALL when we are not.
    4960                 :            : 
    4961                 :            :      In non-ipa mode, we need to generate constraints for each
    4962                 :            :      pointer passed by address.  */
    4963                 :  161237000 :   else if (is_gimple_call (t))
    4964                 :   11385500 :     find_func_aliases_for_call (fn, as_a <gcall *> (t));
    4965                 :            :     
    4966                 :            :   /* Otherwise, just a regular assignment statement.  Only care about
    4967                 :            :      operations with pointer result, others are dealt with as escape
    4968                 :            :      points if they have pointer operands.  */
    4969                 :  149852000 :   else if (is_gimple_assign (t))
    4970                 :            :     {
    4971                 :            :       /* Otherwise, just a regular assignment statement.  */
    4972                 :   52354800 :       tree lhsop = gimple_assign_lhs (t);
    4973                 :   52354800 :       tree rhsop = (gimple_num_ops (t) == 2) ? gimple_assign_rhs1 (t) : NULL;
    4974                 :            : 
    4975                 :   41914900 :       if (rhsop && TREE_CLOBBER_P (rhsop))
    4976                 :            :         /* Ignore clobbers, they don't actually store anything into
    4977                 :            :            the LHS.  */
    4978                 :            :         ;
    4979                 :   87298500 :       else if (rhsop && AGGREGATE_TYPE_P (TREE_TYPE (lhsop)))
    4980                 :    1743440 :         do_structure_copy (lhsop, rhsop);
    4981                 :            :       else
    4982                 :            :         {
    4983                 :   47125700 :           enum tree_code code = gimple_assign_rhs_code (t);
    4984                 :            : 
    4985                 :   47125700 :           get_constraint_for (lhsop, &lhsc);
    4986                 :            : 
    4987                 :   47125700 :           if (code == POINTER_PLUS_EXPR)
    4988                 :    1413070 :             get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
    4989                 :            :                                            gimple_assign_rhs2 (t), &rhsc);
    4990                 :   45712700 :           else if (code == POINTER_DIFF_EXPR)
    4991                 :            :             /* The result is not a pointer (part).  */
    4992                 :            :             ;
    4993                 :   45511500 :           else if (code == BIT_AND_EXPR
    4994                 :   45511500 :                    && TREE_CODE (gimple_assign_rhs2 (t)) == INTEGER_CST)
    4995                 :            :             {
    4996                 :            :               /* Aligning a pointer via a BIT_AND_EXPR is offsetting
    4997                 :            :                  the pointer.  Handle it by offsetting it by UNKNOWN.  */
    4998                 :     375917 :               get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
    4999                 :            :                                              NULL_TREE, &rhsc);
    5000                 :            :             }
    5001                 :   45135600 :           else if (code == TRUNC_DIV_EXPR
    5002                 :            :                    || code == CEIL_DIV_EXPR
    5003                 :            :                    || code == FLOOR_DIV_EXPR
    5004                 :   45135600 :                    || code == ROUND_DIV_EXPR
    5005                 :   45135600 :                    || code == EXACT_DIV_EXPR
    5006                 :            :                    || code == TRUNC_MOD_EXPR
    5007                 :   44894200 :                    || code == CEIL_MOD_EXPR
    5008                 :            :                    || code == FLOOR_MOD_EXPR
    5009                 :   44782300 :                    || code == ROUND_MOD_EXPR)
    5010                 :            :             /* Division and modulo transfer the pointer from the LHS.  */
    5011                 :     354138 :             get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
    5012                 :            :                                            NULL_TREE, &rhsc);
    5013                 :   44781500 :           else if (CONVERT_EXPR_CODE_P (code)
    5014                 :   44781500 :                    || gimple_assign_single_p (t))
    5015                 :            :             /* See through conversions, single RHS are handled by
    5016                 :            :                get_constraint_for_rhs.  */
    5017                 :   36147500 :             get_constraint_for_rhs (rhsop, &rhsc);
    5018                 :    8633960 :           else if (code == COND_EXPR)
    5019                 :            :             {
    5020                 :            :               /* The result is a merge of both COND_EXPR arms.  */
    5021                 :      44114 :               auto_vec<ce_s, 2> tmp;
    5022                 :      22057 :               struct constraint_expr *rhsp;
    5023                 :      22057 :               unsigned i;
    5024                 :      22057 :               get_constraint_for_rhs (gimple_assign_rhs2 (t), &rhsc);
    5025                 :      22057 :               get_constraint_for_rhs (gimple_assign_rhs3 (t), &tmp);
    5026                 :      66171 :               FOR_EACH_VEC_ELT (tmp, i, rhsp)
    5027                 :      22057 :                 rhsc.safe_push (*rhsp);
    5028                 :            :             }
    5029                 :    8611900 :           else if (truth_value_p (code))
    5030                 :            :             /* Truth value results are not pointer (parts).  Or at least
    5031                 :            :                very unreasonable obfuscation of a part.  */
    5032                 :            :             ;
    5033                 :            :           else
    5034                 :            :             {
    5035                 :            :               /* All other operations are possibly offsetting merges.  */
    5036                 :   14988200 :               auto_vec<ce_s, 4> tmp;
    5037                 :    7494080 :               struct constraint_expr *rhsp;
    5038                 :    7494080 :               unsigned i, j;
    5039                 :    7494080 :               get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
    5040                 :            :                                              NULL_TREE, &rhsc);
    5041                 :   14496500 :               for (i = 2; i < gimple_num_ops (t); ++i)
    5042                 :            :                 {
    5043                 :    7002390 :                   get_constraint_for_ptr_offset (gimple_op (t, i),
    5044                 :            :                                                  NULL_TREE, &tmp);
    5045                 :   14004800 :                   FOR_EACH_VEC_ELT (tmp, j, rhsp)
    5046                 :    7002390 :                     rhsc.safe_push (*rhsp);
    5047                 :    7002390 :                   tmp.truncate (0);
    5048                 :            :                 }
    5049                 :            :             }
    5050                 :   47125700 :           process_all_all_constraints (lhsc, rhsc);
    5051                 :            :         }
    5052                 :            :       /* If there is a store to a global variable the rhs escapes.  */
    5053                 :   52354800 :       if ((lhsop = get_base_address (lhsop)) != NULL_TREE
    5054                 :   52354800 :           && DECL_P (lhsop))
    5055                 :            :         {
    5056                 :   14955900 :           varinfo_t vi = get_vi_for_tree (lhsop);
    5057                 :   14955900 :           if ((! in_ipa_mode && vi->is_global_var)
    5058                 :   13885000 :               || vi->is_ipa_escape_point)
    5059                 :    1071720 :             make_escape_constraint (rhsop);
    5060                 :            :         }
    5061                 :            :     }
    5062                 :            :   /* Handle escapes through return.  */
    5063                 :   97496900 :   else if (gimple_code (t) == GIMPLE_RETURN
    5064                 :   97496900 :            && gimple_return_retval (as_a <greturn *> (t)) != NULL_TREE)
    5065                 :            :     {
    5066                 :    1575020 :       greturn *return_stmt = as_a <greturn *> (t);
    5067                 :    1575020 :       fi = NULL;
    5068                 :    1575020 :       if (!in_ipa_mode
    5069                 :            :           && SSA_VAR_P (gimple_return_retval (return_stmt)))
    5070                 :            :         {
    5071                 :            :           /* We handle simple returns by post-processing the solutions.  */
    5072                 :            :           ;
    5073                 :            :         }
    5074                 :    1575020 :       if (!(fi = get_vi_for_tree (fn->decl)))
    5075                 :          0 :         make_escape_constraint (gimple_return_retval (return_stmt));
    5076                 :    1575020 :       else if (in_ipa_mode)
    5077                 :            :         {
    5078                 :       3584 :           struct constraint_expr lhs ;
    5079                 :       3584 :           struct constraint_expr *rhsp;
    5080                 :       3584 :           unsigned i;
    5081                 :            : 
    5082                 :       3584 :           lhs = get_function_part_constraint (fi, fi_result);
    5083                 :       3584 :           get_constraint_for_rhs (gimple_return_retval (return_stmt), &rhsc);
    5084                 :      10752 :           FOR_EACH_VEC_ELT (rhsc, i, rhsp)
    5085                 :       3584 :             process_constraint (new_constraint (lhs, *rhsp));
    5086                 :            :         }
    5087                 :            :     }
    5088                 :            :   /* Handle asms conservatively by adding escape constraints to everything.  */
    5089                 :  165112000 :   else if (gasm *asm_stmt = dyn_cast <gasm *> (t))
    5090                 :            :     {
    5091                 :     213307 :       unsigned i, noutputs;
    5092                 :     213307 :       const char **oconstraints;
    5093                 :     213307 :       const char *constraint;
    5094                 :     213307 :       bool allows_mem, allows_reg, is_inout;
    5095                 :            : 
    5096                 :     213307 :       noutputs = gimple_asm_noutputs (asm_stmt);
    5097                 :     213307 :       oconstraints = XALLOCAVEC (const char *, noutputs);
    5098                 :            : 
    5099                 :     467581 :       for (i = 0; i < noutputs; ++i)
    5100                 :            :         {
    5101                 :     254274 :           tree link = gimple_asm_output_op (asm_stmt, i);
    5102                 :     254274 :           tree op = TREE_VALUE (link);
    5103                 :            : 
    5104                 :     254274 :           constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
    5105                 :     254274 :           oconstraints[i] = constraint;
    5106                 :     254274 :           parse_output_constraint (&constraint, i, 0, 0, &allows_mem,
    5107                 :            :                                    &allows_reg, &is_inout);
    5108                 :            : 
    5109                 :            :           /* A memory constraint makes the address of the operand escape.  */
    5110                 :     254274 :           if (!allows_reg && allows_mem)
    5111                 :       2211 :             make_escape_constraint (build_fold_addr_expr (op));
    5112                 :            : 
    5113                 :            :           /* The asm may read global memory, so outputs may point to
    5114                 :            :              any global memory.  */
    5115                 :     254274 :           if (op)
    5116                 :            :             {
    5117                 :     508548 :               auto_vec<ce_s, 2> lhsc;
    5118                 :     254274 :               struct constraint_expr rhsc, *lhsp;
    5119                 :     254274 :               unsigned j;
    5120                 :     254274 :               get_constraint_for (op, &lhsc);
    5121                 :     254274 :               rhsc.var = nonlocal_id;
    5122                 :     254274 :               rhsc.offset = 0;
    5123                 :     254274 :               rhsc.type = SCALAR;
    5124                 :     762825 :               FOR_EACH_VEC_ELT (lhsc, j, lhsp)
    5125                 :     254277 :                 process_constraint (new_constraint (*lhsp, rhsc));
    5126                 :            :             }
    5127                 :            :         }
    5128                 :     348081 :       for (i = 0; i < gimple_asm_ninputs (asm_stmt); ++i)
    5129                 :            :         {
    5130                 :     134774 :           tree link = gimple_asm_input_op (asm_stmt, i);
    5131                 :     134774 :           tree op = TREE_VALUE (link);
    5132                 :            : 
    5133                 :     134774 :           constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
    5134                 :            : 
    5135                 :     134774 :           parse_input_constraint (&constraint, 0, 0, noutputs, 0, oconstraints,
    5136                 :            :                                   &allows_mem, &allows_reg);
    5137                 :            : 
    5138                 :            :           /* A memory constraint makes the address of the operand escape.  */
    5139                 :     134774 :           if (!allows_reg && allows_mem)
    5140                 :       3673 :             make_escape_constraint (build_fold_addr_expr (op));
    5141                 :            :           /* Strictly we'd only need the constraint to ESCAPED if
    5142                 :            :              the asm clobbers memory, otherwise using something
    5143                 :            :              along the lines of per-call clobbers/uses would be enough.  */
    5144                 :     131101 :           else if (op)
    5145                 :     265875 :             make_escape_constraint (op);
    5146                 :            :         }
    5147                 :            :     }
    5148                 :  164899000 : }
    5149                 :            : 
    5150                 :            : 
    5151                 :            : /* Create a constraint adding to the clobber set of FI the memory
    5152                 :            :    pointed to by PTR.  */
    5153                 :            : 
    5154                 :            : static void
    5155                 :          0 : process_ipa_clobber (varinfo_t fi, tree ptr)
    5156                 :            : {
    5157                 :          0 :   vec<ce_s> ptrc = vNULL;
    5158                 :          0 :   struct constraint_expr *c, lhs;
    5159                 :          0 :   unsigned i;
    5160                 :          0 :   get_constraint_for_rhs (ptr, &ptrc);
    5161                 :          0 :   lhs = get_function_part_constraint (fi, fi_clobbers);
    5162                 :          0 :   FOR_EACH_VEC_ELT (ptrc, i, c)
    5163                 :          0 :     process_constraint (new_constraint (lhs, *c));
    5164                 :          0 :   ptrc.release ();
    5165                 :          0 : }
    5166                 :            : 
    5167                 :            : /* Walk statement T setting up clobber and use constraints according to the
    5168                 :            :    references found in T.  This function is a main part of the
    5169                 :            :    IPA constraint builder.  */
    5170                 :            : 
    5171                 :            : static void
    5172                 :     729869 : find_func_clobbers (struct function *fn, gimple *origt)
    5173                 :            : {
    5174                 :     729869 :   gimple *t = origt;
    5175                 :    1009490 :   auto_vec<ce_s, 16> lhsc;
    5176                 :     279617 :   auto_vec<ce_s, 16> rhsc;
    5177                 :     729869 :   varinfo_t fi;
    5178                 :            : 
    5179                 :            :   /* Add constraints for clobbered/used in IPA mode.
    5180                 :            :      We are not interested in what automatic variables are clobbered
    5181                 :            :      or used as we only use the information in the caller to which
    5182                 :            :      they do not escape.  */
    5183                 :     729869 :   gcc_assert (in_ipa_mode);
    5184                 :            : 
    5185                 :            :   /* If the stmt refers to memory in any way it better had a VUSE.  */
    5186                 :    1559190 :   if (gimple_vuse (t) == NULL_TREE)
    5187                 :     450252 :     return;
    5188                 :            : 
    5189                 :            :   /* We'd better have function information for the current function.  */
    5190                 :     472582 :   fi = lookup_vi_for_tree (fn->decl);
    5191                 :     472582 :   gcc_assert (fi != NULL);
    5192                 :            : 
    5193                 :            :   /* Account for stores in assignments and calls.  */
    5194                 :     472582 :   if (gimple_vdef (t) != NULL_TREE
    5195                 :     868401 :       && gimple_has_lhs (t))
    5196                 :            :     {
    5197                 :     240246 :       tree lhs = gimple_get_lhs (t);
    5198                 :     240246 :       tree tem = lhs;
    5199                 :     353960 :       while (handled_component_p (tem))
    5200                 :     113714 :         tem = TREE_OPERAND (tem, 0);
    5201                 :     240246 :       if ((DECL_P (tem)
    5202                 :     126677 :            && !auto_var_in_fn_p (tem, fn->decl))
    5203                 :     237269 :           || INDIRECT_REF_P (tem)
    5204                 :     477515 :           || (TREE_CODE (tem) == MEM_REF
    5205                 :      20522 :               && !(TREE_CODE (TREE_OPERAND (tem, 0)) == ADDR_EXPR
    5206                 :            :                    && auto_var_in_fn_p
    5207                 :       1664 :                         (TREE_OPERAND (TREE_OPERAND (tem, 0), 0), fn->decl))))
    5208                 :            :         {
    5209                 :      20350 :           struct constraint_expr lhsc, *rhsp;
    5210                 :      20350 :           unsigned i;
    5211                 :      20350 :           lhsc = get_function_part_constraint (fi, fi_clobbers);
    5212                 :      20350 :           get_constraint_for_address_of (lhs, &rhsc);
    5213                 :      40700 :           FOR_EACH_VEC_ELT (rhsc, i, rhsp)
    5214                 :      20350 :             process_constraint (new_constraint (lhsc, *rhsp));
    5215                 :      20350 :           rhsc.truncate (0);
    5216                 :            :         }
    5217                 :            :     }
    5218                 :            : 
    5219                 :            :   /* Account for uses in assigments and returns.  */
    5220                 :     472582 :   if (gimple_assign_single_p (t)
    5221                 :     217842 :       || (gimple_code (t) == GIMPLE_RETURN
    5222                 :      18743 :           && gimple_return_retval (as_a <greturn *> (t)) != NULL_TREE))
    5223                 :            :     {
    5224                 :     513064 :       tree rhs = (gimple_assign_single_p (t)
    5225                 :     254740 :                   ? gimple_assign_rhs1 (t)
    5226                 :       3584 :                   : gimple_return_retval (as_a <greturn *> (t)));
    5227                 :     258324 :       tree tem = rhs;
    5228                 :     364337 :       while (handled_component_p (tem))
    5229                 :     106013 :         tem = TREE_OPERAND (tem, 0);
    5230                 :     258324 :       if ((DECL_P (tem)
    5231                 :      38084 :            && !auto_var_in_fn_p (tem, fn->decl))
    5232                 :     254351 :           || INDIRECT_REF_P (tem)
    5233                 :     512675 :           || (TREE_CODE (tem) == MEM_REF
    5234                 :      71673 :               && !(TREE_CODE (TREE_OPERAND (tem, 0)) == ADDR_EXPR
    5235                 :            :                    && auto_var_in_fn_p
    5236                 :        359 :                         (TREE_OPERAND (TREE_OPERAND (tem, 0), 0), fn->decl))))
    5237                 :            :         {
    5238                 :      75009 :           struct constraint_expr lhs, *rhsp;
    5239                 :      75009 :           unsigned i;
    5240                 :      75009 :           lhs = get_function_part_constraint (fi, fi_uses);
    5241                 :      75009 :           get_constraint_for_address_of (rhs, &rhsc);
    5242                 :     150018 :           FOR_EACH_VEC_ELT (rhsc, i, rhsp)
    5243                 :      75009 :             process_constraint (new_constraint (lhs, *rhsp));
    5244                 :      75009 :           rhsc.truncate (0);
    5245                 :            :         }
    5246                 :            :     }
    5247                 :            : 
    5248                 :     472582 :   if (gcall *call_stmt = dyn_cast <gcall *> (t))
    5249                 :            :     {
    5250                 :     199075 :       varinfo_t cfi = NULL;
    5251                 :     199075 :       tree decl = gimple_call_fndecl (t);
    5252                 :     199075 :       struct constraint_expr lhs, rhs;
    5253                 :     199075 :       unsigned i, j;
    5254                 :            : 
    5255                 :            :       /* For builtins we do not have separate function info.  For those
    5256                 :            :          we do not generate escapes for we have to generate clobbers/uses.  */
    5257                 :     199075 :       if (gimple_call_builtin_p (t, BUILT_IN_NORMAL))
    5258                 :      26026 :         switch (DECL_FUNCTION_CODE (decl))
    5259                 :            :           {
    5260                 :            :           /* The following functions use and clobber memory pointed to
    5261                 :            :              by their arguments.  */
    5262                 :         52 :           case BUILT_IN_STRCPY:
    5263                 :         52 :           case BUILT_IN_STRNCPY:
    5264                 :         52 :           case BUILT_IN_BCOPY:
    5265                 :         52 :           case BUILT_IN_MEMCPY:
    5266                 :         52 :           case BUILT_IN_MEMMOVE:
    5267                 :         52 :           case BUILT_IN_MEMPCPY:
    5268                 :         52 :           case BUILT_IN_STPCPY:
    5269                 :         52 :           case BUILT_IN_STPNCPY:
    5270                 :         52 :           case BUILT_IN_STRCAT:
    5271                 :         52 :           case BUILT_IN_STRNCAT:
    5272                 :         52 :           case BUILT_IN_STRCPY_CHK:
    5273                 :         52 :           case BUILT_IN_STRNCPY_CHK:
    5274                 :         52 :           case BUILT_IN_MEMCPY_CHK:
    5275                 :         52 :           case BUILT_IN_MEMMOVE_CHK:
    5276                 :         52 :           case BUILT_IN_MEMPCPY_CHK:
    5277                 :         52 :           case BUILT_IN_STPCPY_CHK:
    5278                 :         52 :           case BUILT_IN_STPNCPY_CHK:
    5279                 :         52 :           case BUILT_IN_STRCAT_CHK:
    5280                 :         52 :           case BUILT_IN_STRNCAT_CHK:
    5281                 :         52 :             {
    5282                 :        104 :               tree dest = gimple_call_arg (t, (DECL_FUNCTION_CODE (decl)
    5283                 :            :                                                == BUILT_IN_BCOPY ? 1 : 0));
    5284                 :        104 :               tree src = gimple_call_arg (t, (DECL_FUNCTION_CODE (decl)
    5285                 :         52 :                                               == BUILT_IN_BCOPY ? 0 : 1));
    5286                 :         52 :               unsigned i;
    5287                 :         52 :               struct constraint_expr *rhsp, *lhsp;
    5288                 :         52 :               get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
    5289                 :         52 :               lhs = get_function_part_constraint (fi, fi_clobbers);
    5290                 :        104 :               FOR_EACH_VEC_ELT (lhsc, i, lhsp)
    5291                 :         52 :                 process_constraint (new_constraint (lhs, *lhsp));
    5292                 :         52 :               get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
    5293                 :         52 :               lhs = get_function_part_constraint (fi, fi_uses);
    5294                 :        104 :               FOR_EACH_VEC_ELT (rhsc, i, rhsp)
    5295                 :         52 :                 process_constraint (new_constraint (lhs, *rhsp));
    5296                 :            :               return;
    5297                 :            :             }
    5298                 :            :           /* The following function clobbers memory pointed to by
    5299                 :            :              its argument.  */
    5300                 :         74 :           case BUILT_IN_MEMSET:
    5301                 :         74 :           case BUILT_IN_MEMSET_CHK:
    5302                 :         74 :           case BUILT_IN_POSIX_MEMALIGN:
    5303                 :         74 :             {
    5304                 :         74 :               tree dest = gimple_call_arg (t, 0);
    5305                 :         74 :               unsigned i;
    5306                 :         74 :               ce_s *lhsp;
    5307                 :         74 :               get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
    5308                 :         74 :               lhs = get_function_part_constraint (fi, fi_clobbers);
    5309                 :     193113 :               FOR_EACH_VEC_ELT (lhsc, i, lhsp)
    5310                 :         74 :                 process_constraint (new_constraint (lhs, *lhsp));
    5311                 :            :               return;
    5312                 :            :             }
    5313                 :            :           /* The following functions clobber their second and third
    5314                 :            :              arguments.  */
    5315                 :          0 :           case BUILT_IN_SINCOS:
    5316                 :          0 :           case BUILT_IN_SINCOSF:
    5317                 :          0 :           case BUILT_IN_SINCOSL:
    5318                 :          0 :             {
    5319                 :          0 :               process_ipa_clobber (fi, gimple_call_arg (t, 1));
    5320                 :          0 :               process_ipa_clobber (fi, gimple_call_arg (t, 2));
    5321                 :          0 :               return;
    5322                 :            :             }
    5323                 :            :           /* The following functions clobber their second argument.  */
    5324                 :          0 :           case BUILT_IN_FREXP:
    5325                 :          0 :           case BUILT_IN_FREXPF:
    5326                 :          0 :           case BUILT_IN_FREXPL:
    5327                 :          0 :           case BUILT_IN_LGAMMA_R:
    5328                 :          0 :           case BUILT_IN_LGAMMAF_R:
    5329                 :          0 :           case BUILT_IN_LGAMMAL_R:
    5330                 :          0 :           case BUILT_IN_GAMMA_R:
    5331                 :          0 :           case BUILT_IN_GAMMAF_R:
    5332                 :          0 :           case BUILT_IN_GAMMAL_R:
    5333                 :          0 :           case BUILT_IN_MODF:
    5334                 :          0 :           case BUILT_IN_MODFF:
    5335                 :          0 :           case BUILT_IN_MODFL:
    5336                 :          0 :             {
    5337                 :          0 :               process_ipa_clobber (fi, gimple_call_arg (t, 1));
    5338                 :          0 :               return;
    5339                 :            :             }
    5340                 :            :           /* The following functions clobber their third argument.  */
    5341                 :          0 :           case BUILT_IN_REMQUO:
    5342                 :          0 :           case BUILT_IN_REMQUOF:
    5343                 :          0 :           case BUILT_IN_REMQUOL:
    5344                 :          0 :             {
    5345                 :          0 :               process_ipa_clobber (fi, gimple_call_arg (t, 2));
    5346                 :          0 :               return;
    5347                 :            :             }
    5348                 :            :           /* The following functions neither read nor clobber memory.  */
    5349                 :            :           case BUILT_IN_ASSUME_ALIGNED:
    5350                 :            :           case BUILT_IN_FREE:
    5351                 :            :             return;
    5352                 :            :           /* Trampolines are of no interest to us.  */
    5353                 :            :           case BUILT_IN_INIT_TRAMPOLINE:
    5354                 :            :           case BUILT_IN_ADJUST_TRAMPOLINE:
    5355                 :            :             return;
    5356                 :            :           case BUILT_IN_VA_START:
    5357                 :            :           case BUILT_IN_VA_END:
    5358                 :            :             return;
    5359                 :      11070 :           case BUILT_IN_GOMP_PARALLEL:
    5360                 :      11070 :           case BUILT_IN_GOACC_PARALLEL:
    5361                 :      11070 :             {
    5362                 :      11070 :               unsigned int fnpos, argpos;
    5363                 :      11070 :               unsigned int implicit_use_args[2];
    5364                 :      11070 :               unsigned int num_implicit_use_args = 0;
    5365                 :      11070 :               switch (DECL_FUNCTION_CODE (decl))
    5366                 :            :                 {
    5367                 :            :                 case BUILT_IN_GOMP_PARALLEL:
    5368                 :            :                   /* __builtin_GOMP_parallel (fn, data, num_threads, flags).  */
    5369                 :            :                   fnpos = 0;
    5370                 :            :                   argpos = 1;
    5371                 :            :                   break;
    5372                 :      11058 :                 case BUILT_IN_GOACC_PARALLEL:
    5373                 :            :                   /* __builtin_GOACC_parallel (flags_m, fn, mapnum, hostaddrs,
    5374                 :            :                                                sizes, kinds, ...).  */
    5375                 :      11058 :                   fnpos = 1;
    5376                 :      11058 :                   argpos = 3;
    5377                 :      11058 :                   implicit_use_args[num_implicit_use_args++] = 4;
    5378                 :      11058 :                   implicit_use_args[num_implicit_use_args++] = 5;
    5379                 :      11058 :                   break;
    5380                 :          0 :                 default:
    5381                 :          0 :                   gcc_unreachable ();
    5382                 :            :                 }
    5383                 :            : 
    5384                 :      11070 :               tree fnarg = gimple_call_arg (t, fnpos);
    5385                 :      11070 :               gcc_assert (TREE_CODE (fnarg) == ADDR_EXPR);
    5386                 :      11070 :               tree fndecl = TREE_OPERAND (fnarg, 0);
    5387                 :      22140 :               if (fndecl_maybe_in_other_partition (fndecl))
    5388                 :            :                 /* Fallthru to general call handling.  */
    5389                 :            :                 break;
    5390                 :            : 
    5391                 :      11027 :               varinfo_t cfi = get_vi_for_tree (fndecl);
    5392                 :            : 
    5393                 :      11027 :               tree arg = gimple_call_arg (t, argpos);
    5394                 :            : 
    5395                 :            :               /* Parameter passed by value is used.  */
    5396                 :      11027 :               lhs = get_function_part_constraint (fi, fi_uses);
    5397                 :      11027 :               struct constraint_expr *rhsp;
    5398                 :      11027 :               get_constraint_for (arg, &rhsc);
    5399                 :      22054 :               FOR_EACH_VEC_ELT (rhsc, j, rhsp)
    5400                 :      11027 :                 process_constraint (new_constraint (lhs, *rhsp));
    5401                 :      11027 :               rhsc.truncate (0);
    5402                 :            : 
    5403                 :            :               /* Handle parameters used by the call, but not used in cfi, as
    5404                 :            :                  implicitly used by cfi.  */
    5405                 :      11027 :               lhs = get_function_part_constraint (cfi, fi_uses);
    5406                 :      33063 :               for (unsigned i = 0; i < num_implicit_use_args; ++i)
    5407                 :            :                 {
    5408                 :      22036 :                   tree arg = gimple_call_arg (t, implicit_use_args[i]);
    5409                 :      22036 :                   get_constraint_for (arg, &rhsc);
    5410                 :      44072 :                   FOR_EACH_VEC_ELT (rhsc, j, rhsp)
    5411                 :      22036 :                     process_constraint (new_constraint (lhs, *rhsp));
    5412                 :      22036 :                   rhsc.truncate (0);
    5413                 :            :                 }
    5414                 :            : 
    5415                 :            :               /* The caller clobbers what the callee does.  */
    5416                 :      11027 :               lhs = get_function_part_constraint (fi, fi_clobbers);
    5417                 :      11027 :               rhs = get_function_part_constraint (cfi, fi_clobbers);
    5418                 :      11027 :               process_constraint (new_constraint (lhs, rhs));
    5419                 :            : 
    5420                 :            :               /* The caller uses what the callee does.  */
    5421                 :      11027 :               lhs = get_function_part_constraint (fi, fi_uses);
    5422                 :      11027 :               rhs = get_function_part_constraint (cfi, fi_uses);
    5423                 :      11027 :               process_constraint (new_constraint (lhs, rhs));
    5424                 :            : 
    5425                 :      11027 :               return;
    5426                 :            :             }
    5427                 :            :           /* printf-style functions may have hooks to set pointers to
    5428                 :            :              point to somewhere into the generated string.  Leave them
    5429                 :            :              for a later exercise...  */
    5430                 :            :           default:
    5431                 :            :             /* Fallthru to general call handling.  */;
    5432                 :            :           }
    5433                 :            : 
    5434                 :            :       /* Parameters passed by value are used.  */
    5435                 :     186280 :       lhs = get_function_part_constraint (fi, fi_uses);
    5436                 :     916229 :       for (i = 0; i < gimple_call_num_args (t); i++)
    5437                 :            :         {
    5438                 :     729949 :           struct constraint_expr *rhsp;
    5439                 :     729949 :           tree arg = gimple_call_arg (t, i);
    5440                 :            : 
    5441                 :    1447920 :           if (TREE_CODE (arg) == SSA_NAME
    5442                 :     729949 :               || is_gimple_min_invariant (arg))
    5443                 :     717969 :             continue;
    5444                 :            : 
    5445                 :      11980 :           get_constraint_for_address_of (arg, &rhsc);
    5446                 :      23961 :           FOR_EACH_VEC_ELT (rhsc, j, rhsp)
    5447                 :      11981 :             process_constraint (new_constraint (lhs, *rhsp));
    5448                 :      11980 :           rhsc.truncate (0);
    5449                 :            :         }
    5450                 :            : 
    5451                 :            :       /* Build constraints for propagating clobbers/uses along the
    5452                 :            :          callgraph edges.  */
    5453                 :     186280 :       cfi = get_fi_for_callee (call_stmt);
    5454                 :     186280 :       if (cfi->id == anything_id)
    5455                 :            :         {
    5456                 :     282324 :           if (gimple_vdef (t))
    5457                 :      98635 :             make_constraint_from (first_vi_for_offset (fi, fi_clobbers),
    5458                 :            :                                   anything_id);
    5459                 :     141162 :           make_constraint_from (first_vi_for_offset (fi, fi_uses),
    5460                 :            :                                 anything_id);
    5461                 :     141162 :           return;
    5462                 :            :         }
    5463                 :            : 
    5464                 :            :       /* For callees without function info (that's external functions),
    5465                 :            :          ESCAPED is clobbered and used.  */
    5466                 :      45118 :       if (cfi->decl
    5467                 :      45117 :           && TREE_CODE (cfi->decl) == FUNCTION_DECL
    5468                 :      44348 :           && !cfi->is_fn_info)
    5469                 :            :         {
    5470                 :      39008 :           varinfo_t vi;
    5471                 :            : 
    5472                 :      78016 :           if (gimple_vdef (t))
    5473                 :      38848 :             make_copy_constraint (first_vi_for_offset (fi, fi_clobbers),
    5474                 :            :                                   escaped_id);
    5475                 :      39008 :           make_copy_constraint (first_vi_for_offset (fi, fi_uses), escaped_id);
    5476                 :            : 
    5477                 :            :           /* Also honor the call statement use/clobber info.  */
    5478                 :      39008 :           if ((vi = lookup_call_clobber_vi (call_stmt)) != NULL)
    5479                 :       6414 :             make_copy_constraint (first_vi_for_offset (fi, fi_clobbers),
    5480                 :       6414 :                                   vi->id);
    5481                 :      39008 :           if ((vi = lookup_call_use_vi (call_stmt)) != NULL)
    5482                 :       6414 :             make_copy_constraint (first_vi_for_offset (fi, fi_uses),
    5483                 :       6414 :                                   vi->id);
    5484                 :      39008 :           return;
    5485                 :            :         }
    5486                 :            : 
    5487                 :            :       /* Otherwise the caller clobbers and uses what the callee does.
    5488                 :            :          ???  This should use a new complex constraint that filters
    5489                 :            :          local variables of the callee.  */
    5490                 :      12220 :       if (gimple_vdef (t))
    5491                 :            :         {
    5492                 :       5271 :           lhs = get_function_part_constraint (fi, fi_clobbers);
    5493                 :       5271 :           rhs = get_function_part_constraint (cfi, fi_clobbers);
    5494                 :       5271 :           process_constraint (new_constraint (lhs, rhs));
    5495                 :            :         }
    5496                 :       6110 :       lhs = get_function_part_constraint (fi, fi_uses);
    5497                 :       6110 :       rhs = get_function_part_constraint (cfi, fi_uses);
    5498                 :       6110 :       process_constraint (new_constraint (lhs, rhs));
    5499                 :            :     }
    5500                 :     273507 :   else if (gimple_code (t) == GIMPLE_ASM)
    5501                 :            :     {
    5502                 :            :       /* ???  Ick.  We can do better.  */
    5503                 :         24 :       if (gimple_vdef (t))
    5504                 :         24 :         make_constraint_from (first_vi_for_offset (fi, fi_clobbers),
    5505                 :            :                               anything_id);
    5506                 :         24 :       make_constraint_from (first_vi_for_offset (fi, fi_uses),
    5507                 :            :                             anything_id);
    5508                 :            :     }
    5509                 :            : }
    5510                 :            : 
    5511                 :            : 
    5512                 :            : /* Find the first varinfo in the same variable as START that overlaps with
    5513                 :            :    OFFSET.  Return NULL if we can't find one.  */
    5514                 :            : 
    5515                 :            : static varinfo_t
    5516                 :     777874 : first_vi_for_offset (varinfo_t start, unsigned HOST_WIDE_INT offset)
    5517                 :            : {
    5518                 :            :   /* If the offset is outside of the variable, bail out.  */
    5519                 :     777874 :   if (offset >= start->fullsize)
    5520                 :            :     return NULL;
    5521                 :            : 
    5522                 :            :   /* If we cannot reach offset from start, lookup the first field
    5523                 :            :      and start from there.  */
    5524                 :     774516 :   if (start->offset > offset)
    5525                 :          0 :     start = get_varinfo (start->head);
    5526                 :            : 
    5527                 :    2201400 :   while (start)
    5528                 :            :     {
    5529                 :            :       /* We may not find a variable in the field list with the actual
    5530                 :            :          offset when we have glommed a structure to a variable.
    5531                 :            :          In that case, however, offset should still be within the size
    5532                 :            :          of the variable. */
    5533                 :    2201400 :       if (offset >= start->offset
    5534                 :    2201400 :           && (offset - start->offset) < start->size)
    5535                 :     774516 :         return start;
    5536                 :            : 
    5537                 :    1426880 :       start = vi_next (start);
    5538                 :            :     }
    5539                 :            : 
    5540                 :            :   return NULL;
    5541                 :            : }
    5542                 :            : 
    5543                 :            : /* Find the first varinfo in the same variable as START that overlaps with
    5544                 :            :    OFFSET.  If there is no such varinfo the varinfo directly preceding
    5545                 :            :    OFFSET is returned.  */
    5546                 :            : 
    5547                 :            : static varinfo_t
    5548                 :    3911840 : first_or_preceding_vi_for_offset (varinfo_t start,
    5549                 :            :                                   unsigned HOST_WIDE_INT offset)
    5550                 :            : {
    5551                 :            :   /* If we cannot reach offset from start, lookup the first field
    5552                 :            :      and start from there.  */
    5553                 :    3911840 :   if (start->offset > offset)
    5554                 :      71916 :     start = get_varinfo (start->head);
    5555                 :            : 
    5556                 :            :   /* We may not find a variable in the field list with the actual
    5557                 :            :      offset when we have glommed a structure to a variable.
    5558                 :            :      In that case, however, offset should still be within the size
    5559                 :            :      of the variable.
    5560                 :            :      If we got beyond the offset we look for return the field
    5561                 :            :      directly preceding offset which may be the last field.  */
    5562                 :   12364400 :   while (start->next
    5563                 :   10129800 :          && offset >= start->offset
    5564                 :   22493400 :          && !((offset - start->offset) < start->size))
    5565                 :    8452580 :     start = vi_next (start);
    5566                 :            : 
    5567                 :    3911840 :   return start;
    5568                 :            : }
    5569                 :            : 
    5570                 :            : 
    5571                 :            : /* This structure is used during pushing fields onto the fieldstack
    5572                 :            :    to track the offset of the field, since bitpos_of_field gives it
    5573                 :            :    relative to its immediate containing type, and we want it relative
    5574                 :            :    to the ultimate containing object.  */
    5575                 :            : 
    5576                 :            : struct fieldoff
    5577                 :            : {
    5578                 :            :   /* Offset from the base of the base containing object to this field.  */
    5579                 :            :   HOST_WIDE_INT offset;
    5580                 :            : 
    5581                 :            :   /* Size, in bits, of the field.  */
    5582                 :            :   unsigned HOST_WIDE_INT size;
    5583                 :            : 
    5584                 :            :   unsigned has_unknown_size : 1;
    5585                 :            : 
    5586                 :            :   unsigned must_have_pointers : 1;
    5587                 :            : 
    5588                 :            :   unsigned may_have_pointers : 1;
    5589                 :            : 
    5590                 :            :   unsigned only_restrict_pointers : 1;
    5591                 :            : 
    5592                 :            :   tree restrict_pointed_type;
    5593                 :            : };
    5594                 :            : typedef struct fieldoff fieldoff_s;
    5595                 :            : 
    5596                 :            : 
    5597                 :            : /* qsort comparison function for two fieldoff's PA and PB */
    5598                 :            : 
    5599                 :            : static int
    5600                 :  144904000 : fieldoff_compare (const void *pa, const void *pb)
    5601                 :            : {
    5602                 :  144904000 :   const fieldoff_s *foa = (const fieldoff_s *)pa;
    5603                 :  144904000 :   const fieldoff_s *fob = (const fieldoff_s *)pb;
    5604                 :  144904000 :   unsigned HOST_WIDE_INT foasize, fobsize;
    5605                 :            : 
    5606                 :  144904000 :   if (foa->offset < fob->offset)
    5607                 :            :     return -1;
    5608                 :   75533900 :   else if (foa->offset > fob->offset)
    5609                 :            :     return 1;
    5610                 :            : 
    5611                 :     917668 :   foasize = foa->size;
    5612                 :     917668 :   fobsize = fob->size;
    5613                 :     917668 :   if (foasize < fobsize)
    5614                 :            :     return -1;
    5615                 :     796306 :   else if (foasize > fobsize)
    5616                 :      77024 :     return 1;
    5617                 :            :   return 0;
    5618                 :            : }
    5619                 :            : 
    5620                 :            : /* Sort a fieldstack according to the field offset and sizes.  */
    5621                 :            : static void
    5622                 :    5425620 : sort_fieldstack (vec<fieldoff_s> fieldstack)
    5623                 :            : {
    5624                 :    5425620 :   fieldstack.qsort (fieldoff_compare);
    5625                 :    5425620 : }
    5626                 :            : 
    5627                 :            : /* Return true if T is a type that can have subvars.  */
    5628                 :            : 
    5629                 :            : static inline bool
    5630                 :   45370500 : type_can_have_subvars (const_tree t)
    5631                 :            : {
    5632                 :            :   /* Aggregates without overlapping fields can have subvars.  */
    5633                 :    3141810 :   return TREE_CODE (t) == RECORD_TYPE;
    5634                 :            : }
    5635                 :            : 
    5636                 :            : /* Return true if V is a tree that we can have subvars for.
    5637                 :            :    Normally, this is any aggregate type.  Also complex
    5638                 :            :    types which are not gimple registers can have subvars.  */
    5639                 :            : 
    5640                 :            : static inline bool
    5641                 :   81760500 : var_can_have_subvars (const_tree v)
    5642                 :            : {
    5643                 :            :   /* Volatile variables should never have subvars.  */
    5644                 :   81760500 :   if (TREE_THIS_VOLATILE (v))
    5645                 :            :     return false;
    5646                 :            : 
    5647                 :            :   /* Non decls or memory tags can never have subvars.  */
    5648                 :   81418700 :   if (!DECL_P (v))
    5649                 :            :     return false;
    5650                 :            : 
    5651                 :   42228700 :   return type_can_have_subvars (TREE_TYPE (v));
    5652                 :            : }
    5653                 :            : 
    5654                 :            : /* Return true if T is a type that does contain pointers.  */
    5655                 :            : 
    5656                 :            : static bool
    5657                 :   25150600 : type_must_have_pointers (tree type)
    5658                 :            : {
    5659                 :   25640100 :   if (POINTER_TYPE_P (type))
    5660                 :            :     return true;
    5661                 :            : 
    5662                 :   14158900 :   if (TREE_CODE (type) == ARRAY_TYPE)
    5663                 :     489437 :     return type_must_have_pointers (TREE_TYPE (type));
    5664                 :            : 
    5665                 :            :   /* A function or method can have pointers as arguments, so track
    5666                 :            :      those separately.  */
    5667                 :   13669400 :   if (TREE_CODE (type) == FUNCTION_TYPE
    5668                 :   13669400 :       || TREE_CODE (type) == METHOD_TYPE)
    5669                 :          0 :     return true;
    5670                 :            : 
    5671                 :            :   return false;
    5672                 :            : }
    5673                 :            : 
    5674                 :            : static bool
    5675                 :   25150600 : field_must_have_pointers (tree t)
    5676                 :            : {
    5677                 :   25150600 :   return type_must_have_pointers (TREE_TYPE (t));
    5678                 :            : }
    5679                 :            : 
    5680                 :            : /* Given a TYPE, and a vector of field offsets FIELDSTACK, push all
    5681                 :            :    the fields of TYPE onto fieldstack, recording their offsets along
    5682                 :            :    the way.
    5683                 :            : 
    5684                 :            :    OFFSET is used to keep track of the offset in this entire
    5685                 :            :    structure, rather than just the immediately containing structure.
    5686                 :            :    Returns false if the caller is supposed to handle the field we
    5687                 :            :    recursed for.  */
    5688                 :            : 
    5689                 :            : static bool
    5690                 :    9109160 : push_fields_onto_fieldstack (tree type, vec<fieldoff_s> *fieldstack,
    5691                 :            :                              HOST_WIDE_INT offset)
    5692                 :            : {
    5693                 :    9109160 :   tree field;
    5694                 :    9109160 :   bool empty_p = true;
    5695                 :            : 
    5696                 :    9109160 :   if (TREE_CODE (type) != RECORD_TYPE)
    5697                 :            :     return false;
    5698                 :            : 
    5699                 :            :   /* If the vector of fields is growing too big, bail out early.
    5700                 :            :      Callers check for vec::length <= param_max_fields_for_field_sensitive, make
    5701                 :            :      sure this fails.  */
    5702                 :   11116500 :   if (fieldstack->length () > (unsigned)param_max_fields_for_field_sensitive)
    5703                 :            :     return false;
    5704                 :            : 
    5705                 :  158225000 :   for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
    5706                 :  149302000 :     if (TREE_CODE (field) == FIELD_DECL)
    5707                 :            :       {
    5708                 :   28583400 :         bool push = false;
    5709                 :   28583400 :         HOST_WIDE_INT foff = bitpos_of_field (field);
    5710                 :   28583400 :         tree field_type = TREE_TYPE (field);
    5711                 :            : 
    5712                 :   28583400 :         if (!var_can_have_subvars (field)
    5713                 :    3658930 :             || TREE_CODE (field_type) == QUAL_UNION_TYPE
    5714                 :   32242300 :             || TREE_CODE (field_type) == UNION_TYPE)
    5715                 :            :           push = true;
    5716                 :    3658930 :         else if (!push_fields_onto_fieldstack
    5717                 :    3658930 :                     (field_type, fieldstack, offset + foff)
    5718                 :    3987390 :                  && (DECL_SIZE (field)
    5719                 :     328465 :                      && !integer_zerop (DECL_SIZE (field))))
    5720                 :            :           /* Empty structures may have actual size, like in C++.  So
    5721                 :            :              see if we didn't push any subfields and the size is
    5722                 :            :              nonzero, push the field onto the stack.  */
    5723                 :            :           push = true;
    5724                 :            : 
    5725                 :            :         if (push)
    5726                 :            :           {
    5727                 :   25150600 :             fieldoff_s *pair = NULL;
    5728                 :   25150600 :             bool has_unknown_size = false;
    5729                 :   25150600 :             bool must_have_pointers_p;
    5730                 :            : 
    5731                 :   25150600 :             if (!fieldstack->is_empty ())
    5732                 :   19956500 :               pair = &fieldstack->last ();
    5733                 :            : 
    5734                 :            :             /* If there isn't anything at offset zero, create sth.  */
    5735                 :   19956500 :             if (!pair
    5736                 :    5194140 :                 && offset + foff != 0)
    5737                 :            :               {
    5738                 :       1652 :                 fieldoff_s e
    5739                 :       1652 :                   = {0, offset + foff, false, false, true, false, NULL_TREE};
    5740                 :       1652 :                 pair = fieldstack->safe_push (e);
    5741                 :            :               }
    5742                 :            : 
    5743                 :   25150600 :             if (!DECL_SIZE (field)
    5744                 :   25150600 :                 || !tree_fits_uhwi_p (DECL_SIZE (field)))
    5745                 :            :               has_unknown_size = true;
    5746                 :            : 
    5747                 :            :             /* If adjacent fields do not contain pointers merge them.  */
    5748                 :   25150600 :             must_have_pointers_p = field_must_have_pointers (field);
    5749                 :   25150600 :             if (pair
    5750                 :   25150600 :                 && !has_unknown_size
    5751                 :   19933500 :                 && !must_have_pointers_p
    5752                 :            :                 && !pair->must_have_pointers
    5753                 :   12229200 :                 && !pair->has_unknown_size
    5754                 :    8547500 :                 && pair->offset + (HOST_WIDE_INT)pair->size == offset + foff)
    5755                 :            :               {
    5756                 :    8136620 :                 pair->size += tree_to_uhwi (DECL_SIZE (field));
    5757                 :            :               }
    5758                 :            :             else
    5759                 :            :               {
    5760                 :   17014000 :                 fieldoff_s e;
    5761                 :   17014000 :                 e.offset = offset + foff;
    5762                 :   17014000 :                 e.has_unknown_size = has_unknown_size;
    5763                 :   17014000 :                 if (!has_unknown_size)
    5764                 :   16989400 :                   e.size = tree_to_uhwi (DECL_SIZE (field));
    5765                 :            :                 else
    5766                 :      24613 :                   e.size = -1;
    5767                 :   17014000 :                 e.must_have_pointers = must_have_pointers_p;
    5768                 :   17014000 :                 e.may_have_pointers = true;
    5769                 :   17014000 :                 e.only_restrict_pointers
    5770                 :   17014000 :                   = (!has_unknown_size
    5771                 :   16989400 :                      && POINTER_TYPE_P (field_type)
    5772                 :   28489400 :                      && TYPE_RESTRICT (field_type));
    5773                 :   17014000 :                 if (e.only_restrict_pointers)
    5774                 :      63635 :                   e.restrict_pointed_type = TREE_TYPE (field_type);
    5775                 :   17014000 :                 fieldstack->safe_push (e);
    5776                 :            :               }
    5777                 :            :           }
    5778                 :            : 
    5779                 :            :         empty_p = false;
    5780                 :            :       }
    5781                 :            : 
    5782                 :    8923590 :   return !empty_p;
    5783                 :            : }
    5784                 :            : 
    5785                 :            : /* Count the number of arguments DECL has, and set IS_VARARGS to true
    5786                 :            :    if it is a varargs function.  */
    5787                 :            : 
    5788                 :            : static unsigned int
    5789                 :      19095 : count_num_arguments (tree decl, bool *is_varargs)
    5790                 :            : {
    5791                 :      19095 :   unsigned int num = 0;
    5792                 :      19095 :   tree t;
    5793                 :            : 
    5794                 :            :   /* Capture named arguments for K&R functions.  They do not
    5795                 :            :      have a prototype and thus no TYPE_ARG_TYPES.  */
    5796                 :      40196 :   for (t = DECL_ARGUMENTS (decl); t; t = DECL_CHAIN (t))
    5797                 :      21101 :     ++num;
    5798                 :            : 
    5799                 :            :   /* Check if the function has variadic arguments.  */
    5800                 :      40256 :   for (t = TYPE_ARG_TYPES (TREE_TYPE (decl)); t; t = TREE_CHAIN (t))
    5801                 :      39718 :     if (TREE_VALUE (t) == void_type_node)
    5802                 :            :       break;
    5803                 :      19095 :   if (!t)
    5804                 :        478 :     *is_varargs = true;
    5805                 :            : 
    5806                 :      19095 :   return num;
    5807                 :            : }
    5808                 :            : 
    5809                 :            : /* Creation function node for DECL, using NAME, and return the index
    5810                 :            :    of the variable we've created for the function.  If NONLOCAL_p, create
    5811                 :            :    initial constraints.  */
    5812                 :            : 
    5813                 :            : static varinfo_t
    5814                 :      19095 : create_function_info_for (tree decl, const char *name, bool add_id,
    5815                 :            :                           bool nonlocal_p)
    5816                 :            : {
    5817                 :      19095 :   struct function *fn = DECL_STRUCT_FUNCTION (decl);
    5818                 :      19095 :   varinfo_t vi, prev_vi;
    5819                 :      19095 :   tree arg;
    5820                 :      19095 :   unsigned int i;
    5821                 :      19095 :   bool is_varargs = false;
    5822                 :      19095 :   unsigned int num_args = count_num_arguments (decl, &is_varargs);
    5823                 :            : 
    5824                 :            :   /* Create the variable info.  */
    5825                 :            : 
    5826                 :      19095 :   vi = new_var_info (decl, name, add_id);
    5827                 :      19095 :   vi->offset = 0;
    5828                 :      19095 :   vi->size = 1;
    5829                 :      19095 :   vi->fullsize = fi_parm_base + num_args;
    5830                 :      19095 :   vi->is_fn_info = 1;
    5831                 :      19095 :   vi->may_have_pointers = false;
    5832                 :      19095 :   if (is_varargs)
    5833                 :        478 :     vi->fullsize = ~0;
    5834                 :      19095 :   insert_vi_for_tree (vi->decl, vi);
    5835                 :            : 
    5836                 :      19095 :   prev_vi = vi;
    5837                 :            : 
    5838                 :            :   /* Create a variable for things the function clobbers and one for
    5839                 :            :      things the function uses.  */
    5840                 :      19095 :     {
    5841                 :      19095 :       varinfo_t clobbervi, usevi;
    5842                 :      19095 :       const char *newname;
    5843                 :      19095 :       char *tempname;
    5844                 :            : 
    5845                 :      19095 :       tempname = xasprintf ("%s.clobber", name);
    5846                 :      19095 :       newname = ggc_strdup (tempname);
    5847                 :      19095 :       free (tempname);
    5848                 :            : 
    5849                 :      19095 :       clobbervi = new_var_info (NULL, newname, false);
    5850                 :      19095 :       clobbervi->offset = fi_clobbers;
    5851                 :      19095 :       clobbervi->size = 1;
    5852                 :      19095 :       clobbervi->fullsize = vi->fullsize;
    5853                 :      19095 :       clobbervi->is_full_var = true;
    5854                 :      19095 :       clobbervi->is_global_var = false;
    5855                 :      19095 :       clobbervi->is_reg_var = true;
    5856                 :            : 
    5857                 :      19095 :       gcc_assert (prev_vi->offset < clobbervi->offset);
    5858                 :      19095 :       prev_vi->next = clobbervi->id;
    5859                 :      19095 :       prev_vi = clobbervi;
    5860                 :            : 
    5861                 :      19095 :       tempname = xasprintf ("%s.use", name);
    5862                 :      19095 :       newname = ggc_strdup (tempname);
    5863                 :      19095 :       free (tempname);
    5864                 :            : 
    5865                 :      19095 :       usevi = new_var_info (NULL, newname, false);
    5866                 :      19095 :       usevi->offset = fi_uses;
    5867                 :      19095 :       usevi->size = 1;
    5868                 :      19095 :       usevi->fullsize = vi->fullsize;
    5869                 :      19095 :       usevi->is_full_var = true;
    5870                 :      19095 :       usevi->is_global_var = false;
    5871                 :      19095 :       usevi->is_reg_var = true;
    5872                 :            : 
    5873                 :      19095 :       gcc_assert (prev_vi->offset < usevi->offset);
    5874                 :      19095 :       prev_vi->next = usevi->id;
    5875                 :      19095 :       prev_vi = usevi;
    5876                 :            :     }
    5877                 :            : 
    5878                 :            :   /* And one for the static chain.  */
    5879                 :      19095 :   if (fn->static_chain_decl != NULL_TREE)
    5880                 :            :     {
    5881                 :        141 :       varinfo_t chainvi;
    5882                 :        141 :       const char *newname;
    5883                 :        141 :       char *tempname;
    5884                 :            : 
    5885                 :        141 :       tempname = xasprintf ("%s.chain", name);
    5886                 :        141 :       newname = ggc_strdup (tempname);
    5887                 :        141 :       free (tempname);
    5888                 :            : 
    5889                 :        141 :       chainvi = new_var_info (fn->static_chain_decl, newname, false);
    5890                 :        141 :       chainvi->offset = fi_static_chain;
    5891                 :        141 :       chainvi->size = 1;
    5892                 :        141 :       chainvi->fullsize = vi->fullsize;
    5893                 :        141 :       chainvi->is_full_var = true;
    5894                 :        141 :       chainvi->is_global_var = false;
    5895                 :            : 
    5896                 :        141 :       insert_vi_for_tree (fn->static_chain_decl, chainvi);
    5897                 :            : 
    5898                 :        141 :       if (nonlocal_p
    5899                 :          0 :           && chainvi->may_have_pointers)
    5900                 :          0 :         make_constraint_from (chainvi, nonlocal_id);
    5901                 :            : 
    5902                 :        141 :       gcc_assert (prev_vi->offset < chainvi->offset);
    5903                 :        141 :       prev_vi->next = chainvi->id;
    5904                 :        141 :       prev_vi = chainvi;
    5905                 :            :     }
    5906                 :            : 
    5907                 :            :   /* Create a variable for the return var.  */
    5908                 :      19095 :   if (DECL_RESULT (decl) != NULL
    5909                 :      19095 :       || !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
    5910                 :            :     {
    5911                 :      19095 :       varinfo_t resultvi;
    5912                 :      19095 :       const char *newname;
    5913                 :      19095 :       char *tempname;
    5914                 :      19095 :       tree resultdecl = decl;
    5915                 :            : 
    5916                 :      19095 :       if (DECL_RESULT (decl))
    5917                 :      19095 :         resultdecl = DECL_RESULT (decl);
    5918                 :            : 
    5919                 :      19095 :       tempname = xasprintf ("%s.result", name);
    5920                 :      19095 :       newname = ggc_strdup (tempname);
    5921                 :      19095 :       free (tempname);
    5922                 :            : 
    5923                 :      19095 :       resultvi = new_var_info (resultdecl, newname, false);
    5924                 :      19095 :       resultvi->offset = fi_result;
    5925                 :      19095 :       resultvi->size = 1;
    5926                 :      19095 :       resultvi->fullsize = vi->fullsize;
    5927                 :      19095 :       resultvi->is_full_var = true;
    5928                 :      19095 :       if (DECL_RESULT (decl))
    5929                 :      19095 :         resultvi->may_have_pointers = true;
    5930                 :            : 
    5931                 :      19095 :       if (DECL_RESULT (decl))
    5932                 :      19095 :         insert_vi_for_tree (DECL_RESULT (decl), resultvi);
    5933                 :            : 
    5934                 :      19095 :       if (nonlocal_p
    5935                 :       5839 :           && DECL_RESULT (decl)
    5936                 :      30773 :           && DECL_BY_REFERENCE (DECL_RESULT (decl)))
    5937                 :          8 :         make_constraint_from (resultvi, nonlocal_id);
    5938                 :            : 
    5939                 :      19095 :       gcc_assert (prev_vi->offset < resultvi->offset);
    5940                 :      19095 :       prev_vi->next = resultvi->id;
    5941                 :      19095 :       prev_vi = resultvi;
    5942                 :            :     }
    5943                 :            : 
    5944                 :            :   /* We also need to make function return values escape.  Nothing
    5945                 :            :      escapes by returning from main though.  */
    5946                 :      19095 :   if (nonlocal_p
    5947                 :      24934 :       && !MAIN_NAME_P (DECL_NAME (decl)))
    5948                 :            :     {
    5949                 :       2820 :       varinfo_t fi, rvi;
    5950                 :       2820 :       fi = lookup_vi_for_tree (decl);
    5951                 :       2820 :       rvi = first_vi_for_offset (fi, fi_result);
    5952                 :       2820 :       if (rvi && rvi->offset == fi_result)
    5953                 :       2820 :         make_copy_constraint (get_varinfo (escaped_id), rvi->id);
    5954                 :            :     }
    5955                 :            : 
    5956                 :            :   /* Set up variables for each argument.  */
    5957                 :      19095 :   arg = DECL_ARGUMENTS (decl);
    5958                 :      40196 :   for (i = 0; i < num_args; i++)
    5959                 :            :     {
    5960                 :      21101 :       varinfo_t argvi;
    5961                 :      21101 :       const char *newname;
    5962                 :      21101 :       char *tempname;
    5963                 :      21101 :       tree argdecl = decl;
    5964                 :            : 
    5965                 :      21101 :       if (arg)
    5966                 :      21101 :         argdecl = arg;
    5967                 :            : 
    5968                 :      21101 :       tempname = xasprintf ("%s.arg%d", name, i);
    5969                 :      21101 :       newname = ggc_strdup (tempname);
    5970                 :      21101 :       free (tempname);
    5971                 :            : 
    5972                 :      21101 :       argvi = new_var_info (argdecl, newname, false);
    5973                 :      21101 :       argvi->offset = fi_parm_base + i;
    5974                 :      21101 :       argvi->size = 1;
    5975                 :      21101 :       argvi->is_full_var = true;
    5976                 :      21101 :       argvi->fullsize = vi->fullsize;
    5977                 :      21101 :       if (arg)
    5978                 :      21101 :         argvi->may_have_pointers = true;
    5979                 :            : 
    5980                 :      21101 :       if (arg)
    5981                 :      21101 :         insert_vi_for_tree (arg, argvi);
    5982                 :            : 
    5983                 :      21101 :       if (nonlocal_p
    5984                 :       7844 :           && argvi->may_have_pointers)
    5985                 :       7844 :         make_constraint_from (argvi, nonlocal_id);
    5986                 :            : 
    5987                 :      21101 :       gcc_assert (prev_vi->offset < argvi->offset);
    5988                 :      21101 :       prev_vi->next = argvi->id;
    5989                 :      21101 :       prev_vi = argvi;
    5990                 :      21101 :       if (arg)
    5991                 :      21101 :         arg = DECL_CHAIN (arg);
    5992                 :            :     }
    5993                 :            : 
    5994                 :            :   /* Add one representative for all further args.  */
    5995                 :      19095 :   if (is_varargs)
    5996                 :            :     {
    5997                 :        478 :       varinfo_t argvi;
    5998                 :        478 :       const char *newname;
    5999                 :        478 :       char *tempname;
    6000                 :        478 :       tree decl;
    6001                 :            : 
    6002                 :        478 :       tempname = xasprintf ("%s.varargs", name);
    6003                 :        478 :       newname = ggc_strdup (tempname);
    6004                 :        478 :       free (tempname);
    6005                 :            : 
    6006                 :            :       /* We need sth that can be pointed to for va_start.  */
    6007                 :        478 :       decl = build_fake_var_decl (ptr_type_node);
    6008                 :            : 
    6009                 :        478 :       argvi = new_var_info (decl, newname, false);
    6010                 :        478 :       argvi->offset = fi_parm_base + num_args;
    6011                 :        478 :       argvi->size = ~0;
    6012                 :        478 :       argvi->is_full_var = true;
    6013                 :        478 :       argvi->is_heap_var = true;
    6014                 :        478 :       argvi->fullsize = vi->fullsize;
    6015                 :            : 
    6016                 :        478 :       if (nonlocal_p
    6017                 :        434 :           && argvi->may_have_pointers)
    6018                 :        434 :         make_constraint_from (argvi, nonlocal_id);
    6019                 :            : 
    6020                 :        478 :       gcc_assert (prev_vi->offset < argvi->offset);
    6021                 :        478 :       prev_vi->next = argvi->id;
    6022                 :            :     }
    6023                 :            : 
    6024                 :      19095 :   return vi;
    6025                 :            : }
    6026                 :            : 
    6027                 :            : 
    6028                 :            : /* Return true if FIELDSTACK contains fields that overlap.
    6029                 :            :    FIELDSTACK is assumed to be sorted by offset.  */
    6030                 :            : 
    6031                 :            : static bool
    6032                 :    5425620 : check_for_overlaps (vec<fieldoff_s> fieldstack)
    6033                 :            : {
    6034                 :    5425620 :   fieldoff_s *fo = NULL;
    6035                 :    5425620 :   unsigned int i;
    6036                 :    5425620 :   HOST_WIDE_INT lastoffset = -1;
    6037                 :            : 
    6038                 :   21963000 :   FOR_EACH_VEC_ELT (fieldstack, i, fo)
    6039                 :            :     {
    6040                 :   16546400 :       if (fo->offset == lastoffset)
    6041                 :            :         return true;
    6042                 :   16537300 :       lastoffset = fo->offset;
    6043                 :            :     }
    6044                 :            :   return false;
    6045                 :            : }
    6046                 :            : 
    6047                 :            : /* Create a varinfo structure for NAME and DECL, and add it to VARMAP.
    6048                 :            :    This will also create any varinfo structures necessary for fields
    6049                 :            :    of DECL.  DECL is a function parameter if HANDLE_PARAM is set.
    6050                 :            :    HANDLED_STRUCT_TYPE is used to register struct types reached by following
    6051                 :            :    restrict pointers.  This is needed to prevent infinite recursion.
    6052                 :            :    If ADD_RESTRICT, pretend that the pointer NAME is restrict even if DECL
    6053                 :            :    does not advertise it.  */
    6054                 :            : 
    6055                 :            : static varinfo_t
    6056                 :   61806800 : create_variable_info_for_1 (tree decl, const char *name, bool add_id,
    6057                 :            :                             bool handle_param, bitmap handled_struct_type,
    6058                 :            :                             bool add_restrict = false)
    6059                 :            : {
    6060                 :   61806800 :   varinfo_t vi, newvi;
    6061                 :   61806800 :   tree decl_type = TREE_TYPE (decl);
    6062                 :  123614000 :   tree declsize = DECL_P (decl) ? DECL_SIZE (decl) : TYPE_SIZE (decl_type);
    6063                 :   61806800 :   auto_vec<fieldoff_s> fieldstack;
    6064                 :   61806800 :   fieldoff_s *fo;
    6065                 :   61806800 :   unsigned int i;
    6066                 :            : 
    6067                 :   61806800 :   if (!declsize
    6068                 :   54643300 :       || !tree_fits_uhwi_p (declsize))
    6069                 :            :     {
    6070                 :    7174270 :       vi = new_var_info (decl, name, add_id);
    6071                 :    7174270 :       vi->offset = 0;
    6072                 :    7174270 :       vi->size = ~0;
    6073                 :    7174270 :       vi->fullsize = ~0;
    6074                 :    7174270 :       vi->is_unknown_size_var = true;
    6075                 :    7174270 :       vi->is_full_var = true;
    6076                 :    7174270 :       vi->may_have_pointers = true;
    6077                 :    7174270 :       return vi;
    6078                 :            :     }
    6079                 :            : 
    6080                 :            :   /* Collect field information.  */
    6081                 :   54632600 :   if (use_field_sensitive
    6082                 :   52361400 :       && var_can_have_subvars (decl)
    6083                 :            :       /* ???  Force us to not use subfields for globals in IPA mode.
    6084                 :            :          Else we'd have to parse arbitrary initializers.  */
    6085                 :   54646700 :       && !(in_ipa_mode
    6086                 :    5450560 :            && is_global_var (decl)))
    6087                 :            :     {
    6088                 :    5450230 :       fieldoff_s *fo = NULL;
    6089                 :    5450230 :       bool notokay = false;
    6090                 :    5450230 :       unsigned int i;
    6091                 :            : 
    6092                 :    5450230 :       push_fields_onto_fieldstack (decl_type, &fieldstack, 0);
    6093                 :            : 
    6094                 :   22441300 :       for (i = 0; !notokay && fieldstack.iterate (i, &fo); i++)
    6095                 :   17015600 :         if (fo->has_unknown_size
    6096                 :   17015600 :             || fo->offset < 0)
    6097                 :            :           {
    6098                 :            :             notokay = true;
    6099                 :            :             break;
    6100                 :            :           }
    6101                 :            : 
    6102                 :            :       /* We can't sort them if we have a field with a variable sized type,
    6103                 :            :          which will make notokay = true.  In that case, we are going to return
    6104                 :            :          without creating varinfos for the fields anyway, so sorting them is a
    6105                 :            :          waste to boot.  */
    6106                 :    5450230 :       if (!notokay)
    6107                 :            :         {
    6108                 :    5425620 :           sort_fieldstack (fieldstack);
    6109                 :            :           /* Due to some C++ FE issues, like PR 22488, we might end up
    6110                 :            :              what appear to be overlapping fields even though they,
    6111                 :            :              in reality, do not overlap.  Until the C++ FE is fixed,
    6112                 :            :              we will simply disable field-sensitivity for these cases.  */
    6113                 :    5425620 :           notokay = check_for_overlaps (fieldstack);
    6114                 :            :         }
    6115                 :            : 
    6116                 :    5450230 :       if (notokay)
    6117                 :      33622 :         fieldstack.release ();
    6118                 :            :     }
    6119                 :            : 
    6120                 :            :   /* If we didn't end up collecting sub-variables create a full
    6121                 :            :      variable for the decl.  */
    6122                 :   54632600 :   if (fieldstack.length () == 0
    6123                 :    5160520 :       || fieldstack.length () > (unsigned)param_max_fields_for_field_sensitive)
    6124                 :            :     {
    6125                 :   49472300 :       vi = new_var_info (decl, name, add_id);
    6126                 :   49472300 :       vi->offset = 0;
    6127                 :   49472300 :       vi->may_have_pointers = true;
    6128                 :   49472300 :       vi->fullsize = tree_to_uhwi (declsize);
    6129                 :   49472300 :       vi->size = vi->fullsize;
    6130                 :   49472300 :       vi->is_full_var = true;
    6131                 :   49472300 :       if (POINTER_TYPE_P (decl_type)
    6132                 :   65080700 :           && (TYPE_RESTRICT (decl_type) || add_restrict))
    6133                 :     585682 :         vi->only_restrict_pointers = 1;
    6134                 :   49472300 :       if (vi->only_restrict_pointers
    6135                 :     585682 :           && !type_contains_placeholder_p (TREE_TYPE (decl_type))
    6136                 :     585682 :           && handle_param
    6137                 :   49867400 :           && !bitmap_bit_p (handled_struct_type,
    6138                 :     395074 :                             TYPE_UID (TREE_TYPE (decl_type))))
    6139                 :            :         {
    6140                 :     395074 :           varinfo_t rvi;
    6141                 :     395074 :           tree heapvar = build_fake_var_decl (TREE_TYPE (decl_type));
    6142                 :     395074 :           DECL_EXTERNAL (heapvar) = 1;
    6143                 :     395074 :           if (var_can_have_subvars (heapvar))
    6144                 :     315596 :             bitmap_set_bit (handled_struct_type,
    6145                 :     315596 :                             TYPE_UID (TREE_TYPE (decl_type)));
    6146                 :     395074 :           rvi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS", true,
    6147                 :            :                                             true, handled_struct_type);
    6148                 :     395074 :           if (var_can_have_subvars (heapvar))
    6149                 :     315596 :             bitmap_clear_bit (handled_struct_type,
    6150                 :     315596 :                               TYPE_UID (TREE_TYPE (decl_type)));
    6151                 :     395074 :           rvi->is_restrict_var = 1;
    6152                 :     395074 :           insert_vi_for_tree (heapvar, rvi);
    6153                 :     395074 :           make_constraint_from (vi, rvi->id);
    6154                 :     395074 :           make_param_constraints (rvi);
    6155                 :            :         }
    6156                 :   49472300 :       fieldstack.release ();
    6157                 :   49472300 :       return vi;
    6158                 :            :     }
    6159                 :            : 
    6160                 :    5160250 :   vi = new_var_info (decl, name, add_id);
    6161                 :    5160250 :   vi->fullsize = tree_to_uhwi (declsize);
    6162                 :    5160250 :   if (fieldstack.length () == 1)
    6163                 :     856991 :     vi->is_full_var = true;
    6164                 :   16486800 :   for (i = 0, newvi = vi;
    6165                 :   83453900 :        fieldstack.iterate (i, &fo);
    6166                 :   16486800 :        ++i, newvi = vi_next (newvi))
    6167                 :            :     {
    6168                 :   16486800 :       const char *newname = NULL;
    6169                 :   16486800 :       char *tempname;
    6170                 :            : 
    6171                 :   16486800 :       if (dump_file)
    6172                 :            :         {
    6173                 :        370 :           if (fieldstack.length () != 1)
    6174                 :            :             {
    6175                 :        339 :               tempname
    6176                 :        339 :                 = xasprintf ("%s." HOST_WIDE_INT_PRINT_DEC
    6177                 :            :                              "+" HOST_WIDE_INT_PRINT_DEC, name,
    6178                 :            :                              fo->offset, fo->size);
    6179                 :        339 :               newname = ggc_strdup (tempname);
    6180                 :        339 :               free (tempname);
    6181                 :            :             }
    6182                 :            :         }
    6183                 :            :       else
    6184                 :            :         newname = "NULL";
    6185                 :            : 
    6186                 :   16486700 :       if (newname)
    6187                 :   16486700 :           newvi->name = newname;
    6188                 :   16486800 :       newvi->offset = fo->offset;
    6189                 :   16486800 :       newvi->size = fo->size;
    6190                 :   16486800 :       newvi->fullsize = vi->fullsize;
    6191                 :   16486800 :       newvi->may_have_pointers = fo->may_have_pointers;
    6192                 :   16486800 :       newvi->only_restrict_pointers = fo->only_restrict_pointers;
    6193                 :   16486800 :       if (handle_param
    6194                 :    1190360 :           && newvi->only_restrict_pointers
    6195                 :      12767 :           && !type_contains_placeholder_p (fo->restrict_pointed_type)
    6196                 :   16499500 :           && !bitmap_bit_p (handled_struct_type,
    6197                 :      12767 :                             TYPE_UID (fo->restrict_pointed_type)))
    6198                 :            :         {
    6199                 :      12764 :           varinfo_t rvi;
    6200                 :      12764 :           tree heapvar = build_fake_var_decl (fo->restrict_pointed_type);
    6201                 :      12764 :           DECL_EXTERNAL (heapvar) = 1;
    6202                 :      12764 :           if (var_can_have_subvars (heapvar))
    6203                 :        136 :             bitmap_set_bit (handled_struct_type,
    6204                 :         68 :                             TYPE_UID (fo->restrict_pointed_type));
    6205                 :      12764 :           rvi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS", true,
    6206                 :            :                                             true, handled_struct_type);
    6207                 :      12764 :           if (var_can_have_subvars (heapvar))
    6208                 :        136 :             bitmap_clear_bit (handled_struct_type,
    6209                 :         68 :                               TYPE_UID (fo->restrict_pointed_type));
    6210                 :      12764 :           rvi->is_restrict_var = 1;
    6211                 :      12764 :           insert_vi_for_tree (heapvar, rvi);
    6212                 :      12764 :           make_constraint_from (newvi, rvi->id);
    6213                 :      12764 :           make_param_constraints (rvi);
    6214                 :            :         }
    6215                 :   32973500 :       if (i + 1 < fieldstack.length ())
    6216                 :            :         {
    6217                 :   11326500 :           varinfo_t tem = new_var_info (decl, name, false);
    6218                 :   11326500 :           newvi->next = tem->id;
    6219                 :   11326500 :           tem->head = vi->id;
    6220                 :            :         }
    6221                 :            :     }
    6222                 :            : 
    6223                 :            :   return vi;
    6224                 :            : }
    6225                 :            : 
    6226                 :            : static unsigned int
    6227                 :   55237800 : create_variable_info_for (tree decl, const char *name, bool add_id)
    6228                 :            : {
    6229                 :            :   /* First see if we are dealing with an ifunc resolver call and
    6230                 :            :      assiociate that with a call to the resolver function result.  */
    6231                 :   55237800 :   cgraph_node *node;
    6232                 :   55237800 :   if (in_ipa_mode
    6233                 :     545077 :       && TREE_CODE (decl) == FUNCTION_DECL
    6234                 :      13165 :       && (node = cgraph_node::get (decl))
    6235                 :   55251000 :       && node->ifunc_resolver)
    6236                 :            :     {
    6237                 :          2 :       varinfo_t fi = get_vi_for_tree (node->get_alias_target ()->decl);
    6238                 :          1 :       constraint_expr rhs
    6239                 :          1 :         = get_function_part_constraint (fi, fi_result);
    6240                 :          1 :       fi = new_var_info (NULL_TREE, "ifuncres", true);
    6241                 :          1 :       fi->is_reg_var = true;
    6242                 :          1 :       constraint_expr lhs;
    6243                 :          1 :       lhs.type = SCALAR;
    6244                 :          1 :       lhs.var = fi->id;
    6245                 :          1 :       lhs.offset = 0;
    6246                 :          1 :       process_constraint (new_constraint (lhs, rhs));
    6247                 :          1 :       insert_vi_for_tree (decl, fi);
    6248                 :          1 :       return fi->id;
    6249                 :            :     }
    6250                 :            : 
    6251                 :   55237800 :   varinfo_t vi = create_variable_info_for_1 (decl, name, add_id, false, NULL);
    6252                 :   55237800 :   unsigned int id = vi->id;
    6253                 :            : 
    6254                 :   55237800 :   insert_vi_for_tree (decl, vi);
    6255                 :            : 
    6256                 :   55237800 :   if (!VAR_P (decl))
    6257                 :            :     return id;
    6258                 :            : 
    6259                 :            :   /* Create initial constraints for globals.  */
    6260                 :   24489500 :   for (; vi; vi = vi_next (vi))
    6261                 :            :     {
    6262                 :   28516900 :       if (!vi->may_have_pointers
    6263                 :   17482000 :           || !vi->is_global_var)
    6264                 :   11034900 :         continue;
    6265                 :            : 
    6266                 :            :       /* Mark global restrict qualified pointers.  */
    6267                 :   12685000 :       if ((POINTER_TYPE_P (TREE_TYPE (decl))
    6268                 :     209493 :            && TYPE_RESTRICT (TREE_TYPE (decl)))
    6269                 :   12892200 :           || vi->only_restrict_pointers)
    6270                 :            :         {
    6271                 :       5589 :           varinfo_t rvi
    6272                 :       5589 :             = make_constraint_from_global_restrict (vi, "GLOBAL_RESTRICT",
    6273                 :            :                                                     true);
    6274                 :            :           /* ???  For now exclude reads from globals as restrict sources
    6275                 :            :              if those are not (indirectly) from incoming parameters.  */
    6276                 :       5589 :           rvi->is_restrict_var = false;
    6277                 :       5589 :           continue;
    6278                 :            :         }
    6279                 :            : 
    6280                 :            :       /* In non-IPA mode the initializer from nonlocal is all we need.  */
    6281                 :    6441570 :       if (!in_ipa_mode
    6282                 :    6469100 :           || DECL_HARD_REGISTER (decl))
    6283                 :    6414050 :         make_copy_constraint (vi, nonlocal_id);
    6284                 :            : 
    6285                 :            :       /* In IPA mode parse the initializer and generate proper constraints
    6286                 :            :          for it.  */
    6287                 :            :       else
    6288                 :            :         {
    6289                 :      27523 :           varpool_node *vnode = varpool_node::get (decl);
    6290                 :            : 
    6291                 :            :           /* For escaped variables initialize them from nonlocal.  */
    6292                 :      27523 :           if (!vnode->all_refs_explicit_p ())
    6293                 :        937 :             make_copy_constraint (vi, nonlocal_id);
    6294                 :            : 
    6295                 :            :           /* If this is a global variable with an initializer and we are in
    6296                 :            :              IPA mode generate constraints for it.  */
    6297                 :            :           ipa_ref *ref;
    6298                 :   17482700 :           for (unsigned idx = 0; vnode->iterate_reference (idx, ref); ++idx)
    6299                 :            :             {
    6300                 :        956 :               auto_vec<ce_s> rhsc;
    6301                 :        478 :               struct constraint_expr lhs, *rhsp;
    6302                 :        478 :               unsigned i;
    6303                 :        478 :               get_constraint_for_address_of (ref->referred->decl, &rhsc);
    6304                 :        478 :               lhs.var = vi->id;
    6305                 :        478 :               lhs.offset = 0;
    6306                 :        478 :               lhs.type = SCALAR;
    6307                 :        956 :               FOR_EACH_VEC_ELT (rhsc, i, rhsp)
    6308                 :        478 :                 process_constraint (new_constraint (lhs, *rhsp));
    6309                 :            :               /* If this is a variable that escapes from the unit
    6310                 :            :                  the initializer escapes as well.  */
    6311                 :        478 :               if (!vnode->all_refs_explicit_p ())
    6312                 :            :                 {
    6313                 :        840 :                   lhs.var = escaped_id;
    6314                 :        840 :                   lhs.offset = 0;
    6315                 :        840 :                   lhs.type = SCALAR;
    6316                 :       1318 :                   FOR_EACH_VEC_ELT (rhsc, i, rhsp)
    6317                 :        420 :                     process_constraint (new_constraint (lhs, *rhsp));
    6318                 :            :                 }
    6319                 :            :             }
    6320                 :            :         }
    6321                 :            :     }
    6322                 :            : 
    6323                 :            :   return id;
    6324                 :            : }
    6325                 :            : 
    6326                 :            : /* Print out the points-to solution for VAR to FILE.  */
    6327                 :            : 
    6328                 :            : static void
    6329                 :       7647 : dump_solution_for_var (FILE *file, unsigned int var)
    6330                 :            : {
    6331                 :       7647 :   varinfo_t vi = get_varinfo (var);
    6332                 :       7647 :   unsigned int i;
    6333                 :       7647 :   bitmap_iterator bi;
    6334                 :            : 
    6335                 :            :   /* Dump the solution for unified vars anyway, this avoids difficulties
    6336                 :            :      in scanning dumps in the testsuite.  */
    6337                 :       7647 :   fprintf (file, "%s = { ", vi->name);
    6338                 :       7647 :   vi = get_varinfo (find (var));
    6339                 :      18510 :   EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, i, bi)
    6340                 :      10863 :     fprintf (file, "%s ", get_varinfo (i)->name);
    6341                 :       7647 :   fprintf (file, "}");
    6342                 :            : 
    6343                 :            :   /* But note when the variable was unified.  */
    6344                 :       7647 :   if (vi->id != var)
    6345                 :       1398 :     fprintf (file, " same as %s", vi->name);
    6346                 :            : 
    6347                 :       7647 :   fprintf (file, "\n");
    6348                 :       7647 : }
    6349                 :            : 
    6350                 :            : /* Print the points-to solution for VAR to stderr.  */
    6351                 :            : 
    6352                 :            : DEBUG_FUNCTION void
    6353                 :          0 : debug_solution_for_var (unsigned int var)
    6354                 :            : {
    6355                 :          0 :   dump_solution_for_var (stderr, var);
    6356                 :          0 : }
    6357                 :            : 
    6358                 :            : /* Register the constraints for function parameter related VI.  */
    6359                 :            : 
    6360                 :            : static void
    6361                 :    6569050 : make_param_constraints (varinfo_t vi)
    6362                 :            : {
    6363                 :    7573000 :   for (; vi; vi = vi_next (vi))
    6364                 :            :     {
    6365                 :    7222710 :       if (vi->only_restrict_pointers)
    6366                 :            :         ;
    6367                 :    6814870 :       else if (vi->may_have_pointers)
    6368                 :    6814870 :         make_constraint_from (vi, nonlocal_id);
    6369                 :            : 
    6370                 :    7222710 :       if (vi->is_full_var)
    6371                 :            :         break;
    6372                 :            :     }
    6373                 :    6569050 : }
    6374                 :            : 
    6375                 :            : /* Create varinfo structures for all of the variables in the
    6376                 :            :    function for intraprocedural mode.  */
    6377                 :            : 
    6378                 :            : static void
    6379                 :    2915140 : intra_create_variable_infos (struct function *fn)
    6380                 :            : {
    6381                 :    2915140 :   tree t;
    6382                 :    2915140 :   bitmap handled_struct_type = NULL;
    6383                 :    2915140 :   bool this_parm_in_ctor = DECL_CXX_CONSTRUCTOR_P (fn->decl);
    6384                 :            : 
    6385                 :            :   /* For each incoming pointer argument arg, create the constraint ARG
    6386                 :            :      = NONLOCAL or a dummy variable if it is a restrict qualified
    6387                 :            :      passed-by-reference argument.  */
    6388                 :    9076350 :   for (t = DECL_ARGUMENTS (fn->decl); t; t = DECL_CHAIN (t))
    6389                 :            :     {
    6390                 :    6161210 :       if (handled_struct_type == NULL)
    6391                 :    2423120 :         handled_struct_type = BITMAP_ALLOC (NULL);
    6392                 :            : 
    6393                 :    6161210 :       varinfo_t p
    6394                 :    6161210 :         = create_variable_info_for_1 (t, alias_get_name (t), false, true,
    6395                 :            :                                       handled_struct_type, this_parm_in_ctor);
    6396                 :    6161210 :       insert_vi_for_tree (t, p);
    6397                 :            : 
    6398                 :    6161210 :       make_param_constraints (p);
    6399                 :            : 
    6400                 :    6161210 :       this_parm_in_ctor = false;
    6401                 :            :     }
    6402                 :            : 
    6403                 :    2915140 :   if (handled_struct_type != NULL)
    6404                 :    2423120 :     BITMAP_FREE (handled_struct_type);
    6405                 :            : 
    6406                 :            :   /* Add a constraint for a result decl that is passed by reference.  */
    6407                 :    2915140 :   if (DECL_RESULT (fn->decl)
    6408                 :    5830280 :       && DECL_BY_REFERENCE (DECL_RESULT (fn->decl)))
    6409                 :            :     {
    6410                 :      34490 :       varinfo_t p, result_vi = get_vi_for_tree (DECL_RESULT (fn->decl));
    6411                 :            : 
    6412                 :      68980 :       for (p = result_vi; p; p = vi_next (p))
    6413                 :      34490 :         make_constraint_from (p, nonlocal_id);
    6414                 :            :     }
    6415                 :            : 
    6416                 :            :   /* Add a constraint for the incoming static chain parameter.  */
    6417                 :    2915140 :   if (fn->static_chain_decl != NULL_TREE)
    6418                 :            :     {
    6419                 :      37266 :       varinfo_t p, chain_vi = get_vi_for_tree (fn->static_chain_decl);
    6420                 :            : 
    6421                 :      74532 :       for (p = chain_vi; p; p = vi_next (p))
    6422                 :      37266 :         make_constraint_from (p, nonlocal_id);
    6423                 :            :     }
    6424                 :    2915140 : }
    6425                 :            : 
    6426                 :            : /* Structure used to put solution bitmaps in a hashtable so they can
    6427                 :            :    be shared among variables with the same points-to set.  */
    6428                 :            : 
    6429                 :            : typedef struct shared_bitmap_info
    6430                 :            : {
    6431                 :            :   bitmap pt_vars;
    6432                 :            :   hashval_t hashcode;
    6433                 :            : } *shared_bitmap_info_t;
    6434                 :            : typedef const struct shared_bitmap_info *const_shared_bitmap_info_t;
    6435                 :            : 
    6436                 :            : /* Shared_bitmap hashtable helpers.  */
    6437                 :            : 
    6438                 :            : struct shared_bitmap_hasher : free_ptr_hash <shared_bitmap_info>
    6439                 :            : {
    6440                 :            :   static inline hashval_t hash (const shared_bitmap_info *);
    6441                 :            :   static inline bool equal (const shared_bitmap_info *,
    6442                 :            :                             const shared_bitmap_info *);
    6443                 :            : };
    6444                 :            : 
    6445                 :            : /* Hash function for a shared_bitmap_info_t */
    6446                 :            : 
    6447                 :            : inline hashval_t
    6448                 :   28493200 : shared_bitmap_hasher::hash (const shared_bitmap_info *bi)
    6449                 :            : {
    6450                 :   28493200 :   return bi->hashcode;
    6451                 :            : }
    6452                 :            : 
    6453                 :            : /* Equality function for two shared_bitmap_info_t's. */
    6454                 :            : 
    6455                 :            : inline bool
    6456                 :   14427200 : shared_bitmap_hasher::equal (const shared_bitmap_info *sbi1,
    6457                 :            :                              const shared_bitmap_info *sbi2)
    6458                 :            : {
    6459                 :   14427200 :   return bitmap_equal_p (sbi1->pt_vars, sbi2->pt_vars);
    6460                 :            : }
    6461                 :            : 
    6462                 :            : /* Shared_bitmap hashtable.  */
    6463                 :            : 
    6464                 :            : static hash_table<shared_bitmap_hasher> *shared_bitmap_table;
    6465                 :            : 
    6466                 :            : /* Lookup a bitmap in the shared bitmap hashtable, and return an already
    6467                 :            :    existing instance if there is one, NULL otherwise.  */
    6468                 :            : 
    6469                 :            : static bitmap
    6470                 :   13117300 : shared_bitmap_lookup (bitmap pt_vars)
    6471                 :            : {
    6472                 :   13117300 :   shared_bitmap_info **slot;
    6473                 :   13117300 :   struct shared_bitmap_info sbi;
    6474                 :            : 
    6475                 :   13117300 :   sbi.pt_vars = pt_vars;
    6476                 :   13117300 :   sbi.hashcode = bitmap_hash (pt_vars);
    6477                 :            : 
    6478                 :   13117300 :   slot = shared_bitmap_table->find_slot (&sbi, NO_INSERT);
    6479                 :   13117300 :   if (!slot)
    6480                 :            :     return NULL;
    6481                 :            :   else
    6482                 :    8524260 :     return (*slot)->pt_vars;
    6483                 :            : }
    6484                 :            : 
    6485                 :            : 
    6486                 :            : /* Add a bitmap to the shared bitmap hashtable.  */
    6487                 :            : 
    6488                 :            : static void
    6489                 :    4593040 : shared_bitmap_add (bitmap pt_vars)
    6490                 :            : {
    6491                 :    4593040 :   shared_bitmap_info **slot;
    6492                 :    4593040 :   shared_bitmap_info_t sbi = XNEW (struct shared_bitmap_info);
    6493                 :            : 
    6494                 :    4593040 :   sbi->pt_vars = pt_vars;
    6495                 :    4593040 :   sbi->hashcode = bitmap_hash (pt_vars);
    6496                 :            : 
    6497                 :    4593040 :   slot = shared_bitmap_table->find_slot (sbi, INSERT);
    6498                 :    4593040 :   gcc_assert (!*slot);
    6499                 :    4593040 :   *slot = sbi;
    6500                 :    4593040 : }
    6501                 :            : 
    6502                 :            : 
    6503                 :            : /* Set bits in INTO corresponding to the variable uids in solution set FROM.  */
    6504                 :            : 
    6505                 :            : static void
    6506                 :   13117300 : set_uids_in_ptset (bitmap into, bitmap from, struct pt_solution *pt,
    6507                 :            :                    tree fndecl)
    6508                 :            : {
    6509                 :   13117300 :   unsigned int i;
    6510                 :   13117300 :   bitmap_iterator bi;
    6511                 :   13117300 :   varinfo_t escaped_vi = get_varinfo (find (escaped_id));
    6512                 :   13117300 :   bool everything_escaped
    6513                 :   13117300 :     = escaped_vi->solution && bitmap_bit_p (escaped_vi->solution, anything_id);
    6514                 :            : 
    6515                 :   56316000 :   EXECUTE_IF_SET_IN_BITMAP (from, 0, i, bi)
    6516                 :            :     {
    6517                 :   43198700 :       varinfo_t vi = get_varinfo (i);
    6518                 :            : 
    6519                 :   43198700 :       if (vi->is_artificial_var)
    6520                 :   20801600 :         continue;
    6521                 :            : 
    6522                 :   22397100 :       if (everything_escaped
    6523                 :   22397100 :           || (escaped_vi->solution
    6524                 :   21930200 :               && bitmap_bit_p (escaped_vi->solution, i)))
    6525                 :            :         {
    6526                 :   13827200 :           pt->vars_contains_escaped = true;
    6527                 :   13827200 :           pt->vars_contains_escaped_heap |= vi->is_heap_var;
    6528                 :            :         }
    6529                 :            : 
    6530                 :   22397100 :       if (vi->is_restrict_var)
    6531                 :     715480 :         pt->vars_contains_restrict = true;
    6532                 :            : 
    6533                 :   22397100 :       if (VAR_P (vi->decl)
    6534                 :   22397100 :           || TREE_CODE (vi->decl) == PARM_DECL
    6535                 :     471494 :           || TREE_CODE (vi->decl) == RESULT_DECL)
    6536                 :            :         {
    6537                 :            :           /* If we are in IPA mode we will not recompute points-to
    6538                 :            :              sets after inlining so make sure they stay valid.  */
    6539                 :   21928500 :           if (in_ipa_mode
    6540                 :   21928500 :               && !DECL_PT_UID_SET_P (vi->decl))
    6541                 :      24831 :             SET_DECL_PT_UID (vi->decl, DECL_UID (vi->decl));
    6542                 :            : 
    6543                 :            :           /* Add the decl to the points-to set.  Note that the points-to
    6544                 :            :              set contains global variables.  */
    6545                 :   21928500 :           bitmap_set_bit (into, DECL_PT_UID (vi->decl));
    6546                 :   21928500 :           if (vi->is_global_var
    6547                 :            :               /* In IPA mode the escaped_heap trick doesn't work as
    6548                 :            :                  ESCAPED is escaped from the unit but
    6549                 :            :                  pt_solution_includes_global needs to answer true for
    6550                 :            :                  all variables not automatic within a function.
    6551                 :            :                  For the same reason is_global_var is not the
    6552                 :            :                  correct flag to track - local variables from other
    6553                 :            :                  functions also need to be considered global.
    6554                 :            :                  Conveniently all HEAP vars are not put in function
    6555                 :            :                  scope.  */
    6556                 :   35148800 :               || (in_ipa_mode
    6557                 :   13220300 :                   && fndecl
    6558                 :   22162200 :                   && ! auto_var_in_fn_p (vi->decl, fndecl)))
    6559                 :    8878740 :             pt->vars_contains_nonlocal = true;
    6560                 :            : 
    6561                 :            :           /* If we have a variable that is interposable record that fact
    6562                 :            :              for pointer comparison simplification.  */
    6563                 :   21928500 :           if (VAR_P (vi->decl)
    6564                 :   21844800 :               && (TREE_STATIC (vi->decl) || DECL_EXTERNAL (vi->decl))
    6565                 :   30636800 :               && ! decl_binds_to_current_def_p (vi->decl))
    6566                 :    4983490 :             pt->vars_contains_interposable = true;
    6567                 :            : 
    6568                 :            :           /* If this is a local variable we can have overlapping lifetime
    6569                 :            :              of different function invocations through recursion duplicate
    6570                 :            :              it with its shadow variable.  */
    6571                 :   21928500 :           if (in_ipa_mode
    6572                 :   21928500 :               && vi->shadow_var_uid != 0)
    6573                 :            :             {
    6574                 :     185289 :               bitmap_set_bit (into, vi->shadow_var_uid);
    6575                 :     185289 :               pt->vars_contains_nonlocal = true;
    6576                 :            :             }
    6577                 :            :         }
    6578                 :            : 
    6579                 :     468616 :       else if (TREE_CODE (vi->decl) == FUNCTION_DECL
    6580                 :     468616 :                || TREE_CODE (vi->decl) == LABEL_DECL)
    6581                 :            :         {
    6582                 :            :           /* Nothing should read/write from/to code so we can
    6583                 :            :              save bits by not including them in the points-to bitmaps.
    6584                 :            :              Still mark the points-to set as containing global memory
    6585                 :            :              to make code-patching possible - see PR70128.  */
    6586                 :     348280 :           pt->vars_contains_nonlocal = true;
    6587                 :            :         }
    6588                 :            :     }
    6589                 :   13117300 : }
    6590                 :            : 
    6591                 :            : 
    6592                 :            : /* Compute the points-to solution *PT for the variable VI.  */
    6593                 :            : 
    6594                 :            : static struct pt_solution
    6595                 :   19689200 : find_what_var_points_to (tree fndecl, varinfo_t orig_vi)
    6596                 :            : {
    6597                 :   19689200 :   unsigned int i;
    6598                 :   19689200 :   bitmap_iterator bi;
    6599                 :   19689200 :   bitmap finished_solution;
    6600                 :   19689200 :   bitmap result;
    6601                 :   19689200 :   varinfo_t vi;
    6602                 :   19689200 :   struct pt_solution *pt;
    6603                 :            : 
    6604                 :            :   /* This variable may have been collapsed, let's get the real
    6605                 :            :      variable.  */
    6606                 :   19689200 :   vi = get_varinfo (find (orig_vi->id));
    6607                 :            : 
    6608                 :            :   /* See if we have already computed the solution and return it.  */
    6609                 :   19689200 :   pt_solution **slot = &final_solutions->get_or_insert (vi);
    6610                 :   19689200 :   if (*slot != NULL)
    6611                 :    6518040 :     return **slot;
    6612                 :            : 
    6613                 :   13171100 :   *slot = pt = XOBNEW (&final_solutions_obstack, struct pt_solution);
    6614                 :   13171100 :   memset (pt, 0, sizeof (struct pt_solution));
    6615                 :            : 
    6616                 :            :   /* Translate artificial variables into SSA_NAME_PTR_INFO
    6617                 :            :      attributes.  */
    6618                 :   56893500 :   EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, i, bi)
    6619                 :            :     {
    6620                 :   43722400 :       varinfo_t vi = get_varinfo (i);
    6621                 :            : 
    6622                 :   43722400 :       if (vi->is_artificial_var)
    6623                 :            :         {
    6624                 :   20962500 :           if (vi->id == nothing_id)
    6625                 :    1819830 :             pt->null = 1;
    6626                 :   19142600 :           else if (vi->id == escaped_id)
    6627                 :            :             {
    6628                 :    7647260 :               if (in_ipa_mode)
    6629                 :      38857 :                 pt->ipa_escaped = 1;
    6630                 :            :               else
    6631                 :    7608400 :                 pt->escaped = 1;
    6632                 :            :               /* Expand some special vars of ESCAPED in-place here.  */
    6633                 :    7647260 :               varinfo_t evi = get_varinfo (find (escaped_id));
    6634                 :    7647260 :               if (bitmap_bit_p (evi->solution, nonlocal_id))
    6635                 :    7546140 :                 pt->nonlocal = 1;
    6636                 :            :             }
    6637                 :   11495400 :           else if (vi->id == nonlocal_id)
    6638                 :   10603000 :             pt->nonlocal = 1;
    6639                 :     892384 :           else if (vi->id == string_id)
    6640                 :            :             /* Nobody cares - STRING_CSTs are read-only entities.  */
    6641                 :            :             ;
    6642                 :      59592 :           else if (vi->id == anything_id
    6643                 :       6072 :                    || vi->id == integer_id)
    6644                 :      54000 :             pt->anything = 1;
    6645                 :            :         }
    6646                 :            :     }
    6647                 :            : 
    6648                 :            :   /* Instead of doing extra work, simply do not create
    6649                 :            :      elaborate points-to information for pt_anything pointers.  */
    6650                 :   13171100 :   if (pt->anything)
    6651                 :      53835 :     return *pt;
    6652                 :            : 
    6653                 :            :   /* Share the final set of variables when possible.  */
    6654                 :   13117300 :   finished_solution = BITMAP_GGC_ALLOC ();
    6655                 :   13117300 :   stats.points_to_sets_created++;
    6656                 :            : 
    6657                 :   13117300 :   set_uids_in_ptset (finished_solution, vi->solution, pt, fndecl);
    6658                 :   13117300 :   result = shared_bitmap_lookup (finished_solution);
    6659                 :   13117300 :   if (!result)
    6660                 :            :     {
    6661                 :    4593040 :       shared_bitmap_add (finished_solution);
    6662                 :    4593040 :       pt->vars = finished_solution;
    6663                 :            :     }
    6664                 :            :   else
    6665                 :            :     {
    6666                 :    8524260 :       pt->vars = result;
    6667                 :    8524260 :       bitmap_clear (finished_solution);
    6668                 :            :     }
    6669                 :            : 
    6670                 :   13117300 :   return *pt;
    6671                 :            : }
    6672                 :            : 
    6673                 :            : /* Given a pointer variable P, fill in its points-to set.  */
    6674                 :            : 
    6675                 :            : static void
    6676                 :   15848000 : find_what_p_points_to (tree fndecl, tree p)
    6677                 :            : {
    6678                 :   15848000 :   struct ptr_info_def *pi;
    6679                 :   15848000 :   tree lookup_p = p;
    6680                 :   15848000 :   varinfo_t vi;
    6681                 :   15848000 :   bool nonnull = get_ptr_nonnull (p);
    6682                 :            : 
    6683                 :            :   /* For parameters, get at the points-to set for the actual parm
    6684                 :            :      decl.  */
    6685                 :   15848000 :   if (TREE_CODE (p) == SSA_NAME
    6686                 :   15848000 :       && SSA_NAME_IS_DEFAULT_DEF (p)
    6687                 :   22316500 :       && (TREE_CODE (SSA_NAME_VAR (p)) == PARM_DECL
    6688                 :    1331290 :           || TREE_CODE (SSA_NAME_VAR (p)) == RESULT_DECL))
    6689                 :    2602950 :     lookup_p = SSA_NAME_VAR (p);
    6690                 :            : 
    6691                 :   15848000 :   vi = lookup_vi_for_tree (lookup_p);
    6692                 :   15848000 :   if (!vi)
    6693                 :            :     return;
    6694                 :            : 
    6695                 :   15143800 :   pi = get_ptr_info (p);
    6696                 :   15143800 :   pi->pt = find_what_var_points_to (fndecl, vi);
    6697                 :            :   /* Conservatively set to NULL from PTA (to true). */
    6698                 :   15143800 :   pi->pt.null = 1;
    6699                 :            :   /* Preserve pointer nonnull computed by VRP.  See get_ptr_nonnull
    6700                 :            :      in gcc/tree-ssaname.c for more information.  */
    6701                 :   15143800 :   if (nonnull)
    6702                 :     883605 :     set_ptr_nonnull (p);
    6703                 :            : }
    6704                 :            : 
    6705                 :            : 
    6706                 :            : /* Query statistics for points-to solutions.  */
    6707                 :            : 
    6708                 :            : static struct {
    6709                 :            :   unsigned HOST_WIDE_INT pt_solution_includes_may_alias;
    6710                 :            :   unsigned HOST_WIDE_INT pt_solution_includes_no_alias;
    6711                 :            :   unsigned HOST_WIDE_INT pt_solutions_intersect_may_alias;
    6712                 :            :   unsigned HOST_WIDE_INT pt_solutions_intersect_no_alias;
    6713                 :            : } pta_stats;
    6714                 :            : 
    6715                 :            : void
    6716                 :          0 : dump_pta_stats (FILE *s)
    6717                 :            : {
    6718                 :          0 :   fprintf (s, "\nPTA query stats:\n");
    6719                 :          0 :   fprintf (s, "  pt_solution_includes: "
    6720                 :            :            HOST_WIDE_INT_PRINT_DEC" disambiguations, "
    6721                 :            :            HOST_WIDE_INT_PRINT_DEC" queries\n",
    6722                 :            :            pta_stats.pt_solution_includes_no_alias,
    6723                 :          0 :            pta_stats.pt_solution_includes_no_alias
    6724                 :          0 :            + pta_stats.pt_solution_includes_may_alias);
    6725                 :          0 :   fprintf (s, "  pt_solutions_intersect: "
    6726                 :            :            HOST_WIDE_INT_PRINT_DEC" disambiguations, "
    6727                 :            :            HOST_WIDE_INT_PRINT_DEC" queries\n",
    6728                 :            :            pta_stats.pt_solutions_intersect_no_alias,
    6729                 :          0 :            pta_stats.pt_solutions_intersect_no_alias
    6730                 :          0 :            + pta_stats.pt_solutions_intersect_may_alias);
    6731                 :          0 : }
    6732                 :            : 
    6733                 :            : 
    6734                 :            : /* Reset the points-to solution *PT to a conservative default
    6735                 :            :    (point to anything).  */
    6736                 :            : 
    6737                 :            : void
    6738                 :   34750500 : pt_solution_reset (struct pt_solution *pt)
    6739                 :            : {
    6740                 :   34750500 :   memset (pt, 0, sizeof (struct pt_solution));
    6741                 :   34750500 :   pt->anything = true;
    6742                 :   34750500 :   pt->null = true;
    6743                 :   34750500 : }
    6744                 :            : 
    6745                 :            : /* Set the points-to solution *PT to point only to the variables
    6746                 :            :    in VARS.  VARS_CONTAINS_GLOBAL specifies whether that contains
    6747                 :            :    global variables and VARS_CONTAINS_RESTRICT specifies whether
    6748                 :            :    it contains restrict tag variables.  */
    6749                 :            : 
    6750                 :            : void
    6751                 :      46041 : pt_solution_set (struct pt_solution *pt, bitmap vars,
    6752                 :            :                  bool vars_contains_nonlocal)
    6753                 :            : {
    6754                 :      46041 :   memset (pt, 0, sizeof (struct pt_solution));
    6755                 :      46041 :   pt->vars = vars;
    6756                 :      46041 :   pt->vars_contains_nonlocal = vars_contains_nonlocal;
    6757                 :      46041 :   pt->vars_contains_escaped
    6758                 :      92082 :     = (cfun->gimple_df->escaped.anything
    6759                 :      46041 :        || bitmap_intersect_p (cfun->gimple_df->escaped.vars, vars));
    6760                 :      46041 : }
    6761                 :            : 
    6762                 :            : /* Set the points-to solution *PT to point only to the variable VAR.  */
    6763                 :            : 
    6764                 :            : void
    6765                 :      41443 : pt_solution_set_var (struct pt_solution *pt, tree var)
    6766                 :            : {
    6767                 :      41443 :   memset (pt, 0, sizeof (struct pt_solution));
    6768                 :      41443 :   pt->vars = BITMAP_GGC_ALLOC ();
    6769                 :      41443 :   bitmap_set_bit (pt->vars, DECL_PT_UID (var));
    6770                 :      41443 :   pt->vars_contains_nonlocal = is_global_var (var);
    6771                 :      41443 :   pt->vars_contains_escaped
    6772                 :      82886 :     = (cfun->gimple_df->escaped.anything
    6773                 :      81514 :        || bitmap_bit_p (cfun->gimple_df->escaped.vars, DECL_PT_UID (var)));
    6774                 :      41443 : }
    6775                 :            : 
    6776                 :            : /* Computes the union of the points-to solutions *DEST and *SRC and
    6777                 :            :    stores the result in *DEST.  This changes the points-to bitmap
    6778                 :            :    of *DEST and thus may not be used if that might be shared.
    6779                 :            :    The points-to bitmap of *SRC and *DEST will not be shared after
    6780                 :            :    this function if they were not before.  */
    6781                 :            : 
    6782                 :            : static void
    6783                 :         44 : pt_solution_ior_into (struct pt_solution *dest, struct pt_solution *src)
    6784                 :            : {
    6785                 :         44 :   dest->anything |= src->anything;
    6786                 :         44 :   if (dest->anything)
    6787                 :            :     {
    6788                 :          0 :       pt_solution_reset (dest);
    6789                 :          0 :       return;
    6790                 :            :     }
    6791                 :            : 
    6792                 :         44 :   dest->nonlocal |= src->nonlocal;
    6793                 :         44 :   dest->escaped |= src->escaped;
    6794                 :         44 :   dest->ipa_escaped |= src->ipa_escaped;
    6795                 :         44 :   dest->null |= src->null;
    6796                 :         44 :   dest->vars_contains_nonlocal |= src->vars_contains_nonlocal;
    6797                 :         44 :   dest->vars_contains_escaped |= src->vars_contains_escaped;
    6798                 :         44 :   dest->vars_contains_escaped_heap |= src->vars_contains_escaped_heap;
    6799                 :         44 :   if (!src->vars)
    6800                 :            :     return;
    6801                 :            : 
    6802                 :         44 :   if (!dest->vars)
    6803                 :         26 :     dest->vars = BITMAP_GGC_ALLOC ();
    6804                 :         44 :   bitmap_ior_into (dest->vars, src->vars);
    6805                 :            : }
    6806                 :            : 
    6807                 :            : /* Return true if the points-to solution *PT is empty.  */
    6808                 :            : 
    6809                 :            : bool
    6810                 :      13590 : pt_solution_empty_p (const pt_solution *pt)
    6811                 :            : {
    6812                 :      13590 :   if (pt->anything
    6813                 :      13590 :       || pt->nonlocal)
    6814                 :            :     return false;
    6815                 :            : 
    6816                 :        139 :   if (pt->vars
    6817                 :        139 :       && !bitmap_empty_p (pt->vars))
    6818                 :            :     return false;
    6819                 :            : 
    6820                 :            :   /* If the solution includes ESCAPED, check if that is empty.  */
    6821                 :        139 :   if (pt->escaped
    6822                 :        139 :       && !pt_solution_empty_p (&cfun->gimple_df->escaped))
    6823                 :            :     return false;
    6824                 :            : 
    6825                 :            :   /* If the solution includes ESCAPED, check if that is empty.  */
    6826                 :        139 :   if (pt->ipa_escaped
    6827                 :        139 :       && !pt_solution_empty_p (&ipa_escaped_pt))
    6828                 :          0 :     return false;
    6829                 :            : 
    6830                 :            :   return true;
    6831                 :            : }
    6832                 :            : 
    6833                 :            : /* Return true if the points-to solution *PT only point to a single var, and
    6834                 :            :    return the var uid in *UID.  */
    6835                 :            : 
    6836                 :            : bool
    6837                 :     194436 : pt_solution_singleton_or_null_p (struct pt_solution *pt, unsigned *uid)
    6838                 :            : {
    6839                 :     194436 :   if (pt->anything || pt->nonlocal || pt->escaped || pt->ipa_escaped
    6840                 :      56064 :       || pt->vars == NULL
    6841                 :     250500 :       || !bitmap_single_bit_set_p (pt->vars))
    6842                 :     139750 :     return false;
    6843                 :            : 
    6844                 :      54686 :   *uid = bitmap_first_set_bit (pt->vars);
    6845                 :      54686 :   return true;
    6846                 :            : }
    6847                 :            : 
    6848                 :            : /* Return true if the points-to solution *PT includes global memory.  */
    6849                 :            : 
    6850                 :            : bool
    6851                 :   15299800 : pt_solution_includes_global (struct pt_solution *pt)
    6852                 :            : {
    6853                 :   15299800 :   if (pt->anything
    6854                 :            :       || pt->nonlocal
    6855                 :            :       || pt->vars_contains_nonlocal
    6856                 :            :       /* The following is a hack to make the malloc escape hack work.
    6857                 :            :          In reality we'd need different sets for escaped-through-return
    6858                 :            :          and escaped-to-callees and passes would need to be updated.  */
    6859                 :   15299800 :       || pt->vars_contains_escaped_heap)
    6860                 :            :     return true;
    6861                 :            : 
    6862                 :            :   /* 'escaped' is also a placeholder so we have to look into it.  */
    6863                 :     483673 :   if (pt->escaped)
    6864                 :          0 :     return pt_solution_includes_global (&cfun->gimple_df->escaped);
    6865                 :            : 
    6866                 :     483673 :   if (pt->ipa_escaped)
    6867                 :            :     return pt_solution_includes_global (&ipa_escaped_pt);
    6868                 :            : 
    6869                 :            :   return false;
    6870                 :            : }
    6871                 :            : 
    6872                 :            : /* Return true if the points-to solution *PT includes the variable
    6873                 :            :    declaration DECL.  */
    6874                 :            : 
    6875                 :            : static bool
    6876                 :  149530000 : pt_solution_includes_1 (struct pt_solution *pt, const_tree decl)
    6877                 :            : {
    6878                 :  149530000 :   if (pt->anything)
    6879                 :            :     return true;
    6880                 :            : 
    6881                 :  148676000 :   if (pt->nonlocal
    6882                 :  148676000 :       && is_global_var (decl))
    6883                 :            :     return true;
    6884                 :            : 
    6885                 :  130263000 :   if (pt->vars
    6886                 :  260525000 :       && bitmap_bit_p (pt->vars, DECL_PT_UID (decl)))
    6887                 :            :     return true;
    6888                 :            : 
    6889                 :            :   /* If the solution includes ESCAPED, check it.  */
    6890                 :   91404500 :   if (pt->escaped
    6891                 :   91404500 :       && pt_solution_includes_1 (&cfun->gimple_df->escaped, decl))
    6892                 :            :     return true;
    6893                 :            : 
    6894                 :            :   /* If the solution includes ESCAPED, check it.  */
    6895                 :   68376300 :   if (pt->ipa_escaped
    6896                 :   68376300 :       && pt_solution_includes_1 (&ipa_escaped_pt, decl))
    6897                 :      34476 :     return true;
    6898                 :            : 
    6899                 :            :   return false;
    6900                 :            : }
    6901                 :            : 
    6902                 :            : bool
    6903                 :  101851000 : pt_solution_includes (struct pt_solution *pt, const_tree decl)
    6904                 :            : {
    6905                 :  101851000 :   bool res = pt_solution_includes_1 (pt, decl);
    6906                 :  101851000 :   if (res)
    6907                 :   58125400 :     ++pta_stats.pt_solution_includes_may_alias;
    6908                 :            :   else
    6909                 :   43725700 :     ++pta_stats.pt_solution_includes_no_alias;
    6910                 :  101851000 :   return res;
    6911                 :            : }
    6912                 :            : 
    6913                 :            : /* Return true if both points-to solutions PT1 and PT2 have a non-empty
    6914                 :            :    intersection.  */
    6915                 :            : 
    6916                 :            : static bool
    6917                 :   50699400 : pt_solutions_intersect_1 (struct pt_solution *pt1, struct pt_solution *pt2)
    6918                 :            : {
    6919                 :   50699400 :   if (pt1->anything || pt2->anything)
    6920                 :            :     return true;
    6921                 :            : 
    6922                 :            :   /* If either points to unknown global memory and the other points to
    6923                 :            :      any global memory they alias.  */
    6924                 :   50442800 :   if ((pt1->nonlocal
    6925                 :   35753400 :        && (pt2->nonlocal
    6926                 :   50442800 :            || pt2->vars_contains_nonlocal))
    6927                 :   21085900 :       || (pt2->nonlocal
    6928                 :   21085900 :           && pt1->vars_contains_nonlocal))
    6929                 :            :     return true;
    6930                 :            : 
    6931                 :            :   /* If either points to all escaped memory and the other points to
    6932                 :            :      any escaped memory they alias.  */
    6933                 :   20569100 :   if ((pt1->escaped
    6934                 :    2670680 :        && (pt2->escaped
    6935                 :   20569100 :            || pt2->vars_contains_escaped))
    6936                 :   19350500 :       || (pt2->escaped
    6937                 :   19350500 :           && pt1->vars_contains_escaped))
    6938                 :            :     return true;
    6939                 :            : 
    6940                 :            :   /* Check the escaped solution if required.
    6941                 :            :      ???  Do we need to check the local against the IPA escaped sets?  */
    6942                 :   18380200 :   if ((pt1->ipa_escaped || pt2->ipa_escaped)
    6943                 :   18393000 :       && !pt_solution_empty_p (&ipa_escaped_pt))
    6944                 :            :     {
    6945                 :            :       /* If both point to escaped memory and that solution
    6946                 :            :          is not empty they alias.  */
    6947                 :      12784 :       if (pt1->ipa_escaped && pt2->ipa_escaped)
    6948                 :            :         return true;
    6949                 :            : 
    6950                 :            :       /* If either points to escaped memory see if the escaped solution
    6951                 :            :          intersects with the other.  */
    6952                 :      12784 :       if ((pt1->ipa_escaped
    6953                 :       1441 :            && pt_solutions_intersect_1 (&ipa_escaped_pt, pt2))
    6954                 :      12784 :           || (pt2->ipa_escaped
    6955                 :      12016 :               && pt_solutions_intersect_1 (&ipa_escaped_pt, pt1)))
    6956                 :       5434 :         return true;
    6957                 :            :     }
    6958                 :            : 
    6959                 :            :   /* Now both pointers alias if their points-to solution intersects.  */
    6960                 :   18376200 :   return (pt1->vars
    6961                 :   18376200 :           && pt2->vars
    6962                 :   36752400 :           && bitmap_intersect_p (pt1->vars, pt2->vars));
    6963                 :            : }
    6964                 :            : 
    6965                 :            : bool
    6966                 :   50686600 : pt_solutions_intersect (struct pt_solution *pt1, struct pt_solution *pt2)
    6967                 :            : {
    6968                 :   50686600 :   bool res = pt_solutions_intersect_1 (pt1, pt2);
    6969                 :   50686600 :   if (res)
    6970                 :   34201400 :     ++pta_stats.pt_solutions_intersect_may_alias;
    6971                 :            :   else
    6972                 :   16485200 :     ++pta_stats.pt_solutions_intersect_no_alias;
    6973                 :   50686600 :   return res;
    6974                 :            : }
    6975                 :            : 
    6976                 :            : 
    6977                 :            : /* Dump points-to information to OUTFILE.  */
    6978                 :            : 
    6979                 :            : static void
    6980                 :        490 : dump_sa_points_to_info (FILE *outfile)
    6981                 :            : {
    6982                 :        490 :   unsigned int i;
    6983                 :            : 
    6984                 :        490 :   fprintf (outfile, "\nPoints-to sets\n\n");
    6985                 :            : 
    6986                 :        490 :   if (dump_flags & TDF_STATS)
    6987                 :            :     {
    6988                 :        159 :       fprintf (outfile, "Stats:\n");
    6989                 :        159 :       fprintf (outfile, "Total vars:               %d\n", stats.total_vars);
    6990                 :        159 :       fprintf (outfile, "Non-pointer vars:          %d\n",
    6991                 :            :                stats.nonpointer_vars);
    6992                 :        159 :       fprintf (outfile, "Statically unified vars:  %d\n",
    6993                 :            :                stats.unified_vars_static);
    6994                 :        159 :       fprintf (outfile, "Dynamically unified vars: %d\n",
    6995                 :            :                stats.unified_vars_dynamic);
    6996                 :        159 :       fprintf (outfile, "Iterations:               %d\n", stats.iterations);
    6997                 :        159 :       fprintf (outfile, "Number of edges:          %d\n", stats.num_edges);
    6998                 :        159 :       fprintf (outfile, "Number of implicit edges: %d\n",
    6999                 :            :                stats.num_implicit_edges);
    7000                 :            :     }
    7001                 :            : 
    7002                 :      18342 :   for (i = 1; i < varmap.length (); i++)
    7003                 :            :     {
    7004                 :       8681 :       varinfo_t vi = get_varinfo (i);
    7005                 :       8681 :       if (!vi->may_have_pointers)
    7006                 :       1034 :         continue;
    7007                 :       7647 :       dump_solution_for_var (outfile, i);
    7008                 :            :     }
    7009                 :        490 : }
    7010                 :            : 
    7011                 :            : 
    7012                 :            : /* Debug points-to information to stderr.  */
    7013                 :            : 
    7014                 :            : DEBUG_FUNCTION void
    7015                 :          0 : debug_sa_points_to_info (void)
    7016                 :            : {
    7017                 :          0 :   dump_sa_points_to_info (stderr);
    7018                 :          0 : }
    7019                 :            : 
    7020                 :            : 
    7021                 :            : /* Initialize the always-existing constraint variables for NULL
    7022                 :            :    ANYTHING, READONLY, and INTEGER */
    7023                 :            : 
    7024                 :            : static void
    7025                 :    2918700 : init_base_vars (void)
    7026                 :            : {
    7027                 :    2918700 :   struct constraint_expr lhs, rhs;
    7028                 :    2918700 :   varinfo_t var_anything;
    7029                 :    2918700 :   varinfo_t var_nothing;
    7030                 :    2918700 :   varinfo_t var_string;
    7031                 :    2918700 :   varinfo_t var_escaped;
    7032                 :    2918700 :   varinfo_t var_nonlocal;
    7033                 :    2918700 :   varinfo_t var_storedanything;
    7034                 :    2918700 :   varinfo_t var_integer;
    7035                 :            : 
    7036                 :            :   /* Variable ID zero is reserved and should be NULL.  */
    7037                 :    2918700 :   varmap.safe_push (NULL);
    7038                 :            : 
    7039                 :            :   /* Create the NULL variable, used to represent that a variable points
    7040                 :            :      to NULL.  */
    7041                 :    2918700 :   var_nothing = new_var_info (NULL_TREE, "NULL", false);
    7042                 :    2918700 :   gcc_assert (var_nothing->id == nothing_id);
    7043                 :    2918700 :   var_nothing->is_artificial_var = 1;
    7044                 :    2918700 :   var_nothing->offset = 0;
    7045                 :    2918700 :   var_nothing->size = ~0;
    7046                 :    2918700 :   var_nothing->fullsize = ~0;
    7047                 :    2918700 :   var_nothing->is_special_var = 1;
    7048                 :    2918700 :   var_nothing->may_have_pointers = 0;
    7049                 :    2918700 :   var_nothing->is_global_var = 0;
    7050                 :            : 
    7051                 :            :   /* Create the ANYTHING variable, used to represent that a variable
    7052                 :            :      points to some unknown piece of memory.  */
    7053                 :    2918700 :   var_anything = new_var_info (NULL_TREE, "ANYTHING", false);
    7054                 :    2918700 :   gcc_assert (var_anything->id == anything_id);
    7055                 :    2918700 :   var_anything->is_artificial_var = 1;
    7056                 :    2918700 :   var_anything->size = ~0;
    7057                 :    2918700 :   var_anything->offset = 0;
    7058                 :    2918700 :   var_anything->fullsize = ~0;
    7059                 :    2918700 :   var_anything->is_special_var = 1;
    7060                 :            : 
    7061                 :            :   /* Anything points to anything.  This makes deref constraints just
    7062                 :            :      work in the presence of linked list and other p = *p type loops,
    7063                 :            :      by saying that *ANYTHING = ANYTHING. */
    7064                 :    2918700 :   lhs.type = SCALAR;
    7065                 :    2918700 :   lhs.var = anything_id;
    7066                 :    2918700 :   lhs.offset = 0;
    7067                 :    2918700 :   rhs.type = ADDRESSOF;
    7068                 :    2918700 :   rhs.var = anything_id;
    7069                 :    2918700 :   rhs.offset = 0;
    7070                 :            : 
    7071                 :            :   /* This specifically does not use process_constraint because
    7072                 :            :      process_constraint ignores all anything = anything constraints, since all
    7073                 :            :      but this one are redundant.  */
    7074                 :    2918700 :   constraints.safe_push (new_constraint (lhs, rhs));
    7075                 :            : 
    7076                 :            :   /* Create the STRING variable, used to represent that a variable
    7077                 :            :      points to a string literal.  String literals don't contain
    7078                 :            :      pointers so STRING doesn't point to anything.  */
    7079                 :    2918700 :   var_string = new_var_info (NULL_TREE, "STRING", false);
    7080                 :    2918700 :   gcc_assert (var_string->id == string_id);
    7081                 :    2918700 :   var_string->is_artificial_var = 1;
    7082                 :    2918700 :   var_string->offset = 0;
    7083                 :    2918700 :   var_string->size = ~0;
    7084                 :    2918700 :   var_string->fullsize = ~0;
    7085                 :    2918700 :   var_string->is_special_var = 1;
    7086                 :    2918700 :   var_string->may_have_pointers = 0;
    7087                 :            : 
    7088                 :            :   /* Create the ESCAPED variable, used to represent the set of escaped
    7089                 :            :      memory.  */
    7090                 :    2918700 :   var_escaped = new_var_info (NULL_TREE, "ESCAPED", false);
    7091                 :    2918700 :   gcc_assert (var_escaped->id == escaped_id);
    7092                 :    2918700 :   var_escaped->is_artificial_var = 1;
    7093                 :    2918700 :   var_escaped->offset = 0;
    7094                 :    2918700 :   var_escaped->size = ~0;
    7095                 :    2918700 :   var_escaped->fullsize = ~0;
    7096                 :    2918700 :   var_escaped->is_special_var = 0;
    7097                 :            : 
    7098                 :            :   /* Create the NONLOCAL variable, used to represent the set of nonlocal
    7099                 :            :      memory.  */
    7100                 :    2918700 :   var_nonlocal = new_var_info (NULL_TREE, "NONLOCAL", false);
    7101                 :    2918700 :   gcc_assert (var_nonlocal->id == nonlocal_id);
    7102                 :    2918700 :   var_nonlocal->is_artificial_var = 1;
    7103                 :    2918700 :   var_nonlocal->offset = 0;
    7104                 :    2918700 :   var_nonlocal->size = ~0;
    7105                 :    2918700 :   var_nonlocal->fullsize = ~0;
    7106                 :    2918700 :   var_nonlocal->is_special_var = 1;
    7107                 :            : 
    7108                 :            :   /* ESCAPED = *ESCAPED, because escaped is may-deref'd at calls, etc.  */
    7109                 :    2918700 :   lhs.type = SCALAR;
    7110                 :    2918700 :   lhs.var = escaped_id;
    7111                 :    2918700 :   lhs.offset = 0;
    7112                 :    2918700 :   rhs.type = DEREF;
    7113                 :    2918700 :   rhs.var = escaped_id;
    7114                 :    2918700 :   rhs.offset = 0;
    7115                 :    2918700 :   process_constraint (new_constraint (lhs, rhs));
    7116                 :            : 
    7117                 :            :   /* ESCAPED = ESCAPED + UNKNOWN_OFFSET, because if a sub-field escapes the
    7118                 :            :      whole variable escapes.  */
    7119                 :    2918700 :   lhs.type = SCALAR;
    7120                 :    2918700 :   lhs.var = escaped_id;
    7121                 :    2918700 :   lhs.offset = 0;
    7122                 :    2918700 :   rhs.type = SCALAR;
    7123                 :    2918700 :   rhs.var = escaped_id;
    7124                 :    2918700 :   rhs.offset = UNKNOWN_OFFSET;
    7125                 :    2918700 :   process_constraint (new_constraint (lhs, rhs));
    7126                 :            : 
    7127                 :            :   /* *ESCAPED = NONLOCAL.  This is true because we have to assume
    7128                 :            :      everything pointed to by escaped points to what global memory can
    7129                 :            :      point to.  */
    7130                 :    2918700 :   lhs.type = DEREF;
    7131                 :    2918700 :   lhs.var = escaped_id;
    7132                 :    2918700 :   lhs.offset = 0;
    7133                 :    2918700 :   rhs.type = SCALAR;
    7134                 :    2918700 :   rhs.var = nonlocal_id;
    7135                 :    2918700 :   rhs.offset = 0;
    7136                 :    2918700 :   process_constraint (new_constraint (lhs, rhs));
    7137                 :            : 
    7138                 :            :   /* NONLOCAL = &NONLOCAL, NONLOCAL = &ESCAPED.  This is true because
    7139                 :            :      global memory may point to global memory and escaped memory.  */
    7140                 :    2918700 :   lhs.type = SCALAR;
    7141                 :    2918700 :   lhs.var = nonlocal_id;
    7142                 :    2918700 :   lhs.offset = 0;
    7143                 :    2918700 :   rhs.type = ADDRESSOF;
    7144                 :    2918700 :   rhs.var = nonlocal_id;
    7145                 :    2918700 :   rhs.offset = 0;
    7146                 :    2918700 :   process_constraint (new_constraint (lhs, rhs));
    7147                 :    2918700 :   rhs.type = ADDRESSOF;
    7148                 :    2918700 :   rhs.var = escaped_id;
    7149                 :    2918700 :   rhs.offset = 0;
    7150                 :    2918700 :   process_constraint (new_constraint (lhs, rhs));
    7151                 :            : 
    7152                 :            :   /* Create the STOREDANYTHING variable, used to represent the set of
    7153                 :            :      variables stored to *ANYTHING.  */
    7154                 :    2918700 :   var_storedanything = new_var_info (NULL_TREE, "STOREDANYTHING", false);
    7155                 :    2918700 :   gcc_assert (var_storedanything->id == storedanything_id);
    7156                 :    2918700 :   var_storedanything->is_artificial_var = 1;
    7157                 :    2918700 :   var_storedanything->offset = 0;
    7158                 :    2918700 :   var_storedanything->size = ~0;
    7159                 :    2918700 :   var_storedanything->fullsize = ~0;
    7160                 :    2918700 :   var_storedanything->is_special_var = 0;
    7161                 :            : 
    7162                 :            :   /* Create the INTEGER variable, used to represent that a variable points
    7163                 :            :      to what an INTEGER "points to".  */
    7164                 :    2918700 :   var_integer = new_var_info (NULL_TREE, "INTEGER", false);
    7165                 :    2918700 :   gcc_assert (var_integer->id == integer_id);
    7166                 :    2918700 :   var_integer->is_artificial_var = 1;
    7167                 :    2918700 :   var_integer->size = ~0;
    7168                 :    2918700 :   var_integer->fullsize = ~0;
    7169                 :    2918700 :   var_integer->offset = 0;
    7170                 :    2918700 :   var_integer->is_special_var = 1;
    7171                 :            : 
    7172                 :            :   /* INTEGER = ANYTHING, because we don't know where a dereference of
    7173                 :            :      a random integer will point to.  */
    7174                 :    2918700 :   lhs.type = SCALAR;
    7175                 :    2918700 :   lhs.var = integer_id;
    7176                 :    2918700 :   lhs.offset = 0;
    7177                 :    2918700 :   rhs.type = ADDRESSOF;
    7178                 :    2918700 :   rhs.var = anything_id;
    7179                 :    2918700 :   rhs.offset = 0;
    7180                 :    2918700 :   process_constraint (new_constraint (lhs, rhs));
    7181                 :    2918700 : }
    7182                 :            : 
    7183                 :            : /* Initialize things necessary to perform PTA */
    7184                 :            : 
    7185                 :            : static void
    7186                 :    2918700 : init_alias_vars (void)
    7187                 :            : {
    7188                 :    2918700 :   use_field_sensitive = (param_max_fields_for_field_sensitive > 1);
    7189                 :            : 
    7190                 :    2918700 :   bitmap_obstack_initialize (&pta_obstack);
    7191                 :    2918700 :   bitmap_obstack_initialize (&oldpta_obstack);
    7192                 :    2918700 :   bitmap_obstack_initialize (&predbitmap_obstack);
    7193                 :            : 
    7194                 :    2918700 :   constraints.create (8);
    7195                 :    2918700 :   varmap.create (8);
    7196                 :    2918700 :   vi_for_tree = new hash_map<tree, varinfo_t>;
    7197                 :    2918700 :   call_stmt_vars = new hash_map<gimple *, varinfo_t>;
    7198                 :            : 
    7199                 :    2918700 :   memset (&stats, 0, sizeof (stats));
    7200                 :    2918700 :   shared_bitmap_table = new hash_table<shared_bitmap_hasher> (511);
    7201                 :    2918700 :   init_base_vars ();
    7202                 :            : 
    7203                 :    2918700 :   gcc_obstack_init (&fake_var_decl_obstack);
    7204                 :            : 
    7205                 :    2918700 :   final_solutions = new hash_map<varinfo_t, pt_solution *>;
    7206                 :    2918700 :   gcc_obstack_init (&final_solutions_obstack);
    7207                 :    2918700 : }
    7208                 :            : 
    7209                 :            : /* Remove the REF and ADDRESS edges from GRAPH, as well as all the
    7210                 :            :    predecessor edges.  */
    7211                 :            : 
    7212                 :            : static void
    7213                 :    2918700 : remove_preds_and_fake_succs (constraint_graph_t graph)
    7214                 :            : {
    7215                 :    2918700 :   unsigned int i;
    7216                 :            : 
    7217                 :            :   /* Clear the implicit ref and address nodes from the successor
    7218                 :            :      lists.  */
    7219                 :  203276000 :   for (i = 1; i < FIRST_REF_NODE; i++)
    7220                 :            :     {
    7221                 :   98719400 :       if (graph->succs[i])
    7222                 :   15792200 :         bitmap_clear_range (graph->succs[i], FIRST_REF_NODE,
    7223                 :   15792200 :                             FIRST_REF_NODE * 2);
    7224                 :            :     }
    7225                 :            : 
    7226                 :            :   /* Free the successor list for the non-ref nodes.  */
    7227                 :  101638000 :   for (i = FIRST_REF_NODE + 1; i < graph->size; i++)
    7228                 :            :     {
    7229                 :   98719400 :       if (graph->succs[i])
    7230                 :    4541860 :         BITMAP_FREE (graph->succs[i]);
    7231                 :            :     }
    7232                 :            : 
    7233                 :            :   /* Now reallocate the size of the successor list as, and blow away
    7234                 :            :      the predecessor bitmaps.  */
    7235                 :    2918700 :   graph->size = varmap.length ();
    7236                 :    2918700 :   graph->succs = XRESIZEVEC (bitmap, graph->succs, graph->size);
    7237                 :            : 
    7238                 :    2918700 :   free (graph->implicit_preds);
    7239                 :    2918700 :   graph->implicit_preds = NULL;
    7240                 :    2918700 :   free (graph->preds);
    7241                 :    2918700 :   graph->preds = NULL;
    7242                 :    2918700 :   bitmap_obstack_release (&predbitmap_obstack);
    7243                 :    2918700 : }
    7244                 :            : 
    7245                 :            : /* Solve the constraint set.  */
    7246                 :            : 
    7247                 :            : static void
    7248                 :    2918700 : solve_constraints (void)
    7249                 :            : {
    7250                 :    2918700 :   class scc_info *si;
    7251                 :            : 
    7252                 :            :   /* Sort varinfos so that ones that cannot be pointed to are last.
    7253                 :            :      This makes bitmaps more efficient.  */
    7254                 :    2918700 :   unsigned int *map = XNEWVEC (unsigned int, varmap.length ());
    7255                 :   26268300 :   for (unsigned i = 0; i < integer_id + 1; ++i)
    7256                 :   23349600 :     map[i] = i;
    7257                 :            :   /* Start with non-register vars (as possibly address-taken), followed
    7258                 :            :      by register vars as conservative set of vars never appearing in
    7259                 :            :      the points-to solution bitmaps.  */
    7260                 :            :   unsigned j = integer_id + 1;
    7261                 :  162414000 :   for (unsigned i = integer_id + 1; i < varmap.length (); ++i)
    7262                 :   78288400 :     if (! varmap[i]->is_reg_var)
    7263                 :   32499300 :       map[i] = j++;
    7264                 :   81207100 :   for (unsigned i = integer_id + 1; i < varmap.length (); ++i)
    7265                 :   78288400 :     if (varmap[i]->is_reg_var)
    7266                 :   45789100 :       map[i] = j++;
    7267                 :            :   /* Shuffle varmap according to map.  */
    7268                 :  162414000 :   for (unsigned i = integer_id + 1; i < varmap.length (); ++i)
    7269                 :            :     {
    7270                 :  136048000 :       while (map[varmap[i]->id] != i)
    7271                 :  136048000 :         std::swap (varmap[i], varmap[map[varmap[i]->id]]);
    7272                 :   78288400 :       gcc_assert (bitmap_empty_p (varmap[i]->solution));
    7273                 :   78288400 :       varmap[i]->id = i;
    7274                 :   78288400 :       varmap[i]->next = map[varmap[i]->next];
    7275                 :   78288400 :       varmap[i]->head = map[varmap[i]->head];
    7276                 :            :     }
    7277                 :            :   /* Finally rewrite constraints.  */
    7278                 :  275031000 :   for (unsigned i = 0; i < constraints.length (); ++i)
    7279                 :            :     {
    7280                 :  134597000 :       constraints[i]->lhs.var = map[constraints[i]->lhs.var];
    7281                 :  134597000 :       constraints[i]->rhs.var = map[constraints[i]->rhs.var];
    7282                 :            :     }
    7283                 :    2918700 :   free (map);
    7284                 :            : 
    7285                 :    2918700 :   if (dump_file)
    7286                 :        490 :     fprintf (dump_file,
    7287                 :            :              "\nCollapsing static cycles and doing variable "
    7288                 :            :              "substitution\n");
    7289                 :            : 
    7290                 :    5837410 :   init_graph (varmap.length () * 2);
    7291                 :            : 
    7292                 :    2918700 :   if (dump_file)
    7293                 :        490 :     fprintf (dump_file, "Building predecessor graph\n");
    7294                 :    2918700 :   build_pred_graph ();
    7295                 :            : 
    7296                 :    2918700 :   if (dump_file)
    7297                 :        490 :     fprintf (dump_file, "Detecting pointer and location "
    7298                 :            :              "equivalences\n");
    7299                 :    2918700 :   si = perform_var_substitution (graph);
    7300                 :            : 
    7301                 :    2918700 :   if (dump_file)
    7302                 :        490 :     fprintf (dump_file, "Rewriting constraints and unifying "
    7303                 :            :              "variables\n");
    7304                 :    2918700 :   rewrite_constraints (graph, si);
    7305                 :            : 
    7306                 :    2918700 :   build_succ_graph ();
    7307                 :            : 
    7308                 :    2918700 :   free_var_substitution_info (si);
    7309                 :            : 
    7310                 :            :   /* Attach complex constraints to graph nodes.  */
    7311                 :    2918700 :   move_complex_constraints (graph);
    7312                 :            : 
    7313                 :    2918700 :   if (dump_file)
    7314                 :        490 :     fprintf (dump_file, "Uniting pointer but not location equivalent "
    7315                 :            :              "variables\n");
    7316                 :    2918700 :   unite_pointer_equivalences (graph);
    7317                 :            : 
    7318                 :    2918700 :   if (dump_file)
    7319                 :        490 :     fprintf (dump_file, "Finding indirect cycles\n");
    7320                 :    2918700 :   find_indirect_cycles (graph);
    7321                 :            : 
    7322                 :            :   /* Implicit nodes and predecessors are no longer necessary at this
    7323                 :            :      point. */
    7324                 :    2918700 :   remove_preds_and_fake_succs (graph);
    7325                 :            : 
    7326                 :    2918700 :   if (dump_file && (dump_flags & TDF_GRAPH))
    7327                 :            :     {
    7328                 :          3 :       fprintf (dump_file, "\n\n// The constraint graph before solve-graph "
    7329                 :            :                "in dot format:\n");
    7330                 :          3 :       dump_constraint_graph (dump_file);
    7331                 :          3 :       fprintf (dump_file, "\n\n");
    7332                 :            :     }
    7333                 :            : 
    7334                 :    2918700 :   if (dump_file)
    7335                 :        490 :     fprintf (dump_file, "Solving graph\n");
    7336                 :            : 
    7337                 :    2918700 :   solve_graph (graph);
    7338                 :            : 
    7339                 :    2918700 :   if (dump_file && (dump_flags & TDF_GRAPH))
    7340                 :            :     {
    7341                 :          3 :       fprintf (dump_file, "\n\n// The constraint graph after solve-graph "
    7342                 :            :                "in dot format:\n");
    7343                 :          3 :       dump_constraint_graph (dump_file);
    7344                 :          3 :       fprintf (dump_file, "\n\n");
    7345                 :            :     }
    7346                 :    2918700 : }
    7347                 :            : 
    7348                 :            : /* Create points-to sets for the current function.  See the comments
    7349                 :            :    at the start of the file for an algorithmic overview.  */
    7350                 :            : 
    7351                 :            : static void
    7352                 :    2915140 : compute_points_to_sets (void)
    7353                 :            : {
    7354                 :    2915140 :   basic_block bb;
    7355                 :    2915140 :   varinfo_t vi;
    7356                 :            : 
    7357                 :    2915140 :   timevar_push (TV_TREE_PTA);
    7358                 :            : 
    7359                 :    2915140 :   init_alias_vars ();
    7360                 :            : 
    7361                 :    2915140 :   intra_create_variable_infos (cfun);
    7362                 :            : 
    7363                 :            :   /* Now walk all statements and build the constraint set.  */
    7364                 :   24887400 :   FOR_EACH_BB_FN (bb, cfun)
    7365                 :            :     {
    7366                 :   29535200 :       for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
    7367                 :    7562960 :            gsi_next (&gsi))
    7368                 :            :         {
    7369                 :    7562960 :           gphi *phi = gsi.phi ();
    7370                 :            : 
    7371                 :   15125900 :           if (! virtual_operand_p (gimple_phi_result (phi)))
    7372                 :    3604140 :             find_func_aliases (cfun, phi);
    7373                 :            :         }
    7374                 :            : 
    7375                 :  204452000 :       for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
    7376                 :  160507000 :            gsi_next (&gsi))
    7377                 :            :         {
    7378                 :  160507000 :           gimple *stmt = gsi_stmt (gsi);
    7379                 :            : 
    7380                 :  160507000 :           find_func_aliases (cfun, stmt);
    7381                 :            :         }
    7382                 :            :     }
    7383                 :            : 
    7384                 :    2915140 :   if (dump_file)
    7385                 :            :     {
    7386                 :        471 :       fprintf (dump_file, "Points-to analysis\n\nConstraints:\n\n");
    7387                 :        471 :       dump_constraints (dump_file, 0);
    7388                 :            :     }
    7389                 :            : 
    7390                 :            :   /* From the constraints compute the points-to sets.  */
    7391                 :    2915140 :   solve_constraints ();
    7392                 :            : 
    7393                 :            :   /* Post-process solutions for escapes through returns.  */
    7394                 :    2915140 :   edge_iterator ei;
    7395                 :    2915140 :   edge e;
    7396                 :    5776890 :   FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
    7397                 :    5723510 :     if (greturn *ret = safe_dyn_cast <greturn *> (last_stmt (e->src)))
    7398                 :            :       {
    7399                 :    2861490 :         tree val = gimple_return_retval (ret);
    7400                 :            :         /* ???  Easy to handle simple indirections with some work.
    7401                 :            :            Arbitrary references like foo.bar.baz are more difficult
    7402                 :            :            (but conservatively easy enough with just looking at the base).
    7403                 :            :            Mind to fixup find_func_aliases as well.  */
    7404                 :    2861490 :         if (!val || !SSA_VAR_P (val))
    7405                 :    1550700 :           continue;
    7406                 :            :         /* returns happen last in non-IPA so they only influence
    7407                 :            :            the ESCAPED solution and we can filter local variables.  */
    7408                 :    1310790 :         varinfo_t escaped_vi = get_varinfo (find (escaped_id));
    7409                 :    1310790 :         varinfo_t vi = lookup_vi_for_tree (val);
    7410                 :    1310790 :         bitmap delta = BITMAP_ALLOC (&pta_obstack);
    7411                 :    2714870 :         bitmap_iterator bi;
    7412                 :    2714870 :         unsigned i;
    7413                 :    2714870 :         for (; vi; vi = vi_next (vi))
    7414                 :            :           {
    7415                 :    1404080 :             varinfo_t part_vi = get_varinfo (find (vi->id));
    7416                 :    2353890 :             EXECUTE_IF_AND_COMPL_IN_BITMAP (part_vi->solution,
    7417                 :            :                                             escaped_vi->solution, 0, i, bi)
    7418                 :            :               {
    7419                 :     949808 :                 varinfo_t pointed_to_vi = get_varinfo (i);
    7420                 :     949808 :                 if (pointed_to_vi->is_global_var
    7421                 :            :                     /* We delay marking of heap memory as global.  */
    7422                 :     949808 :                     || pointed_to_vi->is_heap_var)
    7423                 :     772631 :                   bitmap_set_bit (delta, i);
    7424                 :            :               }
    7425                 :            :           }
    7426                 :            : 
    7427                 :            :         /* Now compute the transitive closure.  */
    7428                 :    1310790 :         bitmap_ior_into (escaped_vi->solution, delta);
    7429                 :    1310790 :         bitmap new_delta = BITMAP_ALLOC (&pta_obstack);
    7430                 :    2287810 :         while (!bitmap_empty_p (delta))
    7431                 :            :           {
    7432                 :    2118530 :             EXECUTE_IF_SET_IN_BITMAP (delta, 0, i, bi)
    7433                 :            :               {
    7434                 :    1141510 :                 varinfo_t pointed_to_vi = get_varinfo (i);
    7435                 :    1141510 :                 pointed_to_vi = get_varinfo (find (pointed_to_vi->id));
    7436                 :    1141510 :                 unsigned j;
    7437                 :    1141510 :                 bitmap_iterator bi2;
    7438                 :    1540870 :                 EXECUTE_IF_AND_COMPL_IN_BITMAP (pointed_to_vi->solution,
    7439                 :            :                                                 escaped_vi->solution,
    7440                 :            :                                                 0, j, bi2)
    7441                 :            :                   {
    7442                 :     399361 :                     varinfo_t pointed_to_vi2 = get_varinfo (j);
    7443                 :     399361 :                     if (pointed_to_vi2->is_global_var
    7444                 :            :                         /* We delay marking of heap memory as global.  */
    7445                 :     399361 :                         || pointed_to_vi2->is_heap_var)
    7446                 :     397896 :                       bitmap_set_bit (new_delta, j);
    7447                 :            :                   }
    7448                 :            :               }
    7449                 :     977019 :             bitmap_ior_into (escaped_vi->solution, new_delta);
    7450                 :     977019 :             bitmap_clear (delta);
    7451                 :    3264830 :             std::swap (delta, new_delta);
    7452                 :            :           }
    7453                 :    1310790 :         BITMAP_FREE (delta);
    7454                 :    1310790 :         BITMAP_FREE (new_delta);
    7455                 :            :       }
    7456                 :            : 
    7457                 :    2915140 :   if (dump_file)
    7458                 :        471 :     dump_sa_points_to_info (dump_file);
    7459                 :            : 
    7460                 :            :   /* Compute the points-to set for ESCAPED used for call-clobber analysis.  */
    7461                 :    2915140 :   cfun->gimple_df->escaped = find_what_var_points_to (cfun->decl,
    7462                 :    2915140 :                                                       get_varinfo (escaped_id));
    7463                 :            : 
    7464                 :            :   /* Make sure the ESCAPED solution (which is used as placeholder in
    7465                 :            :      other solutions) does not reference itself.  This simplifies
    7466                 :            :      points-to solution queries.  */
    7467                 :    2915140 :   cfun->gimple_df->escaped.escaped = 0;
    7468                 :            : 
    7469                 :            :   /* Compute the points-to sets for pointer SSA_NAMEs.  */
    7470                 :    2915140 :   unsigned i;
    7471                 :    2915140 :   tree ptr;
    7472                 :            : 
    7473                 :  104144000 :   FOR_EACH_SSA_NAME (i, ptr, cfun)
    7474                 :            :     {
    7475                 :   81718700 :       if (POINTER_TYPE_P (TREE_TYPE (ptr)))
    7476                 :   15763300 :         find_what_p_points_to (cfun->decl, ptr);
    7477                 :            :     }
    7478                 :            : 
    7479                 :            :   /* Compute the call-used/clobbered sets.  */
    7480                 :   24887400 :   FOR_EACH_BB_FN (bb, cfun)
    7481                 :            :     {
    7482                 :   21972300 :       gimple_stmt_iterator gsi;
    7483                 :            : 
    7484                 :  204452000 :       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    7485                 :            :         {
    7486                 :  160507000 :           gcall *stmt;
    7487                 :  160507000 :           struct pt_solution *pt;
    7488                 :            : 
    7489                 :  160507000 :           stmt = dyn_cast <gcall *> (gsi_stmt (gsi));
    7490                 :  160507000 :           if (!stmt)
    7491                 :  149324000 :             continue;
    7492                 :            : 
    7493                 :   11183700 :           pt = gimple_call_use_set (stmt);
    7494                 :   11183700 :           if (gimple_call_flags (stmt) & ECF_CONST)
    7495                 :     692666 :             memset (pt, 0, sizeof (struct pt_solution));
    7496                 :   10491100 :           else if ((vi = lookup_call_use_vi (stmt)) != NULL)
    7497                 :            :             {
    7498                 :     990648 :               *pt = find_what_var_points_to (cfun->decl, vi);
    7499                 :            :               /* Escaped (and thus nonlocal) variables are always
    7500                 :            :                  implicitly used by calls.  */
    7501                 :            :               /* ???  ESCAPED can be empty even though NONLOCAL
    7502                 :            :                  always escaped.  */
    7503                 :     990648 :               pt->nonlocal = 1;
    7504                 :     990648 :               pt->escaped = 1;
    7505                 :            :             }
    7506                 :            :           else
    7507                 :            :             {
    7508                 :            :               /* If there is nothing special about this call then
    7509                 :            :                  we have made everything that is used also escape.  */
    7510                 :    9500430 :               *pt = cfun->gimple_df->escaped;
    7511                 :    9500430 :               pt->nonlocal = 1;
    7512                 :            :             }
    7513                 :            : 
    7514                 :   11183700 :           pt = gimple_call_clobber_set (stmt);
    7515                 :   11183700 :           if (gimple_call_flags (stmt) & (ECF_CONST|ECF_PURE|ECF_NOVOPS))
    7516                 :    1158900 :             memset (pt, 0, sizeof (struct pt_solution));
    7517                 :   10024800 :           else if ((vi = lookup_call_clobber_vi (stmt)) != NULL)
    7518                 :            :             {
    7519                 :     590531 :               *pt = find_what_var_points_to (cfun->decl, vi);
    7520                 :            :               /* Escaped (and thus nonlocal) variables are always
    7521                 :            :                  implicitly clobbered by calls.  */
    7522                 :            :               /* ???  ESCAPED can be empty even though NONLOCAL
    7523                 :            :                  always escaped.  */
    7524                 :     590531 :               pt->nonlocal = 1;
    7525                 :     590531 :               pt->escaped = 1;
    7526                 :            :             }
    7527                 :            :           else
    7528                 :            :             {
    7529                 :            :               /* If there is nothing special about this call then
    7530                 :            :                  we have made everything that is used also escape.  */
    7531                 :    9434310 :               *pt = cfun->gimple_df->escaped;
    7532                 :    9434310 :               pt->nonlocal = 1;
    7533                 :            :             }
    7534                 :            :         }
    7535                 :            :     }
    7536                 :            : 
    7537                 :    2915140 :   timevar_pop (TV_TREE_PTA);
    7538                 :    2915140 : }
    7539                 :            : 
    7540                 :            : 
    7541                 :            : /* Delete created points-to sets.  */
    7542                 :            : 
    7543                 :            : static void
    7544                 :    2918700 : delete_points_to_sets (void)
    7545                 :            : {
    7546                 :    2918700 :   unsigned int i;
    7547                 :            : 
    7548                 :    2918700 :   delete shared_bitmap_table;
    7549                 :    2918700 :   shared_bitmap_table = NULL;
    7550                 :    2918700 :   if (dump_file && (dump_flags & TDF_STATS))
    7551                 :        159 :     fprintf (dump_file, "Points to sets created:%d\n",
    7552                 :            :              stats.points_to_sets_created);
    7553                 :            : 
    7554                 :    5837410 :   delete vi_for_tree;
    7555                 :    5837410 :   delete call_stmt_vars;
    7556                 :    2918700 :   bitmap_obstack_release (&pta_obstack);
    7557                 :    2918700 :   constraints.release ();
    7558                 :            : 
    7559                 :  104557000 :   for (i = 0; i < graph->size; i++)
    7560                 :  116116000 :     graph->complex[i].release ();
    7561                 :    2918700 :   free (graph->complex);
    7562                 :            : 
    7563                 :    2918700 :   free (graph->rep);
    7564                 :    2918700 :   free (graph->succs);
    7565                 :    2918700 :   free (graph->pe);
    7566                 :    2918700 :   free (graph->pe_rep);
    7567                 :    2918700 :   free (graph->indirect_cycles);
    7568                 :    2918700 :   free (graph);
    7569                 :            : 
    7570                 :    2918700 :   varmap.release ();
    7571                 :    2918700 :   variable_info_pool.release ();
    7572                 :    2918700 :   constraint_pool.release ();
    7573                 :            : 
    7574                 :    2918700 :   obstack_free (&fake_var_decl_obstack, NULL);
    7575                 :            : 
    7576                 :    5837410 :   delete final_solutions;
    7577                 :    2918700 :   obstack_free (&final_solutions_obstack, NULL);
    7578                 :    2918700 : }
    7579                 :            : 
    7580                 :            : struct vls_data
    7581                 :            : {
    7582                 :            :   unsigned short clique;
    7583                 :            :   bool escaped_p;
    7584                 :            :   bitmap rvars;
    7585                 :            : };
    7586                 :            : 
    7587                 :            : /* Mark "other" loads and stores as belonging to CLIQUE and with
    7588                 :            :    base zero.  */
    7589                 :            : 
    7590                 :            : static bool
    7591                 :    3583970 : visit_loadstore (gimple *, tree base, tree ref, void *data)
    7592                 :            : {
    7593                 :    3583970 :   unsigned short clique = ((vls_data *) data)->clique;
    7594                 :    3583970 :   bitmap rvars = ((vls_data *) data)->rvars;
    7595                 :    3583970 :   bool escaped_p = ((vls_data *) data)->escaped_p;
    7596                 :    3583970 :   if (TREE_CODE (base) == MEM_REF
    7597                 :    3583970 :       || TREE_CODE (base) == TARGET_MEM_REF)
    7598                 :            :     {
    7599                 :    2529890 :       tree ptr = TREE_OPERAND (base, 0);
    7600                 :    2529890 :       if (TREE_CODE (ptr) == SSA_NAME)
    7601                 :            :         {
    7602                 :            :           /* For parameters, get at the points-to set for the actual parm
    7603                 :            :              decl.  */
    7604                 :    2294200 :           if (SSA_NAME_IS_DEFAULT_DEF (ptr)
    7605                 :    3314430 :               && (TREE_CODE (SSA_NAME_VAR (ptr)) == PARM_DECL
    7606                 :    2318590 :                   || TREE_CODE (SSA_NAME_VAR (ptr)) == RESULT_DECL))
    7607                 :    1657140 :             ptr = SSA_NAME_VAR (ptr);
    7608                 :            : 
    7609                 :            :           /* We need to make sure 'ptr' doesn't include any of
    7610                 :            :              the restrict tags we added bases for in its points-to set.  */
    7611                 :    2294200 :           varinfo_t vi = lookup_vi_for_tree (ptr);
    7612                 :    2294200 :           if (! vi)
    7613                 :            :             return false;
    7614                 :            : 
    7615                 :    2294130 :           vi = get_varinfo (find (vi->id));
    7616                 :    2294130 :           if (bitmap_intersect_p (rvars, vi->solution)
    7617                 :    2294130 :               || (escaped_p && bitmap_bit_p (vi->solution, escaped_id)))
    7618                 :    1636700 :             return false;
    7619                 :            :         }
    7620                 :            : 
    7621                 :            :       /* Do not overwrite existing cliques (that includes clique, base
    7622                 :            :          pairs we just set).  */
    7623                 :     893121 :       if (MR_DEPENDENCE_CLIQUE (base) == 0)
    7624                 :            :         {
    7625                 :     631688 :           MR_DEPENDENCE_CLIQUE (base) = clique;
    7626                 :     631688 :           MR_DEPENDENCE_BASE (base) = 0;
    7627                 :            :         }
    7628                 :            :     }
    7629                 :            : 
    7630                 :            :   /* For plain decl accesses see whether they are accesses to globals
    7631                 :            :      and rewrite them to MEM_REFs with { clique, 0 }.  */
    7632                 :    1947200 :   if (VAR_P (base)
    7633                 :    1027910 :       && is_global_var (base)
    7634                 :            :       /* ???  We can't rewrite a plain decl with the walk_stmt_load_store
    7635                 :            :          ops callback.  */
    7636                 :    1995580 :       && base != ref)
    7637                 :            :     {
    7638                 :            :       tree *basep = &ref;
    7639                 :      81403 :       while (handled_component_p (*basep))
    7640                 :      52358 :         basep = &TREE_OPERAND (*basep, 0);
    7641                 :      29045 :       gcc_assert (VAR_P (*basep));
    7642                 :      29045 :       tree ptr = build_fold_addr_expr (*basep);
    7643                 :      29045 :       tree zero = build_int_cst (TREE_TYPE (ptr), 0);
    7644                 :      29045 :       *basep = build2 (MEM_REF, TREE_TYPE (*basep), ptr, zero);
    7645                 :      29045 :       MR_DEPENDENCE_CLIQUE (*basep) = clique;
    7646                 :      29045 :       MR_DEPENDENCE_BASE (*basep) = 0;
    7647                 :            :     }
    7648                 :            : 
    7649                 :            :   return false;
    7650                 :            : }
    7651                 :            : 
    7652                 :            : struct msdi_data {
    7653                 :            :   tree ptr;
    7654                 :            :   unsigned short *clique;
    7655                 :            :   unsigned short *last_ruid;
    7656                 :            :   varinfo_t restrict_var;
    7657                 :            : };
    7658                 :            : 
    7659                 :            : /* If BASE is a MEM_REF then assign a clique, base pair to it, updating
    7660                 :            :    CLIQUE, *RESTRICT_VAR and LAST_RUID as passed via DATA.
    7661                 :            :    Return whether dependence info was assigned to BASE.  */
    7662                 :            : 
    7663                 :            : static bool
    7664                 :    1660340 : maybe_set_dependence_info (gimple *, tree base, tree, void *data)
    7665                 :            : {
    7666                 :    1660340 :   tree ptr = ((msdi_data *)data)->ptr;
    7667                 :    1660340 :   unsigned short &clique = *((msdi_data *)data)->clique;
    7668                 :    1660340 :   unsigned short &last_ruid = *((msdi_data *)data)->last_ruid;
    7669                 :    1660340 :   varinfo_t restrict_var = ((msdi_data *)data)->restrict_var;
    7670                 :    1660340 :   if ((TREE_CODE (base) == MEM_REF
    7671                 :    1660340 :        || TREE_CODE (base) == TARGET_MEM_REF)
    7672                 :    1660340 :       && TREE_OPERAND (base, 0) == ptr)
    7673                 :            :     {
    7674                 :            :       /* Do not overwrite existing cliques.  This avoids overwriting dependence
    7675                 :            :          info inlined from a function with restrict parameters inlined
    7676                 :            :          into a function with restrict parameters.  This usually means we
    7677                 :            :          prefer to be precise in innermost loops.  */
    7678                 :    1576570 :       if (MR_DEPENDENCE_CLIQUE (base) == 0)
    7679                 :            :         {
    7680                 :    1175620 :           if (clique == 0)
    7681                 :            :             {
    7682                 :     239711 :               if (cfun->last_clique == 0)
    7683                 :     102335 :                 cfun->last_clique = 1;
    7684                 :     239711 :               clique = 1;
    7685                 :            :             }
    7686                 :    1175620 :           if (restrict_var->ruid == 0)
    7687                 :     300988 :             restrict_var->ruid = ++last_ruid;
    7688                 :    1175620 :           MR_DEPENDENCE_CLIQUE (base) = clique;
    7689                 :    1175620 :           MR_DEPENDENCE_BASE (base) = restrict_var->ruid;
    7690                 :    1175620 :           return true;
    7691                 :            :         }
    7692                 :            :     }
    7693                 :            :   return false;
    7694                 :            : }
    7695                 :            : 
    7696                 :            : /* Clear dependence info for the clique DATA.  */
    7697                 :            : 
    7698                 :            : static bool
    7699                 :    8765310 : clear_dependence_clique (gimple *, tree base, tree, void *data)
    7700                 :            : {
    7701                 :    8765310 :   unsigned short clique = (uintptr_t)data;
    7702                 :    8765310 :   if ((TREE_CODE (base) == MEM_REF
    7703                 :    8765310 :        || TREE_CODE (base) == TARGET_MEM_REF)
    7704                 :    8765310 :       && MR_DEPENDENCE_CLIQUE (base) == clique)
    7705                 :            :     {
    7706                 :     832146 :       MR_DEPENDENCE_CLIQUE (base) = 0;
    7707                 :     832146 :       MR_DEPENDENCE_BASE (base) = 0;
    7708                 :            :     }
    7709                 :            : 
    7710                 :    8765310 :   return false;
    7711                 :            : }
    7712                 :            : 
    7713                 :            : /* Compute the set of independend memory references based on restrict
    7714                 :            :    tags and their conservative propagation to the points-to sets.  */
    7715                 :            : 
    7716                 :            : static void
    7717                 :    2915140 : compute_dependence_clique (void)
    7718                 :            : {
    7719                 :            :   /* First clear the special "local" clique.  */
    7720                 :    2915140 :   basic_block bb;
    7721                 :    2915140 :   if (cfun->last_clique != 0)
    7722                 :    5066680 :     FOR_EACH_BB_FN (bb, cfun)
    7723                 :    4747800 :       for (gimple_stmt_iterator gsi = gsi_start_bb (bb);
    7724                 :   76229900 :            !gsi_end_p (gsi); gsi_next (&gsi))
    7725                 :            :         {
    7726                 :   71482100 :           gimple *stmt = gsi_stmt (gsi);
    7727                 :   71482100 :           walk_stmt_load_store_ops (stmt, (void *)(uintptr_t) 1,
    7728                 :            :                                     clear_dependence_clique,
    7729                 :            :                                     clear_dependence_clique);
    7730                 :            :         }
    7731                 :            : 
    7732                 :    2915140 :   unsigned short clique = 0;
    7733                 :    2915140 :   unsigned short last_ruid = 0;
    7734                 :    2915140 :   bitmap rvars = BITMAP_ALLOC (NULL);
    7735                 :    2915140 :   bool escaped_p = false;
    7736                 :  214118000 :   for (unsigned i = 0; i < num_ssa_names; ++i)
    7737                 :            :     {
    7738                 :  104144000 :       tree ptr = ssa_name (i);
    7739                 :  185862000 :       if (!ptr || !POINTER_TYPE_P (TREE_TYPE (ptr)))
    7740                 :   89084600 :         continue;
    7741                 :            : 
    7742                 :            :       /* Avoid all this when ptr is not dereferenced?  */
    7743                 :   15763300 :       tree p = ptr;
    7744                 :   15763300 :       if (SSA_NAME_IS_DEFAULT_DEF (ptr)
    7745                 :    6438990 :           && (TREE_CODE (SSA_NAME_VAR (ptr)) == PARM_DECL
    7746                 :   17094500 :               || TREE_CODE (SSA_NAME_VAR (ptr)) == RESULT_DECL))
    7747                 :    2588190 :         p = SSA_NAME_VAR (ptr);
    7748                 :   15763300 :       varinfo_t vi = lookup_vi_for_tree (p);
    7749                 :   15763300 :       if (!vi)
    7750                 :     704103 :         continue;
    7751                 :   15059200 :       vi = get_varinfo (find (vi->id));
    7752                 :   15059200 :       bitmap_iterator bi;
    7753                 :   15059200 :       unsigned j;
    7754                 :   15059200 :       varinfo_t restrict_var = NULL;
    7755                 :   18077000 :       EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, j, bi)
    7756                 :            :         {
    7757                 :   17153400 :           varinfo_t oi = get_varinfo (j);
    7758                 :   17153400 :           if (oi->head != j)
    7759                 :     753754 :             oi = get_varinfo (oi->head);
    7760                 :   17153400 :           if (oi->is_restrict_var)
    7761                 :            :             {
    7762                 :    1333540 :               if (restrict_var
    7763                 :    1333540 :                   && restrict_var != oi)
    7764                 :            :                 {
    7765                 :         40 :                   if (dump_file && (dump_flags & TDF_DETAILS))
    7766                 :            :                     {
    7767                 :          0 :                       fprintf (dump_file, "found restrict pointed-to "
    7768                 :            :                                "for ");
    7769                 :          0 :                       print_generic_expr (dump_file, ptr);
    7770                 :          0 :                       fprintf (dump_file, " but not exclusively\n");
    7771                 :            :                     }
    7772                 :            :                   restrict_var = NULL;
    7773                 :            :                   break;
    7774                 :            :                 }
    7775                 :            :               restrict_var = oi;
    7776                 :            :             }
    7777 </