LCOV - code coverage report
Current view: top level - gcc - pta-andersen.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 97.7 % 1112 1086
Test Date: 2026-02-28 14:20:25 Functions: 98.0 % 50 49
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Andersen-style solver for tree based points-to analysis
       2              :    Copyright (C) 2005-2026 Free Software Foundation, Inc.
       3              :    Contributed by Daniel Berlin <dberlin@dberlin.org>
       4              : 
       5              :    This file is part of GCC.
       6              : 
       7              :    GCC is free software; you can redistribute it and/or modify
       8              :    under the terms of the GNU General Public License as published by
       9              :    the Free Software Foundation; either version 3 of the License, or
      10              :    (at your option) any later version.
      11              : 
      12              :    GCC is distributed in the hope that it will be useful,
      13              :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      14              :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15              :    GNU General Public License for more details.
      16              : 
      17              :    You should have received a copy of the GNU General Public License
      18              :    along with GCC; see the file COPYING3.  If not see
      19              :    <http://www.gnu.org/licenses/>.  */
      20              : 
      21              : #include "config.h"
      22              : #include "system.h"
      23              : #include "coretypes.h"
      24              : #include "backend.h"
      25              : 
      26              : #include "tree-ssa-structalias.h"
      27              : #include "pta-andersen.h"
      28              : 
      29              : /* During variable substitution and the offline version of indirect
      30              :    cycle finding, we create nodes to represent dereferences and
      31              :    address taken constraints.  These represent where these start and
      32              :    end.  */
      33              : #define FIRST_REF_NODE (varmap).length ()
      34              : #define LAST_REF_NODE (FIRST_REF_NODE + (FIRST_REF_NODE - 1))
      35              : 
      36              : #define EXECUTE_IF_IN_NONNULL_BITMAP(a, b, c, d)        \
      37              :   if (a)                                                \
      38              :     EXECUTE_IF_SET_IN_BITMAP (a, b, c, d)
      39              : 
      40              : using namespace pointer_analysis;
      41              : 
      42              : /* Used for predecessor bitmaps.  */
      43              : static bitmap_obstack predbitmap_obstack;
      44              : 
      45              : /* Used for per-solver-iteration bitmaps.  */
      46              : static bitmap_obstack iteration_obstack;
      47              : 
      48              : typedef struct constraint_graph *constraint_graph_t;
      49              : 
      50              : /* The constraint graph is represented as an array of bitmaps
      51              :    containing successor nodes.  */
      52              : 
      53              : struct constraint_graph
      54              : {
      55              :   /* Size of this graph, which may be different than the number of
      56              :      nodes in the variable map.  */
      57              :   unsigned int size;
      58              : 
      59              :   /* Explicit successors of each node.  */
      60              :   bitmap *succs;
      61              : 
      62              :   /* Implicit predecessors of each node (Used for variable
      63              :      substitution). */
      64              :   bitmap *implicit_preds;
      65              : 
      66              :   /* Explicit predecessors of each node (Used for variable substitution).  */
      67              :   bitmap *preds;
      68              : 
      69              :   /* Indirect cycle representatives, or -1 if the node has no indirect
      70              :      cycles.  */
      71              :   int *indirect_cycles;
      72              : 
      73              :   /* Representative node for a node.  rep[a] == a unless the node has
      74              :      been unified.  */
      75              :   unsigned int *rep;
      76              : 
      77              :   /* Equivalence class representative for a label.  This is used for
      78              :      variable substitution.  */
      79              :   int *eq_rep;
      80              : 
      81              :   /* Pointer equivalence label for a node.  All nodes with the same
      82              :      pointer equivalence label can be unified together at some point
      83              :      (either during constraint optimization or after the constraint
      84              :      graph is built).  */
      85              :   unsigned int *pe;
      86              : 
      87              :   /* Pointer equivalence representative for a label.  This is used to
      88              :      handle nodes that are pointer equivalent but not location
      89              :      equivalent.  We can unite these once the addressof constraints
      90              :      are transformed into initial points-to sets.  */
      91              :   int *pe_rep;
      92              : 
      93              :   /* Pointer equivalence label for each node, used during variable
      94              :      substitution.  */
      95              :   unsigned int *pointer_label;
      96              : 
      97              :   /* Location equivalence label for each node, used during location
      98              :      equivalence finding.  */
      99              :   unsigned int *loc_label;
     100              : 
     101              :   /* Pointed-by set for each node, used during location equivalence
     102              :      finding.  This is pointed-by rather than pointed-to, because it
     103              :      is constructed using the predecessor graph.  */
     104              :   bitmap *pointed_by;
     105              : 
     106              :   /* Points to sets for pointer equivalence.  This is *not* the actual
     107              :      points-to sets for nodes.  */
     108              :   bitmap *points_to;
     109              : 
     110              :   /* Bitmap of nodes where the bit is set if the node is a direct
     111              :      node.  Used for variable substitution.  */
     112              :   sbitmap direct_nodes;
     113              : 
     114              :   /* Bitmap of nodes where the bit is set if the node is address
     115              :      taken.  Used for variable substitution.  */
     116              :   bitmap address_taken;
     117              : 
     118              :   /* Vector of complex constraints for each graph node.  Complex
     119              :      constraints are those involving dereferences or offsets that are
     120              :      not 0.  */
     121              :   vec<constraint_t> *complex;
     122              : };
     123              : 
     124              : static constraint_graph_t graph;
     125              : 
     126              : static void unify_nodes (constraint_graph_t, unsigned int, unsigned int, bool);
     127              : 
     128              : 
     129              : /* Return the representative node for NODE, if NODE has been unioned
     130              :    with another NODE.
     131              :    This function performs path compression along the way to finding
     132              :    the representative.  */
     133              : 
     134              : static unsigned int
     135   9273931844 : find (unsigned int node)
     136              : {
     137   9273931844 :   gcc_checking_assert (node < graph->size);
     138   9273931844 :   if (graph->rep[node] != node)
     139   1049986764 :     return graph->rep[node] = find (graph->rep[node]);
     140              :   return node;
     141              : }
     142              : 
     143              : /* Union the TO and FROM nodes to the TO nodes.
     144              :    Note that at some point in the future, we may want to do
     145              :    union-by-rank, in which case we are going to have to return the
     146              :    node we unified to.  */
     147              : 
     148              : static bool
     149    591747803 : unite (unsigned int to, unsigned int from)
     150              : {
     151    591747803 :   gcc_checking_assert (to < graph->size && from < graph->size);
     152    591747803 :   if (to != from && graph->rep[from] != to)
     153              :     {
     154     69667372 :       graph->rep[from] = to;
     155     69667372 :       return true;
     156              :     }
     157              :   return false;
     158              : }
     159              : 
     160              : /* Perform path compression for all nodes in the node representatives
     161              :    union-find structure.  */
     162              : 
     163              : static void
     164      4415916 : union_find_compress_all (void)
     165              : {
     166      4415916 :   unsigned int i;
     167    229396132 :   for (i = 0; i < graph->size; i++)
     168    224980216 :     find (i);
     169      4415916 : }
     170              : 
     171              : /* Print the constraint graph in dot format.  */
     172              : 
     173              : static void
     174            6 : dump_constraint_graph (FILE *file)
     175              : {
     176            6 :   unsigned int i;
     177              : 
     178              :   /* Only print the graph if it has already been initialized:  */
     179            6 :   if (!graph)
     180              :     return;
     181              : 
     182              :   /* Prints the header of the dot file:  */
     183            6 :   fprintf (file, "strict digraph {\n");
     184            6 :   fprintf (file, "  node [\n    shape = box\n  ]\n");
     185            6 :   fprintf (file, "  edge [\n    fontsize = \"12\"\n  ]\n");
     186            6 :   fprintf (file, "\n  // List of nodes and complex constraints in "
     187              :            "the constraint graph:\n");
     188              : 
     189              :   /* The next lines print the nodes in the graph together with the
     190              :      complex constraints attached to them.  */
     191           80 :   for (i = 1; i < graph->size; i++)
     192              :     {
     193          148 :       if (i == FIRST_REF_NODE)
     194            0 :         continue;
     195           74 :       if (find (i) != i)
     196            2 :         continue;
     197           72 :       if (i < FIRST_REF_NODE)
     198           72 :         fprintf (file, "\"%s\"", get_varinfo (i)->name);
     199              :       else
     200            0 :         fprintf (file, "\"*%s\"", get_varinfo (i - FIRST_REF_NODE)->name);
     201           72 :       if (graph->complex[i].exists ())
     202              :         {
     203           16 :           unsigned j;
     204           16 :           constraint_t c;
     205           16 :           fprintf (file, " [label=\"\\N\\n");
     206           70 :           for (j = 0; graph->complex[i].iterate (j, &c); ++j)
     207              :             {
     208           38 :               dump_constraint (file, c);
     209           38 :               fprintf (file, "\\l");
     210              :             }
     211           16 :           fprintf (file, "\"]");
     212              :         }
     213           72 :       fprintf (file, ";\n");
     214              :     }
     215              : 
     216              :   /* Go over the edges.  */
     217            6 :   fprintf (file, "\n  // Edges in the constraint graph:\n");
     218           80 :   for (i = 1; i < graph->size; i++)
     219              :     {
     220           74 :       unsigned j;
     221           74 :       bitmap_iterator bi;
     222           74 :       if (find (i) != i)
     223            2 :         continue;
     224          102 :       EXECUTE_IF_IN_NONNULL_BITMAP (graph->succs[i], 0, j, bi)
     225              :         {
     226           30 :           unsigned to = find (j);
     227           30 :           if (i == to)
     228            0 :             continue;
     229           30 :           if (i < FIRST_REF_NODE)
     230           30 :             fprintf (file, "\"%s\"", get_varinfo (i)->name);
     231              :           else
     232            0 :             fprintf (file, "\"*%s\"", get_varinfo (i - FIRST_REF_NODE)->name);
     233           30 :           fprintf (file, " -> ");
     234           30 :           if (to < FIRST_REF_NODE)
     235           30 :             fprintf (file, "\"%s\"", get_varinfo (to)->name);
     236              :           else
     237            0 :             fprintf (file, "\"*%s\"", get_varinfo (to - FIRST_REF_NODE)->name);
     238           30 :           fprintf (file, ";\n");
     239              :         }
     240              :     }
     241              : 
     242              :   /* Prints the tail of the dot file.  */
     243            6 :   fprintf (file, "}\n");
     244              : }
     245              : 
     246              : /* Print out the constraint graph to stderr.  */
     247              : 
     248              : DEBUG_FUNCTION void
     249            0 : debug_constraint_graph (void)
     250              : {
     251            0 :   dump_constraint_graph (stderr);
     252            0 : }
     253              : 
     254              : 
     255              : /* SOLVER FUNCTIONS
     256              : 
     257              :    The solver is a simple worklist solver, that works on the following
     258              :    algorithm:
     259              : 
     260              :    sbitmap changed_nodes = all zeroes;
     261              :    changed_count = 0;
     262              :    For each node that is not already collapsed:
     263              :        changed_count++;
     264              :        set bit in changed nodes
     265              : 
     266              :    while (changed_count > 0)
     267              :    {
     268              :      compute topological ordering for constraint graph
     269              : 
     270              :      find and collapse cycles in the constraint graph (updating
     271              :      changed if necessary)
     272              : 
     273              :      for each node (n) in the graph in topological order:
     274              :        changed_count--;
     275              : 
     276              :        Process each complex constraint associated with the node,
     277              :        updating changed if necessary.
     278              : 
     279              :        For each outgoing edge from n, propagate the solution from n to
     280              :        the destination of the edge, updating changed as necessary.
     281              : 
     282              :    }  */
     283              : 
     284              : /* Return true if two constraint expressions A and B are equal.  */
     285              : 
     286              : static bool
     287     19188668 : constraint_expr_equal (struct constraint_expr a, struct constraint_expr b)
     288              : {
     289     11981889 :   return a.type == b.type && a.var == b.var && a.offset == b.offset;
     290              : }
     291              : 
     292              : /* Return true if constraint expression A is less than constraint expression
     293              :    B.  This is just arbitrary, but consistent, in order to give them an
     294              :    ordering.  */
     295              : 
     296              : static bool
     297    449382623 : constraint_expr_less (struct constraint_expr a, struct constraint_expr b)
     298              : {
     299            0 :   if (a.type == b.type)
     300              :     {
     301    268610025 :       if (a.var == b.var)
     302    201326930 :         return a.offset < b.offset;
     303              :       else
     304     67283095 :         return a.var < b.var;
     305              :     }
     306              :   else
     307    180772598 :     return a.type < b.type;
     308              : }
     309              : 
     310              : /* Return true if constraint A is less than constraint B.  This is just
     311              :    arbitrary, but consistent, in order to give them an ordering.  */
     312              : 
     313              : static bool
     314    247255416 : constraint_less (const constraint_t &a, const constraint_t &b)
     315              : {
     316    494510832 :   if (constraint_expr_less (a->lhs, b->lhs))
     317              :     return true;
     318    213821300 :   else if (constraint_expr_less (b->lhs, a->lhs))
     319              :     return false;
     320              :   else
     321     95216557 :     return constraint_expr_less (a->rhs, b->rhs);
     322              : }
     323              : 
     324              : /* Return true if two constraints A and B are equal.  */
     325              : 
     326              : static bool
     327     12597130 : constraint_equal (const constraint &a, const constraint &b)
     328              : {
     329     19188668 :   return constraint_expr_equal (a.lhs, b.lhs)
     330     12597130 :     && constraint_expr_equal (a.rhs, b.rhs);
     331              : }
     332              : 
     333              : /* Find a constraint LOOKFOR in the sorted constraint vector VEC.  */
     334              : 
     335              : static constraint_t
     336       265964 : constraint_vec_find (vec<constraint_t> vec,
     337              :                      constraint &lookfor)
     338              : {
     339       265964 :   unsigned int place;
     340       265964 :   constraint_t found;
     341              : 
     342       265964 :   if (!vec.exists ())
     343              :     return NULL;
     344              : 
     345       212678 :   place = vec.lower_bound (&lookfor, constraint_less);
     346       212678 :   if (place >= vec.length ())
     347              :     return NULL;
     348        83446 :   found = vec[place];
     349        83446 :   if (!constraint_equal (*found, lookfor))
     350              :     return NULL;
     351              :   return found;
     352              : }
     353              : 
     354              : /* Union two constraint vectors, TO and FROM.  Put the result in TO.
     355              :    Returns true of TO set is changed.  */
     356              : 
     357              : static bool
     358     69547016 : constraint_set_union (vec<constraint_t> *to,
     359              :                       vec<constraint_t> *from)
     360              : {
     361     69547016 :   int i;
     362     69547016 :   constraint_t c;
     363     69547016 :   bool any_change = false;
     364              : 
     365     69812980 :   FOR_EACH_VEC_ELT (*from, i, c)
     366              :     {
     367       265964 :       if (constraint_vec_find (*to, *c) == NULL)
     368              :         {
     369       265481 :           unsigned int place = to->lower_bound (c, constraint_less);
     370       265481 :           to->safe_insert (place, c);
     371       265481 :           any_change = true;
     372              :         }
     373              :     }
     374     69547016 :   return any_change;
     375              : }
     376              : 
     377              : /* Expands the solution in SET to all sub-fields of variables included.  */
     378              : 
     379              : static bitmap
     380    134397636 : solution_set_expand (bitmap set, bitmap *expanded)
     381              : {
     382    134397636 :   bitmap_iterator bi;
     383    134397636 :   unsigned j;
     384              : 
     385    134397636 :   if (*expanded)
     386              :     return *expanded;
     387              : 
     388     74938141 :   *expanded = BITMAP_ALLOC (&iteration_obstack);
     389              : 
     390              :   /* In a first pass expand variables, once for each head to avoid
     391              :      quadratic behavior, to include all sub-fields.  */
     392     74938141 :   unsigned prev_head = 0;
     393    294254207 :   EXECUTE_IF_SET_IN_BITMAP (set, 0, j, bi)
     394              :     {
     395    219316066 :       varinfo_t v = get_varinfo (j);
     396    219316066 :       if (v->is_artificial_var
     397    130662080 :           || v->is_full_var)
     398    109870160 :         continue;
     399    109445906 :       if (v->head != prev_head)
     400              :         {
     401     24609609 :           varinfo_t head = get_varinfo (v->head);
     402     24609609 :           unsigned num = 1;
     403    145992285 :           for (varinfo_t n = vi_next (head); n != NULL; n = vi_next (n))
     404              :             {
     405    121382676 :               if (n->id != head->id + num)
     406              :                 {
     407              :                   /* Usually sub variables are adjacent but since we
     408              :                      create pointed-to restrict representatives there
     409              :                      can be gaps as well.  */
     410        17194 :                   bitmap_set_range (*expanded, head->id, num);
     411        17194 :                   head = n;
     412        17194 :                   num = 1;
     413              :                 }
     414              :               else
     415    121365482 :                 num++;
     416              :             }
     417              : 
     418     24609609 :           bitmap_set_range (*expanded, head->id, num);
     419     24609609 :           prev_head = v->head;
     420              :         }
     421              :     }
     422              : 
     423              :   /* And finally set the rest of the bits from SET in an efficient way.  */
     424     74938141 :   bitmap_ior_into (*expanded, set);
     425              : 
     426     74938141 :   return *expanded;
     427              : }
     428              : 
     429              : /* Union solution sets TO and DELTA, and add INC to each member of DELTA in the
     430              :    process.  */
     431              : 
     432              : static bool
     433     83996388 : set_union_with_increment (bitmap to, bitmap delta, HOST_WIDE_INT inc,
     434              :                           bitmap *expanded_delta)
     435              : {
     436     83996388 :   bool changed = false;
     437     83996388 :   bitmap_iterator bi;
     438     83996388 :   unsigned int i;
     439              : 
     440              :   /* If the solution of DELTA contains anything it is good enough to transfer
     441              :      this to TO.  */
     442     83996388 :   if (bitmap_bit_p (delta, anything_id))
     443      1181147 :     return bitmap_set_bit (to, anything_id);
     444              : 
     445              :   /* If the offset is unknown we have to expand the solution to
     446              :      all subfields.  */
     447     82815241 :   if (inc == UNKNOWN_OFFSET)
     448              :     {
     449     81855057 :       delta = solution_set_expand (delta, expanded_delta);
     450     81855057 :       changed |= bitmap_ior_into (to, delta);
     451     81855057 :       return changed;
     452              :     }
     453              : 
     454              :   /* For non-zero offset union the offsetted solution into the destination.  */
     455      4345780 :   EXECUTE_IF_SET_IN_BITMAP (delta, 0, i, bi)
     456              :     {
     457      3385596 :       varinfo_t vi = get_varinfo (i);
     458              : 
     459              :       /* If this is a variable with just one field just set its bit
     460              :          in the result.  */
     461      3385596 :       if (vi->is_artificial_var
     462      2127492 :           || vi->is_unknown_size_var
     463      1943961 :           || vi->is_full_var)
     464      1669605 :         changed |= bitmap_set_bit (to, i);
     465              :       else
     466              :         {
     467      1715991 :           HOST_WIDE_INT fieldoffset = vi->offset + inc;
     468      1715991 :           unsigned HOST_WIDE_INT size = vi->size;
     469              : 
     470              :           /* If the offset makes the pointer point to before the
     471              :              variable use offset zero for the field lookup.  */
     472      1715991 :           if (fieldoffset < 0)
     473        62386 :             vi = get_varinfo (vi->head);
     474              :           else
     475      1653605 :             vi = first_or_preceding_vi_for_offset (vi, fieldoffset);
     476              : 
     477      2756651 :           do
     478              :             {
     479      2756651 :               changed |= bitmap_set_bit (to, vi->id);
     480      2756651 :               if (vi->is_full_var
     481      2756611 :                   || vi->next == 0)
     482              :                 break;
     483              : 
     484              :               /* We have to include all fields that overlap the current field
     485              :                  shifted by inc.  */
     486      1670188 :               vi = vi_next (vi);
     487              :             }
     488      1670188 :           while (vi->offset < fieldoffset + size);
     489              :         }
     490              :     }
     491              : 
     492              :   return changed;
     493              : }
     494              : 
     495              : /* Insert constraint C into the list of complex constraints for graph
     496              :    node VAR.  */
     497              : 
     498              : static void
     499    143871550 : insert_into_complex (constraint_graph_t graph,
     500              :                      unsigned int var, constraint_t c)
     501              : {
     502    143871550 :   vec<constraint_t> complex = graph->complex[var];
     503    143871550 :   unsigned int place = complex.lower_bound (c, constraint_less);
     504              : 
     505              :   /* Only insert constraints that do not already exist.  */
     506    143871550 :   if (place >= complex.length ()
     507     98862729 :       || !constraint_equal (*c, *complex[place]))
     508    141912654 :     graph->complex[var].safe_insert (place, c);
     509    143871550 : }
     510              : 
     511              : 
     512              : /* Condense two variable nodes into a single variable node, by moving
     513              :    all associated info from FROM to TO.  Returns true if TO node's
     514              :    constraint set changes after the merge.  */
     515              : 
     516              : static bool
     517     69547016 : merge_node_constraints (constraint_graph_t graph, unsigned int to,
     518              :                         unsigned int from)
     519              : {
     520     69547016 :   unsigned int i;
     521     69547016 :   constraint_t c;
     522     69547016 :   bool any_change = false;
     523              : 
     524     69547016 :   gcc_checking_assert (find (from) == to);
     525              : 
     526              :   /* Move all complex constraints from src node into to node.  */
     527     69812980 :   FOR_EACH_VEC_ELT (graph->complex[from], i, c)
     528              :     {
     529              :       /* In complex constraints for node FROM, we may have either
     530              :          a = *FROM, and *FROM = a, or an offseted constraint which are
     531              :          always added to the rhs node's constraints.  */
     532              : 
     533       265964 :       if (c->rhs.type == DEREF)
     534        87014 :         c->rhs.var = to;
     535       178950 :       else if (c->lhs.type == DEREF)
     536        87970 :         c->lhs.var = to;
     537              :       else
     538        90980 :         c->rhs.var = to;
     539              : 
     540              :     }
     541     69547016 :   any_change = constraint_set_union (&graph->complex[to],
     542              :                                      &graph->complex[from]);
     543     69547016 :   graph->complex[from].release ();
     544     69547016 :   return any_change;
     545              : }
     546              : 
     547              : /* Remove edges involving NODE from GRAPH.  */
     548              : 
     549              : static void
     550     89270388 : clear_edges_for_node (constraint_graph_t graph, unsigned int node)
     551              : {
     552     89270388 :   if (graph->succs[node])
     553      2420744 :     BITMAP_FREE (graph->succs[node]);
     554     89270388 : }
     555              : 
     556              : /* Merge GRAPH nodes FROM and TO into node TO.  */
     557              : 
     558              : static void
     559     69547016 : merge_graph_nodes (constraint_graph_t graph, unsigned int to,
     560              :                    unsigned int from)
     561              : {
     562     69547016 :   if (graph->indirect_cycles[from] != -1)
     563              :     {
     564              :       /* If we have indirect cycles with the from node, and we have
     565              :          none on the to node, the to node has indirect cycles from the
     566              :          from node now that they are unified.
     567              :          If indirect cycles exist on both, unify the nodes that they
     568              :          are in a cycle with, since we know they are in a cycle with
     569              :          each other.  */
     570          117 :       if (graph->indirect_cycles[to] == -1)
     571           73 :         graph->indirect_cycles[to] = graph->indirect_cycles[from];
     572              :     }
     573              : 
     574              :   /* Merge all the successor edges.  */
     575     69547016 :   if (graph->succs[from])
     576              :     {
     577      2420744 :       if (!graph->succs[to])
     578      1232286 :         graph->succs[to] = BITMAP_ALLOC (&pta_obstack);
     579      2420744 :       bitmap_ior_into (graph->succs[to],
     580      2420744 :                        graph->succs[from]);
     581              :     }
     582              : 
     583     69547016 :   clear_edges_for_node (graph, from);
     584     69547016 : }
     585              : 
     586              : 
     587              : /* Add an indirect graph edge to GRAPH, going from TO to FROM if
     588              :    it doesn't exist in the graph already.  */
     589              : 
     590              : static void
     591    290074372 : add_implicit_graph_edge (constraint_graph_t graph, unsigned int to,
     592              :                          unsigned int from)
     593              : {
     594    290074372 :   if (to == from)
     595              :     return;
     596              : 
     597    290074372 :   if (!graph->implicit_preds[to])
     598    162403278 :     graph->implicit_preds[to] = BITMAP_ALLOC (&predbitmap_obstack);
     599              : 
     600    290074372 :   if (bitmap_set_bit (graph->implicit_preds[to], from))
     601    272749759 :     stats.num_implicit_edges++;
     602              : }
     603              : 
     604              : /* Add a predecessor graph edge to GRAPH, going from TO to FROM if
     605              :    it doesn't exist in the graph already.
     606              :    Return false if the edge already existed, true otherwise.  */
     607              : 
     608              : static void
     609    245171208 : add_pred_graph_edge (constraint_graph_t graph, unsigned int to,
     610              :                      unsigned int from)
     611              : {
     612    245171208 :   if (!graph->preds[to])
     613    144481620 :     graph->preds[to] = BITMAP_ALLOC (&predbitmap_obstack);
     614    245171208 :   bitmap_set_bit (graph->preds[to], from);
     615    245171208 : }
     616              : 
     617              : /* Add a graph edge to GRAPH, going from FROM to TO if
     618              :    it doesn't exist in the graph already.
     619              :    Return false if the edge already existed, true otherwise.  */
     620              : 
     621              : static bool
     622    788308239 : add_graph_edge (constraint_graph_t graph, unsigned int to,
     623              :                 unsigned int from)
     624              : {
     625    788308239 :   if (to == from)
     626              :     {
     627              :       return false;
     628              :     }
     629              :   else
     630              :     {
     631    787577261 :       bool r = false;
     632              : 
     633    787577261 :       if (!graph->succs[from])
     634     91734105 :         graph->succs[from] = BITMAP_ALLOC (&pta_obstack);
     635              : 
     636              :       /* The graph solving process does not avoid "triangles", thus
     637              :          there can be multiple paths from a node to another involving
     638              :          intermediate other nodes.  That causes extra copying which is
     639              :          most difficult to avoid when the intermediate node is ESCAPED
     640              :          because there are no edges added from ESCAPED.  Avoid
     641              :          adding the direct edge FROM -> TO when we have FROM -> ESCAPED
     642              :          and TO contains ESCAPED.
     643              :          ???  Note this is only a heuristic, it does not prevent the
     644              :          situation from occuring.  The heuristic helps PR38474 and
     645              :          PR99912 significantly.  */
     646    787577261 :       if (to < FIRST_REF_NODE
     647    756183991 :           && bitmap_bit_p (graph->succs[from], find (escaped_id))
     648   1150304682 :           && bitmap_bit_p (get_varinfo (find (to))->solution, escaped_id))
     649              :         {
     650    305170427 :           stats.num_avoided_edges++;
     651    305170427 :           return false;
     652              :         }
     653              : 
     654    482406834 :       if (bitmap_set_bit (graph->succs[from], to))
     655              :         {
     656    337868317 :           r = true;
     657    337868317 :           if (to < FIRST_REF_NODE && from < FIRST_REF_NODE)
     658    294459667 :             stats.num_edges++;
     659              :         }
     660    482406834 :       return r;
     661              :     }
     662              : }
     663              : 
     664              : /* Initialize the constraint graph structure to contain SIZE nodes.  */
     665              : 
     666              : static void
     667      4415916 : init_graph (unsigned int size)
     668              : {
     669      4415916 :   unsigned int j;
     670              : 
     671      4415916 :   bitmap_obstack_initialize (&predbitmap_obstack);
     672              : 
     673      4415916 :   graph = XCNEW (struct constraint_graph);
     674      4415916 :   graph->size = size;
     675      4415916 :   graph->succs = XCNEWVEC (bitmap, graph->size);
     676      4415916 :   graph->indirect_cycles = XNEWVEC (int, graph->size);
     677      4415916 :   graph->rep = XNEWVEC (unsigned int, graph->size);
     678              :   /* ??? Macros do not support template types with multiple arguments,
     679              :      so we use a typedef to work around it.  */
     680      4415916 :   typedef vec<constraint_t> vec_constraint_t_heap;
     681      4415916 :   graph->complex = XCNEWVEC (vec_constraint_t_heap, size);
     682      4415916 :   graph->pe = XCNEWVEC (unsigned int, graph->size);
     683      4415916 :   graph->pe_rep = XNEWVEC (int, graph->size);
     684              : 
     685    454376348 :   for (j = 0; j < graph->size; j++)
     686              :     {
     687    449960432 :       graph->rep[j] = j;
     688    449960432 :       graph->pe_rep[j] = -1;
     689    449960432 :       graph->indirect_cycles[j] = -1;
     690              :     }
     691      4415916 : }
     692              : 
     693              : /* Build the constraint graph, adding only predecessor edges right now.  */
     694              : 
     695              : static void
     696      4415916 : build_pred_graph (void)
     697              : {
     698      4415916 :   int i;
     699      4415916 :   constraint_t c;
     700      4415916 :   unsigned int j;
     701              : 
     702      4415916 :   graph->implicit_preds = XCNEWVEC (bitmap, graph->size);
     703      4415916 :   graph->preds = XCNEWVEC (bitmap, graph->size);
     704      4415916 :   graph->pointer_label = XCNEWVEC (unsigned int, graph->size);
     705      4415916 :   graph->loc_label = XCNEWVEC (unsigned int, graph->size);
     706      4415916 :   graph->pointed_by = XCNEWVEC (bitmap, graph->size);
     707      4415916 :   graph->points_to = XCNEWVEC (bitmap, graph->size);
     708      4415916 :   graph->eq_rep = XNEWVEC (int, graph->size);
     709      4415916 :   graph->direct_nodes = sbitmap_alloc (graph->size);
     710      4415916 :   graph->address_taken = BITMAP_ALLOC (&predbitmap_obstack);
     711      4415916 :   bitmap_clear (graph->direct_nodes);
     712              : 
     713    454376348 :   for (j = 1; j < FIRST_REF_NODE; j++)
     714              :     {
     715    220564300 :       if (!get_varinfo (j)->is_special_var)
     716    198484720 :         bitmap_set_bit (graph->direct_nodes, j);
     717              :     }
     718              : 
     719    454376348 :   for (j = 0; j < graph->size; j++)
     720    449960432 :     graph->eq_rep[j] = -1;
     721              : 
     722    458792264 :   for (j = 0; j < varmap.length (); j++)
     723    224980216 :     graph->indirect_cycles[j] = -1;
     724              : 
     725    439574561 :   FOR_EACH_VEC_ELT (constraints, i, c)
     726              :     {
     727    435158645 :       struct constraint_expr lhs = c->lhs;
     728    435158645 :       struct constraint_expr rhs = c->rhs;
     729    435158645 :       unsigned int lhsvar = lhs.var;
     730    435158645 :       unsigned int rhsvar = rhs.var;
     731              : 
     732    435158645 :       if (lhs.type == DEREF)
     733              :         {
     734              :           /* *x = y.  */
     735     35732151 :           if (rhs.offset == 0 && lhs.offset == 0 && rhs.type == SCALAR)
     736              :             {
     737     31415715 :               if (lhs.var == anything_id)
     738            0 :                 add_pred_graph_edge (graph, storedanything_id, rhsvar);
     739              :               else
     740     62831430 :                 add_pred_graph_edge (graph, FIRST_REF_NODE + lhsvar, rhsvar);
     741              :             }
     742              :         }
     743    399426494 :       else if (rhs.type == DEREF)
     744              :         {
     745              :           /* x = *y */
     746     48255330 :           if (rhs.offset == 0 && lhs.offset == 0 && lhs.type == SCALAR)
     747     26094418 :             add_pred_graph_edge (graph, lhsvar, FIRST_REF_NODE + rhsvar);
     748              :           else
     749     35208121 :             bitmap_clear_bit (graph->direct_nodes, lhsvar);
     750              :         }
     751    351171164 :       else if (rhs.type == ADDRESSOF)
     752              :         {
     753     89366088 :           varinfo_t v;
     754              : 
     755              :           /* x = &y */
     756     89366088 :           if (graph->points_to[lhsvar] == NULL)
     757     66412194 :             graph->points_to[lhsvar] = BITMAP_ALLOC (&predbitmap_obstack);
     758     89366088 :           bitmap_set_bit (graph->points_to[lhsvar], rhsvar);
     759              : 
     760     89366088 :           if (graph->pointed_by[rhsvar] == NULL)
     761     21439098 :             graph->pointed_by[rhsvar] = BITMAP_ALLOC (&predbitmap_obstack);
     762     89366088 :           bitmap_set_bit (graph->pointed_by[rhsvar], lhsvar);
     763              : 
     764              :           /* Implicitly, *x = y */
     765    178732176 :           add_implicit_graph_edge (graph, FIRST_REF_NODE + lhsvar, rhsvar);
     766              : 
     767              :           /* All related variables are no longer direct nodes.  */
     768     89366088 :           bitmap_clear_bit (graph->direct_nodes, rhsvar);
     769     89366088 :           v = get_varinfo (rhsvar);
     770     89366088 :           if (!v->is_full_var)
     771              :             {
     772      7203851 :               v = get_varinfo (v->head);
     773     46311264 :               do
     774              :                 {
     775     46311264 :                   bitmap_clear_bit (graph->direct_nodes, v->id);
     776     46311264 :                   v = vi_next (v);
     777              :                 }
     778     46311264 :               while (v != NULL);
     779              :             }
     780     89366088 :           bitmap_set_bit (graph->address_taken, rhsvar);
     781              :         }
     782    261805076 :       else if (lhsvar > anything_id
     783    261805076 :                && lhsvar != rhsvar && lhs.offset == 0 && rhs.offset == 0)
     784              :         {
     785              :           /* x = y */
     786    200708284 :           add_pred_graph_edge (graph, lhsvar, rhsvar);
     787              :           /* Implicitly, *x = *y */
     788    200708284 :           add_implicit_graph_edge (graph, FIRST_REF_NODE + lhsvar,
     789    200708284 :                                    FIRST_REF_NODE + rhsvar);
     790              :         }
     791     61096792 :       else if (lhs.offset != 0 || rhs.offset != 0)
     792              :         {
     793     60901245 :           if (rhs.offset != 0)
     794     60901245 :             bitmap_clear_bit (graph->direct_nodes, lhs.var);
     795            0 :           else if (lhs.offset != 0)
     796            0 :             bitmap_clear_bit (graph->direct_nodes, rhs.var);
     797              :         }
     798              :     }
     799      4415916 : }
     800              : 
     801              : /* Build the constraint graph, adding successor edges.  */
     802              : 
     803              : static void
     804      4415916 : build_succ_graph (void)
     805              : {
     806      4415916 :   unsigned i, t;
     807      4415916 :   constraint_t c;
     808              : 
     809    439574561 :   FOR_EACH_VEC_ELT (constraints, i, c)
     810              :     {
     811    435158645 :       struct constraint_expr lhs;
     812    435158645 :       struct constraint_expr rhs;
     813    435158645 :       unsigned int lhsvar;
     814    435158645 :       unsigned int rhsvar;
     815              : 
     816    435158645 :       if (!c)
     817      2455141 :         continue;
     818              : 
     819    432703504 :       lhs = c->lhs;
     820    432703504 :       rhs = c->rhs;
     821    432703504 :       lhsvar = find (lhs.var);
     822    432703504 :       rhsvar = find (rhs.var);
     823              : 
     824    432703504 :       if (lhs.type == DEREF)
     825              :         {
     826     35689454 :           if (rhs.offset == 0 && lhs.offset == 0 && rhs.type == SCALAR)
     827              :             {
     828     31393270 :               if (lhs.var == anything_id)
     829            0 :                 add_graph_edge (graph, storedanything_id, rhsvar);
     830              :               else
     831     62786540 :                 add_graph_edge (graph, FIRST_REF_NODE + lhsvar, rhsvar);
     832              :             }
     833              :         }
     834    397014050 :       else if (rhs.type == DEREF)
     835              :         {
     836     48254352 :           if (rhs.offset == 0 && lhs.offset == 0 && lhs.type == SCALAR)
     837     26092838 :             add_graph_edge (graph, lhsvar, FIRST_REF_NODE + rhsvar);
     838              :         }
     839    348759698 :       else if (rhs.type == ADDRESSOF)
     840              :         {
     841              :           /* x = &y */
     842     89366088 :           gcc_checking_assert (find (rhs.var) == rhs.var);
     843     89366088 :           bitmap_set_bit (get_varinfo (lhsvar)->solution, rhsvar);
     844              :         }
     845    259393610 :       else if (lhsvar > anything_id
     846    259393610 :                && lhsvar != rhsvar && lhs.offset == 0 && rhs.offset == 0)
     847              :         {
     848    150805404 :           add_graph_edge (graph, lhsvar, rhsvar);
     849              :         }
     850              :     }
     851              : 
     852              :   /* Add edges from STOREDANYTHING to all nodes that can receive pointers.  */
     853      4415916 :   t = find (storedanything_id);
     854    194068804 :   for (i = integer_id + 1; i < FIRST_REF_NODE; ++i)
     855              :     {
     856    185236972 :       if (get_varinfo (i)->may_have_pointers)
     857    185213250 :         add_graph_edge (graph, find (i), t);
     858              :     }
     859              : 
     860              :   /* Everything stored to ANYTHING also potentially escapes.  */
     861      4415916 :   add_graph_edge (graph, find (escaped_id), t);
     862      4415916 : }
     863              : 
     864              : 
     865              : /* Changed variables on the last iteration.  */
     866              : static bitmap changed;
     867              : 
     868              : /* Strongly Connected Component visitation info.  */
     869              : 
     870              : class scc_info
     871              : {
     872              : public:
     873              :   scc_info (size_t size);
     874              :   ~scc_info ();
     875              : 
     876              :   auto_sbitmap visited;
     877              :   auto_sbitmap deleted;
     878              :   unsigned int *dfs;
     879              :   unsigned int *node_mapping;
     880              :   int current_index;
     881              :   auto_vec<unsigned> scc_stack;
     882              : };
     883              : 
     884              : 
     885              : /* Recursive routine to find strongly connected components in GRAPH.
     886              :    SI is the SCC info to store the information in, and N is the id of current
     887              :    graph node we are processing.
     888              : 
     889              :    This is Tarjan's strongly connected component finding algorithm, as
     890              :    modified by Nuutila to keep only non-root nodes on the stack.
     891              :    The algorithm can be found in "On finding the strongly connected
     892              :    connected components in a directed graph" by Esko Nuutila and Eljas
     893              :    Soisalon-Soininen, in Information Processing Letters volume 49,
     894              :    number 1, pages 9-14.  */
     895              : 
     896              : static void
     897    377177230 : scc_visit (constraint_graph_t graph, class scc_info *si, unsigned int n)
     898              : {
     899    377177230 :   unsigned int i;
     900    377177230 :   bitmap_iterator bi;
     901    377177230 :   unsigned int my_dfs;
     902              : 
     903    377177230 :   bitmap_set_bit (si->visited, n);
     904    377177230 :   si->dfs[n] = si->current_index ++;
     905    377177230 :   my_dfs = si->dfs[n];
     906              : 
     907              :   /* Visit all the successors.  */
     908    640523914 :   EXECUTE_IF_IN_NONNULL_BITMAP (graph->succs[n], 0, i, bi)
     909              :     {
     910    263346684 :       unsigned int w;
     911              : 
     912    526693368 :       if (i > LAST_REF_NODE)
     913              :         break;
     914              : 
     915    263346684 :       w = find (i);
     916    263346684 :       if (bitmap_bit_p (si->deleted, w))
     917    114239840 :         continue;
     918              : 
     919    149106844 :       if (!bitmap_bit_p (si->visited, w))
     920    148845100 :         scc_visit (graph, si, w);
     921              : 
     922    149106844 :       unsigned int t = find (w);
     923    149106844 :       gcc_checking_assert (find (n) == n);
     924    149106844 :       if (si->dfs[t] < si->dfs[n])
     925       139269 :         si->dfs[n] = si->dfs[t];
     926              :     }
     927              : 
     928              :   /* See if any components have been identified.  */
     929    377177230 :   if (si->dfs[n] == my_dfs)
     930              :     {
     931    377038019 :       if (si->scc_stack.length () > 0
     932    377038019 :           && si->dfs[si->scc_stack.last ()] >= my_dfs)
     933              :         {
     934       105670 :           bitmap scc = BITMAP_ALLOC (NULL);
     935       105670 :           unsigned int lowest_node;
     936       105670 :           bitmap_iterator bi;
     937              : 
     938       105670 :           bitmap_set_bit (scc, n);
     939              : 
     940       105670 :           while (si->scc_stack.length () != 0
     941       244881 :                  && si->dfs[si->scc_stack.last ()] >= my_dfs)
     942              :             {
     943       139211 :               unsigned int w = si->scc_stack.pop ();
     944              : 
     945       139211 :               bitmap_set_bit (scc, w);
     946              :             }
     947              : 
     948       105670 :           lowest_node = bitmap_first_set_bit (scc);
     949       105670 :           gcc_assert (lowest_node < FIRST_REF_NODE);
     950              : 
     951              :           /* Collapse the SCC nodes into a single node, and mark the
     952              :              indirect cycles.  */
     953       350551 :           EXECUTE_IF_SET_IN_BITMAP (scc, 0, i, bi)
     954              :             {
     955       244881 :               if (i < FIRST_REF_NODE)
     956              :                 {
     957       124525 :                   if (unite (lowest_node, i))
     958        18855 :                     unify_nodes (graph, lowest_node, i, false);
     959              :                 }
     960              :               else
     961              :                 {
     962       120356 :                   unite (lowest_node, i);
     963       240712 :                   graph->indirect_cycles[i - FIRST_REF_NODE] = lowest_node;
     964              :                 }
     965              :             }
     966       105670 :           bitmap_set_bit (si->deleted, lowest_node);
     967              :         }
     968              :       else
     969    376932349 :         bitmap_set_bit (si->deleted, n);
     970              :     }
     971              :   else
     972       139211 :     si->scc_stack.safe_push (n);
     973    377177230 : }
     974              : 
     975              : /* Unify node FROM into node TO, updating the changed count if
     976              :    necessary when UPDATE_CHANGED is true.  */
     977              : 
     978              : static void
     979     69547016 : unify_nodes (constraint_graph_t graph, unsigned int to, unsigned int from,
     980              :              bool update_changed)
     981              : {
     982     69547016 :   gcc_checking_assert (to != from && find (to) == to);
     983              : 
     984     69547016 :   if (dump_file && (dump_flags & TDF_DETAILS))
     985         1228 :     fprintf (dump_file, "Unifying %s to %s\n",
     986         1228 :              get_varinfo (from)->name,
     987         1228 :              get_varinfo (to)->name);
     988              : 
     989     69547016 :   if (update_changed)
     990       343630 :     stats.unified_vars_dynamic++;
     991              :   else
     992     69203386 :     stats.unified_vars_static++;
     993              : 
     994     69547016 :   merge_graph_nodes (graph, to, from);
     995     69547016 :   if (merge_node_constraints (graph, to, from))
     996              :     {
     997        90229 :       if (update_changed)
     998        10955 :         bitmap_set_bit (changed, to);
     999              :     }
    1000              : 
    1001              :   /* Mark TO as changed if FROM was changed.  If TO was already marked
    1002              :      as changed, decrease the changed count.  */
    1003              : 
    1004     69467742 :   if (update_changed
    1005     69467742 :       && bitmap_clear_bit (changed, from))
    1006        36522 :     bitmap_set_bit (changed, to);
    1007     69547016 :   varinfo_t fromvi = get_varinfo (from);
    1008     69547016 :   if (fromvi->solution)
    1009              :     {
    1010              :       /* If the solution changes because of the merging, we need to mark
    1011              :          the variable as changed.  */
    1012     69547016 :       varinfo_t tovi = get_varinfo (to);
    1013     69547016 :       if (bitmap_ior_into (tovi->solution, fromvi->solution))
    1014              :         {
    1015      1911016 :           if (update_changed)
    1016        68195 :             bitmap_set_bit (changed, to);
    1017              :         }
    1018              : 
    1019     69547016 :       BITMAP_FREE (fromvi->solution);
    1020     69547016 :       if (fromvi->oldsolution)
    1021       217721 :         BITMAP_FREE (fromvi->oldsolution);
    1022              : 
    1023     69547016 :       if (stats.iterations > 0
    1024       343630 :           && tovi->oldsolution)
    1025        18259 :         BITMAP_FREE (tovi->oldsolution);
    1026              :     }
    1027     69547016 :   if (graph->succs[to])
    1028      2602438 :     bitmap_clear_bit (graph->succs[to], to);
    1029     69547016 : }
    1030              : 
    1031              : /* Add a copy edge FROM -> TO, optimizing special cases.  Returns TRUE
    1032              :    if the solution of TO changed.  */
    1033              : 
    1034              : static bool
    1035    424386731 : solve_add_graph_edge (constraint_graph_t graph, unsigned int to,
    1036              :                       unsigned int from)
    1037              : {
    1038              :   /* Adding edges from the special vars is pointless.
    1039              :      They don't have sets that can change.  */
    1040    424386731 :   if (get_varinfo (from)->is_special_var)
    1041     30062143 :     return bitmap_ior_into (get_varinfo (to)->solution,
    1042     60124286 :                             get_varinfo (from)->solution);
    1043              :   /* Merging the solution from ESCAPED needlessly increases
    1044              :      the set.  Use ESCAPED as representative instead.  */
    1045    394324588 :   else if (from == find (escaped_id))
    1046     34953743 :     return bitmap_set_bit (get_varinfo (to)->solution, escaped_id);
    1047    359370845 :   else if (get_varinfo (from)->may_have_pointers
    1048    359370845 :            && add_graph_edge (graph, to, from))
    1049    116997558 :     return bitmap_ior_into (get_varinfo (to)->solution,
    1050    116997558 :                             get_varinfo (from)->solution);
    1051              :   return false;
    1052              : }
    1053              : 
    1054              : /* Process a constraint C that represents x = *(y + off), using DELTA as the
    1055              :    starting solution for y.  */
    1056              : 
    1057              : static void
    1058     68735019 : do_sd_constraint (constraint_graph_t graph, constraint_t c,
    1059              :                   bitmap delta, bitmap *expanded_delta)
    1060              : {
    1061     68735019 :   unsigned int lhs = c->lhs.var;
    1062     68735019 :   bool flag = false;
    1063     68735019 :   bitmap sol = get_varinfo (lhs)->solution;
    1064     68735019 :   unsigned int j;
    1065     68735019 :   bitmap_iterator bi;
    1066     68735019 :   HOST_WIDE_INT roffset = c->rhs.offset;
    1067              : 
    1068              :   /* Our IL does not allow this.  */
    1069     68735019 :   gcc_checking_assert (c->lhs.offset == 0);
    1070              : 
    1071              :   /* If the solution of Y contains anything it is good enough to transfer
    1072              :      this to the LHS.  */
    1073     68735019 :   if (bitmap_bit_p (delta, anything_id))
    1074              :     {
    1075       573642 :       flag |= bitmap_set_bit (sol, anything_id);
    1076       573642 :       goto done;
    1077              :     }
    1078              : 
    1079              :   /* If we do not know at with offset the rhs is dereferenced compute
    1080              :      the reachability set of DELTA, conservatively assuming it is
    1081              :      dereferenced at all valid offsets.  */
    1082     68161377 :   if (roffset == UNKNOWN_OFFSET)
    1083              :     {
    1084     50466408 :       delta = solution_set_expand (delta, expanded_delta);
    1085              :       /* No further offset processing is necessary.  */
    1086     50466408 :       roffset = 0;
    1087              :     }
    1088              : 
    1089              :   /* For each variable j in delta (Sol(y)), add
    1090              :      an edge in the graph from j to x, and union Sol(j) into Sol(x).  */
    1091    310121455 :   EXECUTE_IF_SET_IN_BITMAP (delta, 0, j, bi)
    1092              :     {
    1093    241960078 :       varinfo_t v = get_varinfo (j);
    1094    241960078 :       HOST_WIDE_INT fieldoffset = v->offset + roffset;
    1095    241960078 :       unsigned HOST_WIDE_INT size = v->size;
    1096    241960078 :       unsigned int t;
    1097              : 
    1098    241960078 :       if (v->is_full_var)
    1099              :         ;
    1100    145225065 :       else if (roffset != 0)
    1101              :         {
    1102      5791932 :           if (fieldoffset < 0)
    1103       136104 :             v = get_varinfo (v->head);
    1104              :           else
    1105      5655828 :             v = first_or_preceding_vi_for_offset (v, fieldoffset);
    1106              :         }
    1107              : 
    1108              :       /* We have to include all fields that overlap the current field
    1109              :          shifted by roffset.  */
    1110    243918853 :       do
    1111              :         {
    1112    243918853 :           t = find (v->id);
    1113              : 
    1114    243918853 :           flag |= solve_add_graph_edge (graph, lhs, t);
    1115              : 
    1116    243918853 :           if (v->is_full_var
    1117    147183648 :               || v->next == 0)
    1118              :             break;
    1119              : 
    1120    120214920 :           v = vi_next (v);
    1121              :         }
    1122    120214920 :       while (v->offset < fieldoffset + size);
    1123              :     }
    1124              : 
    1125     68161377 : done:
    1126              :   /* If the LHS solution changed, mark the var as changed.  */
    1127     68735019 :   if (flag)
    1128     27603431 :     bitmap_set_bit (changed, lhs);
    1129     68735019 : }
    1130              : 
    1131              : /* Process a constraint C that represents *(x + off) = y using DELTA
    1132              :    as the starting solution for x.  */
    1133              : 
    1134              : static void
    1135     55523753 : do_ds_constraint (constraint_t c, bitmap delta, bitmap *expanded_delta)
    1136              : {
    1137     55523753 :   unsigned int rhs = c->rhs.var;
    1138     55523753 :   bitmap sol = get_varinfo (rhs)->solution;
    1139     55523753 :   unsigned int j;
    1140     55523753 :   bitmap_iterator bi;
    1141     55523753 :   HOST_WIDE_INT loff = c->lhs.offset;
    1142     55523753 :   bool escaped_p = false;
    1143              : 
    1144              :   /* Our IL does not allow this.  */
    1145     55523753 :   gcc_checking_assert (c->rhs.offset == 0);
    1146              : 
    1147              :   /* If the solution of y contains ANYTHING simply use the ANYTHING
    1148              :      solution.  This avoids needlessly increasing the points-to sets.  */
    1149     55523753 :   if (bitmap_bit_p (sol, anything_id))
    1150       412012 :     sol = get_varinfo (find (anything_id))->solution;
    1151              : 
    1152              :   /* If the solution for x contains ANYTHING we have to merge the
    1153              :      solution of y into all pointer variables which we do via
    1154              :      STOREDANYTHING.  */
    1155     55523753 :   if (bitmap_bit_p (delta, anything_id))
    1156              :     {
    1157       448545 :       unsigned t = find (storedanything_id);
    1158       448545 :       if (solve_add_graph_edge (graph, t, rhs))
    1159        36255 :         bitmap_set_bit (changed, t);
    1160       448545 :       return;
    1161              :     }
    1162              : 
    1163              :   /* If we do not know at with offset the rhs is dereferenced compute
    1164              :      the reachability set of DELTA, conservatively assuming it is
    1165              :      dereferenced at all valid offsets.  */
    1166     55075208 :   if (loff == UNKNOWN_OFFSET)
    1167              :     {
    1168      2076171 :       delta = solution_set_expand (delta, expanded_delta);
    1169      2076171 :       loff = 0;
    1170              :     }
    1171              : 
    1172              :   /* For each member j of delta (Sol(x)), add an edge from y to j and
    1173              :      union Sol(y) into Sol(j) */
    1174    270821342 :   EXECUTE_IF_SET_IN_BITMAP (delta, 0, j, bi)
    1175              :     {
    1176    215746134 :       varinfo_t v = get_varinfo (j);
    1177    215746134 :       unsigned int t;
    1178    215746134 :       HOST_WIDE_INT fieldoffset = v->offset + loff;
    1179    215746134 :       unsigned HOST_WIDE_INT size = v->size;
    1180              : 
    1181    215746134 :       if (v->is_full_var)
    1182              :         ;
    1183    132457581 :       else if (loff != 0)
    1184              :         {
    1185      8153148 :           if (fieldoffset < 0)
    1186         4748 :             v = get_varinfo (v->head);
    1187              :           else
    1188      8148400 :             v = first_or_preceding_vi_for_offset (v, fieldoffset);
    1189              :         }
    1190              : 
    1191              :       /* We have to include all fields that overlap the current field
    1192              :          shifted by loff.  */
    1193    218193284 :       do
    1194              :         {
    1195    218193284 :           if (v->may_have_pointers)
    1196              :             {
    1197              :               /* If v is a global variable then this is an escape point.  */
    1198    205879561 :               if (v->is_global_var
    1199    154585437 :                   && !escaped_p)
    1200              :                 {
    1201     44063540 :                   t = find (escaped_id);
    1202     44063540 :                   if (add_graph_edge (graph, t, rhs)
    1203     57553205 :                       && bitmap_ior_into (get_varinfo (t)->solution, sol))
    1204      1346766 :                     bitmap_set_bit (changed, t);
    1205              :                   /* Enough to let rhs escape once.  */
    1206              :                   escaped_p = true;
    1207              :                 }
    1208              : 
    1209    205879561 :               if (v->is_special_var)
    1210              :                 break;
    1211              : 
    1212    180019333 :               t = find (v->id);
    1213              : 
    1214    180019333 :               if (solve_add_graph_edge (graph, t, rhs))
    1215     12263819 :                 bitmap_set_bit (changed, t);
    1216              :             }
    1217              : 
    1218    192333056 :           if (v->is_full_var
    1219    134904589 :               || v->next == 0)
    1220              :             break;
    1221              : 
    1222    110354728 :           v = vi_next (v);
    1223              :         }
    1224    110354728 :       while (v->offset < fieldoffset + size);
    1225              :     }
    1226              : }
    1227              : 
    1228              : /* Handle a non-simple (simple meaning requires no iteration),
    1229              :    constraint (IE *x = &y, x = *y, *x = y, and x = y with offsets involved).  */
    1230              : 
    1231              : static void
    1232    208255160 : do_complex_constraint (constraint_graph_t graph, constraint_t c, bitmap delta,
    1233              :                        bitmap *expanded_delta)
    1234              : {
    1235    208255160 :   if (c->lhs.type == DEREF)
    1236              :     {
    1237     55523753 :       if (c->rhs.type == ADDRESSOF)
    1238              :         {
    1239            0 :           gcc_unreachable ();
    1240              :         }
    1241              :       else
    1242              :         {
    1243              :           /* *x = y */
    1244     55523753 :           do_ds_constraint (c, delta, expanded_delta);
    1245              :         }
    1246              :     }
    1247    152731407 :   else if (c->rhs.type == DEREF)
    1248              :     {
    1249              :       /* x = *y */
    1250     68735019 :       if (!(get_varinfo (c->lhs.var)->is_special_var))
    1251     68735019 :         do_sd_constraint (graph, c, delta, expanded_delta);
    1252              :     }
    1253              :   else
    1254              :     {
    1255     83996388 :       bitmap tmp;
    1256     83996388 :       bool flag = false;
    1257              : 
    1258     83996388 :       gcc_checking_assert (c->rhs.type == SCALAR && c->lhs.type == SCALAR
    1259              :                            && c->rhs.offset != 0 && c->lhs.offset == 0);
    1260     83996388 :       tmp = get_varinfo (c->lhs.var)->solution;
    1261              : 
    1262     83996388 :       flag = set_union_with_increment (tmp, delta, c->rhs.offset,
    1263              :                                        expanded_delta);
    1264              : 
    1265     83996388 :       if (flag)
    1266     20839300 :         bitmap_set_bit (changed, c->lhs.var);
    1267              :     }
    1268    208255160 : }
    1269              : 
    1270              : /* Initialize and return a new SCC info structure.  */
    1271              : 
    1272      8831832 : scc_info::scc_info (size_t size) :
    1273      8831832 :   visited (size), deleted (size), current_index (0), scc_stack (1)
    1274              : {
    1275      8831832 :   bitmap_clear (visited);
    1276      8831832 :   bitmap_clear (deleted);
    1277      8831832 :   node_mapping = XNEWVEC (unsigned int, size);
    1278      8831832 :   dfs = XCNEWVEC (unsigned int, size);
    1279              : 
    1280    908752696 :   for (size_t i = 0; i < size; i++)
    1281    899920864 :     node_mapping[i] = i;
    1282      8831832 : }
    1283              : 
    1284              : /* Free an SCC info structure pointed to by SI.  */
    1285              : 
    1286      8831832 : scc_info::~scc_info ()
    1287              : {
    1288      8831832 :   free (node_mapping);
    1289      8831832 :   free (dfs);
    1290      8831832 : }
    1291              : 
    1292              : 
    1293              : /* Find indirect cycles in GRAPH that occur, using strongly connected
    1294              :    components, and note them in the indirect cycles map.
    1295              : 
    1296              :    This technique comes from Ben Hardekopf and Calvin Lin,
    1297              :    "It Pays to be Lazy: Fast and Accurate Pointer Analysis for Millions of
    1298              :    Lines of Code", submitted to PLDI 2007.  */
    1299              : 
    1300              : static void
    1301      4415916 : find_indirect_cycles (constraint_graph_t graph)
    1302              : {
    1303      4415916 :   unsigned int i;
    1304      4415916 :   unsigned int size = graph->size;
    1305      4415916 :   scc_info si (size);
    1306              : 
    1307    904336780 :   for (i = 0; i < MIN (LAST_REF_NODE, size); i++)
    1308    445544516 :     if (!bitmap_bit_p (si.visited, i) && find (i) == i)
    1309    228332130 :       scc_visit (graph, &si, i);
    1310      4415916 : }
    1311              : 
    1312              : /* Visit the graph in topological order starting at node N, and store the
    1313              :    order in TOPO_ORDER using VISITED to indicate visited nodes.  */
    1314              : 
    1315              : static void
    1316    383169402 : topo_visit (constraint_graph_t graph, vec<unsigned> &topo_order,
    1317              :             sbitmap visited, unsigned int n)
    1318              : {
    1319    383169402 :   bitmap_iterator bi;
    1320    383169402 :   unsigned int j;
    1321              : 
    1322    383169402 :   bitmap_set_bit (visited, n);
    1323              : 
    1324    383169402 :   if (graph->succs[n])
    1325    929950707 :     EXECUTE_IF_SET_IN_BITMAP (graph->succs[n], 0, j, bi)
    1326              :       {
    1327    733824270 :         unsigned k = find (j);
    1328    733824270 :         if (!bitmap_bit_p (visited, k))
    1329    279701074 :           topo_visit (graph, topo_order, visited, k);
    1330              :       }
    1331              : 
    1332              :   /* Also consider copy with offset complex constraints as implicit edges.  */
    1333    818912775 :   for (auto c : graph->complex[n])
    1334              :     {
    1335              :       /* Constraints are ordered so that SCALAR = SCALAR appear first.  */
    1336    253047831 :       if (c->lhs.type != SCALAR || c->rhs.type != SCALAR)
    1337              :         break;
    1338    140942567 :       gcc_checking_assert (c->rhs.var == n);
    1339    140942567 :       unsigned k = find (c->lhs.var);
    1340    140942567 :       if (!bitmap_bit_p (visited, k))
    1341     36509726 :         topo_visit (graph, topo_order, visited, k);
    1342              :     }
    1343              : 
    1344    383169402 :   topo_order.quick_push (n);
    1345    383169402 : }
    1346              : 
    1347              : /* Compute a topological ordering for GRAPH, and return the result.  */
    1348              : 
    1349              : static auto_vec<unsigned>
    1350      7833434 : compute_topo_order (constraint_graph_t graph)
    1351              : {
    1352      7833434 :   unsigned int i;
    1353      7833434 :   unsigned int size = graph->size;
    1354              : 
    1355      7833434 :   auto_sbitmap visited (size);
    1356      7833434 :   bitmap_clear (visited);
    1357              : 
    1358              :   /* For the heuristic in add_graph_edge to work optimally make sure to
    1359              :      first visit the connected component of the graph containing
    1360              :      ESCAPED.  Do this by extracting the connected component
    1361              :      with ESCAPED and append that to all other components as solve_graph
    1362              :      pops from the order.  */
    1363      7833434 :   auto_vec<unsigned> tail (size);
    1364      7833434 :   topo_visit (graph, tail, visited, find (escaped_id));
    1365              : 
    1366      7833434 :   auto_vec<unsigned> topo_order (size);
    1367              : 
    1368    581636155 :   for (i = 0; i != size; ++i)
    1369    565969287 :     if (!bitmap_bit_p (visited, i) && find (i) == i)
    1370     59125168 :       topo_visit (graph, topo_order, visited, i);
    1371              : 
    1372      7833434 :   topo_order.splice (tail);
    1373      7833434 :   return topo_order;
    1374      7833434 : }
    1375              : 
    1376              : /* Structure used to for hash value numbering of pointer equivalence
    1377              :    classes.  */
    1378              : 
    1379              : typedef struct equiv_class_label
    1380              : {
    1381              :   hashval_t hashcode;
    1382              :   unsigned int equivalence_class;
    1383              :   bitmap labels;
    1384              : } *equiv_class_label_t;
    1385              : typedef const struct equiv_class_label *const_equiv_class_label_t;
    1386              : 
    1387              : /* Equiv_class_label hashtable helpers.  */
    1388              : 
    1389              : struct equiv_class_hasher : nofree_ptr_hash <equiv_class_label>
    1390              : {
    1391              :   static inline hashval_t hash (const equiv_class_label *);
    1392              :   static inline bool equal (const equiv_class_label *,
    1393              :                             const equiv_class_label *);
    1394              : };
    1395              : 
    1396              : /* A hashtable for mapping a bitmap of labels->pointer equivalence
    1397              :    classes.  */
    1398              : static hash_table<equiv_class_hasher> *pointer_equiv_class_table;
    1399              : 
    1400              : /* A hashtable for mapping a bitmap of labels->location equivalence
    1401              :    classes.  */
    1402              : static hash_table<equiv_class_hasher> *location_equiv_class_table;
    1403              : 
    1404              : /* Hash function for a equiv_class_label_t.  */
    1405              : 
    1406              : inline hashval_t
    1407    186271176 : equiv_class_hasher::hash (const equiv_class_label *ecl)
    1408              : {
    1409    186271176 :   return ecl->hashcode;
    1410              : }
    1411              : 
    1412              : /* Equality function for two equiv_class_label_t's.  */
    1413              : 
    1414              : inline bool
    1415    241531248 : equiv_class_hasher::equal (const equiv_class_label *eql1,
    1416              :                            const equiv_class_label *eql2)
    1417              : {
    1418    241531248 :   return (eql1->hashcode == eql2->hashcode
    1419    241531248 :           && bitmap_equal_p (eql1->labels, eql2->labels));
    1420              : }
    1421              : 
    1422              : struct obstack equiv_class_obstack;
    1423              : 
    1424              : /* Lookup a equivalence class in TABLE by the bitmap of LABELS with
    1425              :    hash HAS it contains.  Sets *REF_LABELS to the bitmap LABELS
    1426              :    is equivalent to.  */
    1427              : 
    1428              : static equiv_class_label *
    1429    192366361 : equiv_class_lookup_or_add (hash_table<equiv_class_hasher> *table,
    1430              :                            bitmap labels)
    1431              : {
    1432    192366361 :   equiv_class_label **slot;
    1433    192366361 :   equiv_class_label ecl;
    1434              : 
    1435    192366361 :   ecl.labels = labels;
    1436    192366361 :   ecl.hashcode = bitmap_hash (labels);
    1437    192366361 :   slot = table->find_slot (&ecl, INSERT);
    1438    192366361 :   if (!*slot)
    1439              :     {
    1440    160909877 :       *slot = XOBNEW (&equiv_class_obstack, struct equiv_class_label);
    1441    160909877 :       (*slot)->labels = labels;
    1442    160909877 :       (*slot)->hashcode = ecl.hashcode;
    1443    160909877 :       (*slot)->equivalence_class = 0;
    1444              :     }
    1445              : 
    1446    192366361 :   return *slot;
    1447              : }
    1448              : 
    1449              : 
    1450              : /* Perform offline variable substitution.
    1451              : 
    1452              :    This is a worst case quadratic time way of identifying variables
    1453              :    that must have equivalent points-to sets, including those caused by
    1454              :    static cycles, and single entry subgraphs, in the constraint graph.
    1455              : 
    1456              :    The technique is described in "Exploiting Pointer and Location
    1457              :    Equivalence to Optimize Pointer Analysis.  In the 14th International
    1458              :    Static Analysis Symposium (SAS), August 2007."  It is known as the
    1459              :    "HU" algorithm, and is equivalent to value numbering the collapsed
    1460              :    constraint graph including evaluating unions.
    1461              : 
    1462              :    The general method of finding equivalence classes is as follows:
    1463              :    Add fake nodes (REF nodes) and edges for *a = b and a = *b constraints.
    1464              :    Initialize all non-REF nodes to be direct nodes.
    1465              :    For each constraint a = a U {b}, we set pts(a) = pts(a) u {fresh
    1466              :    variable}
    1467              :    For each constraint containing the dereference, we also do the same
    1468              :    thing.
    1469              : 
    1470              :    We then compute SCC's in the graph and unify nodes in the same SCC,
    1471              :    including pts sets.
    1472              : 
    1473              :    For each non-collapsed node x:
    1474              :     Visit all unvisited explicit incoming edges.
    1475              :     Ignoring all non-pointers, set pts(x) = Union of pts(a) for y
    1476              :     where y->x.
    1477              :     Lookup the equivalence class for pts(x).
    1478              :      If we found one, equivalence_class(x) = found class.
    1479              :      Otherwise, equivalence_class(x) = new class, and new_class is
    1480              :     added to the lookup table.
    1481              : 
    1482              :    All direct nodes with the same equivalence class can be replaced
    1483              :    with a single representative node.
    1484              :    All unlabeled nodes (label == 0) are not pointers and all edges
    1485              :    involving them can be eliminated.
    1486              :    We perform these optimizations during rewrite_constraints
    1487              : 
    1488              :    In addition to pointer equivalence class finding, we also perform
    1489              :    location equivalence class finding.  This is the set of variables
    1490              :    that always appear together in points-to sets.  We use this to
    1491              :    compress the size of the points-to sets.  */
    1492              : 
    1493              : /* Current maximum pointer equivalence class id.  */
    1494              : static int pointer_equiv_class;
    1495              : 
    1496              : /* Current maximum location equivalence class id.  */
    1497              : static int location_equiv_class;
    1498              : 
    1499              : /* Recursive routine to find strongly connected components in GRAPH,
    1500              :    and label it's nodes with DFS numbers.  */
    1501              : 
    1502              : static void
    1503    263168521 : condense_visit (constraint_graph_t graph, class scc_info *si, unsigned int n)
    1504              : {
    1505    263168521 :   unsigned int i;
    1506    263168521 :   bitmap_iterator bi;
    1507    263168521 :   unsigned int my_dfs;
    1508              : 
    1509    263168521 :   gcc_checking_assert (si->node_mapping[n] == n);
    1510    263168521 :   bitmap_set_bit (si->visited, n);
    1511    263168521 :   si->dfs[n] = si->current_index ++;
    1512    263168521 :   my_dfs = si->dfs[n];
    1513              : 
    1514              :   /* Visit all the successors.  */
    1515    483320093 :   EXECUTE_IF_IN_NONNULL_BITMAP (graph->preds[n], 0, i, bi)
    1516              :     {
    1517    220151572 :       unsigned int w = si->node_mapping[i];
    1518              : 
    1519    220151572 :       if (bitmap_bit_p (si->deleted, w))
    1520    139727579 :         continue;
    1521              : 
    1522     80423993 :       if (!bitmap_bit_p (si->visited, w))
    1523     78963144 :         condense_visit (graph, si, w);
    1524              : 
    1525     80423993 :       unsigned int t = si->node_mapping[w];
    1526     80423993 :       gcc_checking_assert (si->node_mapping[n] == n);
    1527     80423993 :       if (si->dfs[t] < si->dfs[n])
    1528      2613679 :         si->dfs[n] = si->dfs[t];
    1529              :     }
    1530              : 
    1531              :   /* Visit all the implicit predecessors.  */
    1532    321016656 :   EXECUTE_IF_IN_NONNULL_BITMAP (graph->implicit_preds[n], 0, i, bi)
    1533              :     {
    1534     57848135 :       unsigned int w = si->node_mapping[i];
    1535              : 
    1536     57848135 :       if (bitmap_bit_p (si->deleted, w))
    1537     19166626 :         continue;
    1538              : 
    1539     38681509 :       if (!bitmap_bit_p (si->visited, w))
    1540     33883281 :         condense_visit (graph, si, w);
    1541              : 
    1542     38681509 :       unsigned int t = si->node_mapping[w];
    1543     38681509 :       gcc_assert (si->node_mapping[n] == n);
    1544     38681509 :       if (si->dfs[t] < si->dfs[n])
    1545      8185787 :         si->dfs[n] = si->dfs[t];
    1546              :     }
    1547              : 
    1548              :   /* See if any components have been identified.  */
    1549    263168521 :   if (si->dfs[n] == my_dfs)
    1550              :     {
    1551    252538004 :       if (si->scc_stack.length () != 0
    1552    252538004 :           && si->dfs[si->scc_stack.last ()] >= my_dfs)
    1553              :         {
    1554              :           /* Find the first node of the SCC and do non-bitmap work.  */
    1555              :           bool direct_p = true;
    1556              :           unsigned first = si->scc_stack.length ();
    1557     10630517 :           do
    1558              :             {
    1559     10630517 :               --first;
    1560     10630517 :               unsigned int w = si->scc_stack[first];
    1561     10630517 :               si->node_mapping[w] = n;
    1562     10630517 :               if (!bitmap_bit_p (graph->direct_nodes, w))
    1563      8540948 :                 direct_p = false;
    1564              :             }
    1565              :           while (first > 0
    1566     11972208 :                  && si->dfs[si->scc_stack[first - 1]] >= my_dfs);
    1567      1341691 :           if (!direct_p)
    1568       852181 :             bitmap_clear_bit (graph->direct_nodes, n);
    1569              : 
    1570              :           /* Want to reduce to node n, push that first.  */
    1571      1341691 :           si->scc_stack.reserve (1);
    1572      1341691 :           si->scc_stack.quick_push (si->scc_stack[first]);
    1573      1341691 :           si->scc_stack[first] = n;
    1574              : 
    1575      1341691 :           unsigned scc_size = si->scc_stack.length () - first;
    1576      1341691 :           unsigned split = scc_size / 2;
    1577      1341691 :           unsigned carry = scc_size - split * 2;
    1578      4702195 :           while (split > 0)
    1579              :             {
    1580     13991021 :               for (unsigned i = 0; i < split; ++i)
    1581              :                 {
    1582     10630517 :                   unsigned a = si->scc_stack[first + i];
    1583     10630517 :                   unsigned b = si->scc_stack[first + split + carry + i];
    1584              : 
    1585              :                   /* Unify our nodes.  */
    1586     10630517 :                   if (graph->preds[b])
    1587              :                     {
    1588      4663679 :                       if (!graph->preds[a])
    1589       957743 :                         std::swap (graph->preds[a], graph->preds[b]);
    1590              :                       else
    1591      3705936 :                         bitmap_ior_into_and_free (graph->preds[a],
    1592              :                                                   &graph->preds[b]);
    1593              :                     }
    1594     10630517 :                   if (graph->implicit_preds[b])
    1595              :                     {
    1596      8443698 :                       if (!graph->implicit_preds[a])
    1597       865735 :                         std::swap (graph->implicit_preds[a],
    1598              :                                    graph->implicit_preds[b]);
    1599              :                       else
    1600      7577963 :                         bitmap_ior_into_and_free (graph->implicit_preds[a],
    1601              :                                                   &graph->implicit_preds[b]);
    1602              :                     }
    1603     10630517 :                   if (graph->points_to[b])
    1604              :                     {
    1605       522389 :                       if (!graph->points_to[a])
    1606       230416 :                         std::swap (graph->points_to[a], graph->points_to[b]);
    1607              :                       else
    1608       291973 :                         bitmap_ior_into_and_free (graph->points_to[a],
    1609              :                                                   &graph->points_to[b]);
    1610              :                     }
    1611              :                 }
    1612      3360504 :               unsigned remain = split + carry;
    1613      3360504 :               split = remain / 2;
    1614      3360504 :               carry = remain - split * 2;
    1615              :             }
    1616              :           /* Actually pop the SCC.  */
    1617      1341691 :           si->scc_stack.truncate (first);
    1618              :         }
    1619    252538004 :       bitmap_set_bit (si->deleted, n);
    1620              :     }
    1621              :   else
    1622     10630517 :     si->scc_stack.safe_push (n);
    1623    263168521 : }
    1624              : 
    1625              : /* Label pointer equivalences.
    1626              : 
    1627              :    This performs a value numbering of the constraint graph to
    1628              :    discover which variables will always have the same points-to sets
    1629              :    under the current set of constraints.
    1630              : 
    1631              :    The way it value numbers is to store the set of points-to bits
    1632              :    generated by the constraints and graph edges.  This is just used as a
    1633              :    hash and equality comparison.  The *actual set of points-to bits* is
    1634              :    completely irrelevant, in that we don't care about being able to
    1635              :    extract them later.
    1636              : 
    1637              :    The equality values (currently bitmaps) just have to satisfy a few
    1638              :    constraints, the main ones being:
    1639              :    1. The combining operation must be order independent.
    1640              :    2. The end result of a given set of operations must be unique iff the
    1641              :       combination of input values is unique
    1642              :    3. Hashable.  */
    1643              : 
    1644              : static void
    1645    229646256 : label_visit (constraint_graph_t graph, class scc_info *si, unsigned int n)
    1646              : {
    1647    229646256 :   unsigned int i, first_pred;
    1648    229646256 :   bitmap_iterator bi;
    1649              : 
    1650    229646256 :   bitmap_set_bit (si->visited, n);
    1651              : 
    1652              :   /* Label and union our incoming edges's points to sets.  */
    1653    229646256 :   first_pred = -1U;
    1654    444595695 :   EXECUTE_IF_IN_NONNULL_BITMAP (graph->preds[n], 0, i, bi)
    1655              :     {
    1656    214949439 :       unsigned int w = si->node_mapping[i];
    1657    214949439 :       if (!bitmap_bit_p (si->visited, w))
    1658     74345358 :         label_visit (graph, si, w);
    1659              : 
    1660              :       /* Skip unused edges.  */
    1661    214949439 :       if (w == n || graph->pointer_label[w] == 0)
    1662      5144884 :         continue;
    1663              : 
    1664    209804555 :       if (graph->points_to[w])
    1665              :         {
    1666    209804555 :           if (!graph->points_to[n])
    1667              :             {
    1668    146043211 :               if (first_pred == -1U)
    1669              :                 first_pred = w;
    1670              :               else
    1671              :                 {
    1672     40545411 :                   graph->points_to[n] = BITMAP_ALLOC (&predbitmap_obstack);
    1673     40545411 :                   bitmap_ior (graph->points_to[n],
    1674     40545411 :                               graph->points_to[first_pred],
    1675     40545411 :                               graph->points_to[w]);
    1676              :                 }
    1677              :             }
    1678              :           else
    1679     63761344 :             bitmap_ior_into (graph->points_to[n], graph->points_to[w]);
    1680              :         }
    1681              :     }
    1682              : 
    1683              :   /* Indirect nodes get fresh variables and a new pointer equiv class.  */
    1684    229646256 :   if (!bitmap_bit_p (graph->direct_nodes, n))
    1685              :     {
    1686    111318330 :       if (!graph->points_to[n])
    1687              :         {
    1688     64261631 :           graph->points_to[n] = BITMAP_ALLOC (&predbitmap_obstack);
    1689     64261631 :           if (first_pred != -1U)
    1690     25955362 :             bitmap_copy (graph->points_to[n], graph->points_to[first_pred]);
    1691              :         }
    1692    222636660 :       bitmap_set_bit (graph->points_to[n], FIRST_REF_NODE + n);
    1693    111318330 :       graph->pointer_label[n] = pointer_equiv_class++;
    1694    111318330 :       equiv_class_label_t ecl;
    1695    222636660 :       ecl = equiv_class_lookup_or_add (pointer_equiv_class_table,
    1696    111318330 :                                        graph->points_to[n]);
    1697    111318330 :       ecl->equivalence_class = graph->pointer_label[n];
    1698    170037323 :       return;
    1699              :     }
    1700              : 
    1701              :   /* If there was only a single non-empty predecessor the pointer equiv
    1702              :      class is the same.  */
    1703    118327926 :   if (!graph->points_to[n])
    1704              :     {
    1705     58718993 :       if (first_pred != -1U)
    1706              :         {
    1707     38997027 :           graph->pointer_label[n] = graph->pointer_label[first_pred];
    1708     38997027 :           graph->points_to[n] = graph->points_to[first_pred];
    1709              :         }
    1710     58718993 :       return;
    1711              :     }
    1712              : 
    1713     59608933 :   if (!bitmap_empty_p (graph->points_to[n]))
    1714              :     {
    1715     59608933 :       equiv_class_label_t ecl;
    1716     59608933 :       ecl = equiv_class_lookup_or_add (pointer_equiv_class_table,
    1717              :                                        graph->points_to[n]);
    1718     59608933 :       if (ecl->equivalence_class == 0)
    1719     28592696 :         ecl->equivalence_class = pointer_equiv_class++;
    1720              :       else
    1721              :         {
    1722     31016237 :           BITMAP_FREE (graph->points_to[n]);
    1723     31016237 :           graph->points_to[n] = ecl->labels;
    1724              :         }
    1725     59608933 :       graph->pointer_label[n] = ecl->equivalence_class;
    1726              :     }
    1727              : }
    1728              : 
    1729              : /* Print the pred graph in dot format.  */
    1730              : 
    1731              : static void
    1732            3 : dump_pred_graph (class scc_info *si, FILE *file)
    1733              : {
    1734            3 :   unsigned int i;
    1735              : 
    1736              :   /* Only print the graph if it has already been initialized:  */
    1737            3 :   if (!graph)
    1738              :     return;
    1739              : 
    1740              :   /* Prints the header of the dot file:  */
    1741            3 :   fprintf (file, "strict digraph {\n");
    1742            3 :   fprintf (file, "  node [\n    shape = box\n  ]\n");
    1743            3 :   fprintf (file, "  edge [\n    fontsize = \"12\"\n  ]\n");
    1744            3 :   fprintf (file, "\n  // List of nodes and complex constraints in "
    1745              :            "the constraint graph:\n");
    1746              : 
    1747              :   /* The next lines print the nodes in the graph together with the
    1748              :      complex constraints attached to them.  */
    1749           80 :   for (i = 1; i < graph->size; i++)
    1750              :     {
    1751          154 :       if (i == FIRST_REF_NODE)
    1752            3 :         continue;
    1753           74 :       if (si->node_mapping[i] != i)
    1754            0 :         continue;
    1755           74 :       if (i < FIRST_REF_NODE)
    1756           37 :         fprintf (file, "\"%s\"", get_varinfo (i)->name);
    1757              :       else
    1758           37 :         fprintf (file, "\"*%s\"", get_varinfo (i - FIRST_REF_NODE)->name);
    1759           74 :       if (graph->points_to[i]
    1760           74 :           && !bitmap_empty_p (graph->points_to[i]))
    1761              :         {
    1762           11 :           if (i < FIRST_REF_NODE)
    1763           11 :             fprintf (file, "[label=\"%s = {", get_varinfo (i)->name);
    1764              :           else
    1765            0 :             fprintf (file, "[label=\"*%s = {",
    1766            0 :                      get_varinfo (i - FIRST_REF_NODE)->name);
    1767           11 :           unsigned j;
    1768           11 :           bitmap_iterator bi;
    1769           25 :           EXECUTE_IF_SET_IN_BITMAP (graph->points_to[i], 0, j, bi)
    1770           14 :             fprintf (file, " %d", j);
    1771           11 :           fprintf (file, " }\"]");
    1772              :         }
    1773           74 :       fprintf (file, ";\n");
    1774              :     }
    1775              : 
    1776              :   /* Go over the edges.  */
    1777            3 :   fprintf (file, "\n  // Edges in the constraint graph:\n");
    1778           80 :   for (i = 1; i < graph->size; i++)
    1779              :     {
    1780           77 :       unsigned j;
    1781           77 :       bitmap_iterator bi;
    1782           77 :       if (si->node_mapping[i] != i)
    1783            0 :         continue;
    1784           92 :       EXECUTE_IF_IN_NONNULL_BITMAP (graph->preds[i], 0, j, bi)
    1785              :         {
    1786           15 :           unsigned from = si->node_mapping[j];
    1787           15 :           if (from < FIRST_REF_NODE)
    1788            7 :             fprintf (file, "\"%s\"", get_varinfo (from)->name);
    1789              :           else
    1790            8 :             fprintf (file, "\"*%s\"",
    1791            8 :                      get_varinfo (from - FIRST_REF_NODE)->name);
    1792           15 :           fprintf (file, " -> ");
    1793           15 :           if (i < FIRST_REF_NODE)
    1794           11 :             fprintf (file, "\"%s\"", get_varinfo (i)->name);
    1795              :           else
    1796            8 :             fprintf (file, "\"*%s\"", get_varinfo (i - FIRST_REF_NODE)->name);
    1797           15 :           fprintf (file, ";\n");
    1798              :         }
    1799              :     }
    1800              : 
    1801              :   /* Prints the tail of the dot file.  */
    1802            3 :   fprintf (file, "}\n");
    1803              : }
    1804              : 
    1805              : /* Perform offline variable substitution, discovering equivalence
    1806              :    classes, and eliminating non-pointer variables.  */
    1807              : 
    1808              : static class scc_info *
    1809      4415916 : perform_var_substitution (constraint_graph_t graph)
    1810              : {
    1811      4415916 :   unsigned int i;
    1812      4415916 :   unsigned int size = graph->size;
    1813      4415916 :   scc_info *si = new scc_info (size);
    1814              : 
    1815      4415916 :   bitmap_obstack_initialize (&iteration_obstack);
    1816      4415916 :   gcc_obstack_init (&equiv_class_obstack);
    1817      4415916 :   pointer_equiv_class_table = new hash_table<equiv_class_hasher> (511);
    1818      4415916 :   location_equiv_class_table
    1819      4415916 :     = new hash_table<equiv_class_hasher> (511);
    1820      4415916 :   pointer_equiv_class = 1;
    1821      4415916 :   location_equiv_class = 1;
    1822              : 
    1823              :   /* Condense the nodes, which means to find SCC's, count incoming
    1824              :      predecessors, and unite nodes in SCC's.  */
    1825    224980216 :   for (i = 1; i < FIRST_REF_NODE; i++)
    1826    220564300 :     if (!bitmap_bit_p (si->visited, si->node_mapping[i]))
    1827    150322096 :       condense_visit (graph, si, si->node_mapping[i]);
    1828              : 
    1829      4415916 :   if (dump_file && (dump_flags & TDF_GRAPH))
    1830              :     {
    1831            3 :       fprintf (dump_file, "\n\n// The constraint graph before var-substitution "
    1832              :                "in dot format:\n");
    1833            3 :       dump_pred_graph (si, dump_file);
    1834            3 :       fprintf (dump_file, "\n\n");
    1835              :     }
    1836              : 
    1837      4415916 :   bitmap_clear (si->visited);
    1838              :   /* Actually the label the nodes for pointer equivalences.  */
    1839    454376348 :   for (i = 1; i < FIRST_REF_NODE; i++)
    1840    220564300 :     if (!bitmap_bit_p (si->visited, si->node_mapping[i]))
    1841    155300898 :       label_visit (graph, si, si->node_mapping[i]);
    1842              : 
    1843              :   /* Calculate location equivalence labels.  */
    1844    224980216 :   for (i = 1; i < FIRST_REF_NODE; i++)
    1845              :     {
    1846    220564300 :       bitmap pointed_by;
    1847    220564300 :       bitmap_iterator bi;
    1848    220564300 :       unsigned int j;
    1849              : 
    1850    220564300 :       if (!graph->pointed_by[i])
    1851    199125202 :         continue;
    1852     21439098 :       pointed_by = BITMAP_ALLOC (&iteration_obstack);
    1853              : 
    1854              :       /* Translate the pointed-by mapping for pointer equivalence
    1855              :          labels.  */
    1856     96671772 :       EXECUTE_IF_SET_IN_BITMAP (graph->pointed_by[i], 0, j, bi)
    1857              :         {
    1858     75232674 :           bitmap_set_bit (pointed_by,
    1859     75232674 :                           graph->pointer_label[si->node_mapping[j]]);
    1860              :         }
    1861              :       /* The original pointed_by is now dead.  */
    1862     21439098 :       BITMAP_FREE (graph->pointed_by[i]);
    1863              : 
    1864              :       /* Look up the location equivalence label if one exists, or make
    1865              :          one otherwise.  */
    1866     21439098 :       equiv_class_label_t ecl;
    1867     21439098 :       ecl = equiv_class_lookup_or_add (location_equiv_class_table, pointed_by);
    1868     21439098 :       if (ecl->equivalence_class == 0)
    1869     20998851 :         ecl->equivalence_class = location_equiv_class++;
    1870              :       else
    1871              :         {
    1872       440247 :           if (dump_file && (dump_flags & TDF_DETAILS))
    1873           54 :             fprintf (dump_file, "Found location equivalence for node %s\n",
    1874           54 :                      get_varinfo (i)->name);
    1875       440247 :           BITMAP_FREE (pointed_by);
    1876              :         }
    1877     21439098 :       graph->loc_label[i] = ecl->equivalence_class;
    1878              : 
    1879              :     }
    1880              : 
    1881      4415916 :   if (dump_file && (dump_flags & TDF_DETAILS))
    1882         6826 :     for (i = 1; i < FIRST_REF_NODE; i++)
    1883              :       {
    1884         6523 :         unsigned j = si->node_mapping[i];
    1885         6523 :         if (j != i)
    1886              :           {
    1887           21 :             fprintf (dump_file, "%s node id %d ",
    1888           21 :                      bitmap_bit_p (graph->direct_nodes, i)
    1889              :                      ? "Direct" : "Indirect", i);
    1890           21 :             if (i < FIRST_REF_NODE)
    1891           21 :               fprintf (dump_file, "\"%s\"", get_varinfo (i)->name);
    1892              :             else
    1893            0 :               fprintf (dump_file, "\"*%s\"",
    1894            0 :                        get_varinfo (i - FIRST_REF_NODE)->name);
    1895           21 :             fprintf (dump_file, " mapped to SCC leader node id %d ", j);
    1896           21 :             if (j < FIRST_REF_NODE)
    1897           21 :               fprintf (dump_file, "\"%s\"\n", get_varinfo (j)->name);
    1898              :             else
    1899            0 :               fprintf (dump_file, "\"*%s\"\n",
    1900            0 :                        get_varinfo (j - FIRST_REF_NODE)->name);
    1901              :           }
    1902              :         else
    1903              :           {
    1904        10019 :             fprintf (dump_file,
    1905              :                      "Equivalence classes for %s node id %d ",
    1906         6502 :                      bitmap_bit_p (graph->direct_nodes, i)
    1907              :                      ? "direct" : "indirect", i);
    1908         6502 :             if (i < FIRST_REF_NODE)
    1909         6502 :               fprintf (dump_file, "\"%s\"", get_varinfo (i)->name);
    1910              :             else
    1911            0 :               fprintf (dump_file, "\"*%s\"",
    1912            0 :                        get_varinfo (i - FIRST_REF_NODE)->name);
    1913         6502 :             fprintf (dump_file,
    1914              :                      ": pointer %d, location %d\n",
    1915         6502 :                      graph->pointer_label[i], graph->loc_label[i]);
    1916              :           }
    1917              :       }
    1918              : 
    1919              :   /* Quickly eliminate our non-pointer variables.  */
    1920              : 
    1921    224980216 :   for (i = 1; i < FIRST_REF_NODE; i++)
    1922              :     {
    1923    220564300 :       unsigned int node = si->node_mapping[i];
    1924              : 
    1925    220564300 :       if (graph->pointer_label[node] == 0)
    1926              :         {
    1927     19723372 :           if (dump_file && (dump_flags & TDF_DETAILS))
    1928          928 :             fprintf (dump_file,
    1929              :                      "%s is a non-pointer variable, eliminating edges.\n",
    1930          928 :                      get_varinfo (node)->name);
    1931     19723372 :           stats.nonpointer_vars++;
    1932     19723372 :           clear_edges_for_node (graph, node);
    1933              :         }
    1934              :     }
    1935              : 
    1936      4415916 :   return si;
    1937              : }
    1938              : 
    1939              : /* Free information that was only necessary for variable
    1940              :    substitution.  */
    1941              : 
    1942              : static void
    1943      4415916 : free_var_substitution_info (class scc_info *si)
    1944              : {
    1945      4415916 :   delete si;
    1946      4415916 :   free (graph->pointer_label);
    1947      4415916 :   free (graph->loc_label);
    1948      4415916 :   free (graph->pointed_by);
    1949      4415916 :   free (graph->points_to);
    1950      4415916 :   free (graph->eq_rep);
    1951      4415916 :   sbitmap_free (graph->direct_nodes);
    1952      4415916 :   delete pointer_equiv_class_table;
    1953      4415916 :   pointer_equiv_class_table = NULL;
    1954      4415916 :   delete location_equiv_class_table;
    1955      4415916 :   location_equiv_class_table = NULL;
    1956      4415916 :   obstack_free (&equiv_class_obstack, NULL);
    1957      4415916 :   bitmap_obstack_release (&iteration_obstack);
    1958      4415916 : }
    1959              : 
    1960              : /* Return an existing node that is equivalent to NODE, which has
    1961              :    equivalence class LABEL, if one exists.  Return NODE otherwise.  */
    1962              : 
    1963              : static unsigned int
    1964    865407008 : find_equivalent_node (constraint_graph_t graph,
    1965              :                       unsigned int node, unsigned int label)
    1966              : {
    1967              :   /* If the address version of this variable is unused, we can
    1968              :      substitute it for anything else with the same label.
    1969              :      Otherwise, we know the pointers are equivalent, but not the
    1970              :      locations, and we can unite them later.  */
    1971              : 
    1972    865407008 :   if (!bitmap_bit_p (graph->address_taken, node))
    1973              :     {
    1974    673164580 :       gcc_checking_assert (label < graph->size);
    1975              : 
    1976    673164580 :       if (graph->eq_rep[label] != -1)
    1977              :         {
    1978              :           /* Unify the two variables since we know they are equivalent.  */
    1979    569720194 :           if (unite (graph->eq_rep[label], node))
    1980     66924145 :             unify_nodes (graph, graph->eq_rep[label], node, false);
    1981    569720194 :           return graph->eq_rep[label];
    1982              :         }
    1983              :       else
    1984              :         {
    1985    103444386 :           graph->eq_rep[label] = node;
    1986    103444386 :           graph->pe_rep[label] = node;
    1987              :         }
    1988              :     }
    1989              :   else
    1990              :     {
    1991    192242428 :       gcc_checking_assert (label < graph->size);
    1992    192242428 :       graph->pe[node] = label;
    1993    192242428 :       if (graph->pe_rep[label] == -1)
    1994     21347807 :         graph->pe_rep[label] = node;
    1995              :     }
    1996              : 
    1997              :   return node;
    1998              : }
    1999              : 
    2000              : /* Unite pointer equivalent but not location equivalent nodes in
    2001              :    GRAPH.  This may only be performed once variable substitution is
    2002              :    finished.  */
    2003              : 
    2004              : static void
    2005      4415916 : unite_pointer_equivalences (constraint_graph_t graph)
    2006              : {
    2007      4415916 :   unsigned int i;
    2008              : 
    2009              :   /* Go through the pointer equivalences and unite them to their
    2010              :      representative, if they aren't already.  */
    2011    224980216 :   for (i = 1; i < FIRST_REF_NODE; i++)
    2012              :     {
    2013    220564300 :       unsigned int label = graph->pe[i];
    2014    220564300 :       if (label)
    2015              :         {
    2016     21439098 :           int label_rep = graph->pe_rep[label];
    2017              : 
    2018     21439098 :           if (label_rep == -1)
    2019            0 :             continue;
    2020              : 
    2021     21439098 :           label_rep = find (label_rep);
    2022     21439098 :           if (label_rep >= 0 && unite (label_rep, find (i)))
    2023      2260386 :             unify_nodes (graph, label_rep, i, false);
    2024              :         }
    2025              :     }
    2026      4415916 : }
    2027              : 
    2028              : /* Move complex constraints to the GRAPH nodes they belong to.  */
    2029              : 
    2030              : static void
    2031      4415916 : move_complex_constraints (constraint_graph_t graph)
    2032              : {
    2033      4415916 :   int i;
    2034      4415916 :   constraint_t c;
    2035              : 
    2036    439574561 :   FOR_EACH_VEC_ELT (constraints, i, c)
    2037              :     {
    2038    435158645 :       if (c)
    2039              :         {
    2040    432703504 :           struct constraint_expr lhs = c->lhs;
    2041    432703504 :           struct constraint_expr rhs = c->rhs;
    2042              : 
    2043    432703504 :           if (lhs.type == DEREF)
    2044              :             {
    2045     35689454 :               insert_into_complex (graph, lhs.var, c);
    2046              :             }
    2047    397014050 :           else if (rhs.type == DEREF)
    2048              :             {
    2049     48254352 :               if (!(get_varinfo (lhs.var)->is_special_var))
    2050     48254346 :                 insert_into_complex (graph, rhs.var, c);
    2051              :             }
    2052    348759698 :           else if (rhs.type != ADDRESSOF && lhs.var > anything_id
    2053    259232611 :                    && (lhs.offset != 0 || rhs.offset != 0))
    2054              :             {
    2055     59927750 :               insert_into_complex (graph, rhs.var, c);
    2056              :             }
    2057              :         }
    2058              :     }
    2059      4415916 : }
    2060              : 
    2061              : /* Optimize and rewrite complex constraints while performing
    2062              :    collapsing of equivalent nodes.  SI is the SCC_INFO that is the
    2063              :    result of perform_variable_substitution.  */
    2064              : 
    2065              : static void
    2066      4415916 : rewrite_constraints (constraint_graph_t graph,
    2067              :                      class scc_info *si)
    2068              : {
    2069      4415916 :   int i;
    2070      4415916 :   constraint_t c;
    2071              : 
    2072      4415916 :   if (flag_checking)
    2073              :     {
    2074    454373200 :       for (unsigned int j = 0; j < graph->size; j++)
    2075    449957344 :         gcc_assert (find (j) == j);
    2076              :     }
    2077              : 
    2078    439574561 :   FOR_EACH_VEC_ELT (constraints, i, c)
    2079              :     {
    2080    435158645 :       struct constraint_expr lhs = c->lhs;
    2081    435158645 :       struct constraint_expr rhs = c->rhs;
    2082    435158645 :       unsigned int lhsvar = find (lhs.var);
    2083    435158645 :       unsigned int rhsvar = find (rhs.var);
    2084    435158645 :       unsigned int lhsnode, rhsnode;
    2085    435158645 :       unsigned int lhslabel, rhslabel;
    2086              : 
    2087    435158645 :       lhsnode = si->node_mapping[lhsvar];
    2088    435158645 :       rhsnode = si->node_mapping[rhsvar];
    2089    435158645 :       lhslabel = graph->pointer_label[lhsnode];
    2090    435158645 :       rhslabel = graph->pointer_label[rhsnode];
    2091              : 
    2092              :       /* See if it is really a non-pointer variable, and if so, ignore
    2093              :          the constraint.  */
    2094    435158645 :       if (lhslabel == 0)
    2095              :         {
    2096       761545 :           if (dump_file && (dump_flags & TDF_DETAILS))
    2097              :             {
    2098              : 
    2099           44 :               fprintf (dump_file, "%s is a non-pointer variable, "
    2100              :                        "ignoring constraint:",
    2101           22 :                        get_varinfo (lhs.var)->name);
    2102           22 :               dump_constraint (dump_file, c);
    2103           22 :               fprintf (dump_file, "\n");
    2104              :             }
    2105       761545 :           constraints[i] = NULL;
    2106      2455141 :           continue;
    2107              :         }
    2108              : 
    2109    434397100 :       if (rhslabel == 0)
    2110              :         {
    2111      1693596 :           if (dump_file && (dump_flags & TDF_DETAILS))
    2112              :             {
    2113              : 
    2114           88 :               fprintf (dump_file, "%s is a non-pointer variable, "
    2115              :                        "ignoring constraint:",
    2116           44 :                        get_varinfo (rhs.var)->name);
    2117           44 :               dump_constraint (dump_file, c);
    2118           44 :               fprintf (dump_file, "\n");
    2119              :             }
    2120      1693596 :           constraints[i] = NULL;
    2121      1693596 :           continue;
    2122              :         }
    2123              : 
    2124    432703504 :       lhsvar = find_equivalent_node (graph, lhsvar, lhslabel);
    2125    432703504 :       rhsvar = find_equivalent_node (graph, rhsvar, rhslabel);
    2126    432703504 :       c->lhs.var = lhsvar;
    2127    432703504 :       c->rhs.var = rhsvar;
    2128              :     }
    2129      4415916 : }
    2130              : 
    2131              : /* Eliminate indirect cycles involving NODE.  Return true if NODE was
    2132              :    part of an SCC, false otherwise.  */
    2133              : 
    2134              : static bool
    2135    382857558 : eliminate_indirect_cycles (unsigned int node)
    2136              : {
    2137    382857558 :   if (graph->indirect_cycles[node] != -1
    2138    383178977 :       && !bitmap_empty_p (get_varinfo (node)->solution))
    2139              :     {
    2140       289900 :       unsigned int i;
    2141       289900 :       auto_vec<unsigned> queue;
    2142       289900 :       int queuepos;
    2143       289900 :       unsigned int to = find (graph->indirect_cycles[node]);
    2144       289900 :       bitmap_iterator bi;
    2145              : 
    2146              :       /* We can't touch the solution set and call unify_nodes
    2147              :          at the same time, because unify_nodes is going to do
    2148              :          bitmap unions into it.  */
    2149              : 
    2150      1567555 :       EXECUTE_IF_SET_IN_BITMAP (get_varinfo (node)->solution, 0, i, bi)
    2151              :         {
    2152      1277655 :           if (find (i) == i && i != to)
    2153              :             {
    2154       343630 :               if (unite (to, i))
    2155       343630 :                 queue.safe_push (i);
    2156              :             }
    2157              :         }
    2158              : 
    2159       343630 :       for (queuepos = 0;
    2160       633530 :            queue.iterate (queuepos, &i);
    2161              :            queuepos++)
    2162              :         {
    2163       343630 :           unify_nodes (graph, to, i, true);
    2164              :         }
    2165       289900 :       return true;
    2166       289900 :     }
    2167              :   return false;
    2168              : }
    2169              : 
    2170              : /* Solve the constraint graph GRAPH using our worklist solver.
    2171              :    This is based on the PW* family of solvers from the "Efficient Field
    2172              :    Sensitive Pointer Analysis for C" paper.
    2173              :    It works by iterating over all the graph nodes, processing the complex
    2174              :    constraints and propagating the copy constraints, until everything stops
    2175              :    changed.  This corresponds to steps 6-8 in the solving list given above.  */
    2176              : 
    2177              : static void
    2178      4415916 : solve_graph (constraint_graph_t graph)
    2179              : {
    2180      4415916 :   unsigned int size = graph->size;
    2181      4415916 :   unsigned int i;
    2182      4415916 :   bitmap pts;
    2183              : 
    2184      4415916 :   changed = BITMAP_ALLOC (NULL);
    2185              : 
    2186              :   /* Mark all initial non-collapsed nodes as changed.  */
    2187    224980216 :   for (i = 1; i < size; i++)
    2188              :     {
    2189    220564300 :       varinfo_t ivi = get_varinfo (i);
    2190    371925214 :       if (find (i) == i && !bitmap_empty_p (ivi->solution)
    2191    273219751 :           && ((graph->succs[i] && !bitmap_empty_p (graph->succs[i]))
    2192    228418646 :               || graph->complex[i].length () > 0))
    2193     33574632 :         bitmap_set_bit (changed, i);
    2194              :     }
    2195              : 
    2196              :   /* Allocate a bitmap to be used to store the changed bits.  */
    2197      4415916 :   pts = BITMAP_ALLOC (&pta_obstack);
    2198              : 
    2199     16665266 :   while (!bitmap_empty_p (changed))
    2200              :     {
    2201      7833434 :       unsigned int i;
    2202      7833434 :       stats.iterations++;
    2203              : 
    2204      7833434 :       bitmap_obstack_initialize (&iteration_obstack);
    2205              : 
    2206      7833434 :       auto_vec<unsigned> topo_order = compute_topo_order (graph);
    2207    398836270 :       while (topo_order.length () != 0)
    2208              :         {
    2209    383169402 :           i = topo_order.pop ();
    2210              : 
    2211              :           /* If this variable is not a representative, skip it.  */
    2212    383169402 :           if (find (i) != i)
    2213       311844 :             continue;
    2214              : 
    2215              :           /* In certain indirect cycle cases, we may merge this
    2216              :              variable to another.  */
    2217    382857558 :           if (eliminate_indirect_cycles (i) && find (i) != i)
    2218           86 :             continue;
    2219              : 
    2220              :           /* If the node has changed, we need to process the
    2221              :              complex constraints and outgoing edges again.  For complex
    2222              :              constraints that modify i itself, like the common group of
    2223              :                callarg = callarg + UNKNOWN;
    2224              :                callarg = *callarg + UNKNOWN;
    2225              :                *callarg = callescape;
    2226              :              make sure to iterate immediately because that maximizes
    2227              :              cache reuse and expands the graph quickest, leading to
    2228              :              better visitation order in the next iteration.  */
    2229    524496423 :           while (bitmap_clear_bit (changed, i))
    2230              :             {
    2231    141927200 :               bitmap solution;
    2232    141927200 :               vec<constraint_t> &complex = graph->complex[i];
    2233    141927200 :               varinfo_t vi = get_varinfo (i);
    2234    141927200 :               bool solution_empty;
    2235              : 
    2236              :               /* Compute the changed set of solution bits.  If anything
    2237              :                  is in the solution just propagate that.  */
    2238    141927200 :               if (bitmap_bit_p (vi->solution, anything_id))
    2239              :                 {
    2240              :                   /* If anything is also in the old solution there is
    2241              :                      nothing to do.
    2242              :                      ???  But we shouldn't ended up with "changed" set ...  */
    2243      2490704 :                   if (vi->oldsolution
    2244      2490704 :                       && bitmap_bit_p (vi->oldsolution, anything_id))
    2245              :                     break;
    2246      2202455 :                   bitmap_copy (pts, get_varinfo (find (anything_id))->solution);
    2247              :                 }
    2248    139436496 :               else if (vi->oldsolution)
    2249     36288003 :                 bitmap_and_compl (pts, vi->solution, vi->oldsolution);
    2250              :               else
    2251    103148493 :                 bitmap_copy (pts, vi->solution);
    2252              : 
    2253    141638951 :               if (bitmap_empty_p (pts))
    2254              :                 break;
    2255              : 
    2256    141638951 :               if (vi->oldsolution)
    2257     37309530 :                 bitmap_ior_into (vi->oldsolution, pts);
    2258              :               else
    2259              :                 {
    2260    104329421 :                   vi->oldsolution = BITMAP_ALLOC (&oldpta_obstack);
    2261    104329421 :                   bitmap_copy (vi->oldsolution, pts);
    2262              :                 }
    2263              : 
    2264    141638951 :               solution = vi->solution;
    2265    141638951 :               solution_empty = bitmap_empty_p (solution);
    2266              : 
    2267              :               /* Process the complex constraints.  */
    2268    141638951 :               hash_set<constraint_t> *cvisited = nullptr;
    2269    141638951 :               if (flag_checking)
    2270    141638266 :                 cvisited = new hash_set<constraint_t>;
    2271    141638951 :               bitmap expanded_pts = NULL;
    2272    350178778 :               for (unsigned j = 0; j < complex.length (); ++j)
    2273              :                 {
    2274    208539827 :                   constraint_t c = complex[j];
    2275              :                   /* At unification time only the directly involved nodes
    2276              :                      will get their complex constraints updated.  Update
    2277              :                      our complex constraints now but keep the constraint
    2278              :                      vector sorted and clear of duplicates.  Also make
    2279              :                      sure to evaluate each prevailing constraint only once.  */
    2280    208539827 :                   unsigned int new_lhs = find (c->lhs.var);
    2281    208539827 :                   unsigned int new_rhs = find (c->rhs.var);
    2282    208539827 :                   if (c->lhs.var != new_lhs || c->rhs.var != new_rhs)
    2283              :                     {
    2284      1581271 :                       constraint tem = *c;
    2285      1581271 :                       tem.lhs.var = new_lhs;
    2286      1581271 :                       tem.rhs.var = new_rhs;
    2287      1581271 :                       unsigned int place
    2288      1581271 :                         = complex.lower_bound (&tem, constraint_less);
    2289      1581271 :                       c->lhs.var = new_lhs;
    2290      1581271 :                       c->rhs.var = new_rhs;
    2291      1581271 :                       if (place != j)
    2292              :                         {
    2293      1568864 :                           complex.ordered_remove (j);
    2294      1568864 :                           if (j < place)
    2295      1551065 :                             --place;
    2296      1568864 :                           if (place < complex.length ())
    2297              :                             {
    2298       352469 :                               if (constraint_equal (*complex[place], *c))
    2299              :                                 {
    2300        35777 :                                   j--;
    2301       284667 :                                   continue;
    2302              :                                 }
    2303              :                               else
    2304       316692 :                                 complex.safe_insert (place, c);
    2305              :                             }
    2306              :                           else
    2307      1216395 :                             complex.quick_push (c);
    2308      1533087 :                           if (place > j)
    2309              :                             {
    2310       248890 :                               j--;
    2311       248890 :                               continue;
    2312              :                             }
    2313              :                         }
    2314              :                     }
    2315              : 
    2316              :                   /* The only complex constraint that can change our
    2317              :                      solution to non-empty, given an empty solution,
    2318              :                      is a constraint where the lhs side is receiving
    2319              :                      some set from elsewhere.  */
    2320    208255160 :                   if (cvisited && cvisited->add (c))
    2321            0 :                     gcc_unreachable ();
    2322    208255160 :                   if (!solution_empty || c->lhs.type != DEREF)
    2323    208255160 :                     do_complex_constraint (graph, c, pts, &expanded_pts);
    2324              :                 }
    2325    141638951 :               if (cvisited)
    2326              :                 {
    2327              :                   /* When checking, verify the order of constraints is
    2328              :                      maintained and each constraint is evaluated exactly
    2329              :                      once.  */
    2330    269272760 :                   for (unsigned j = 1; j < complex.length (); ++j)
    2331    127634494 :                     gcc_assert (constraint_less (complex[j-1], complex[j]));
    2332    222257872 :                   gcc_assert (cvisited->elements () == complex.length ());
    2333    141638266 :                   delete cvisited;
    2334              :                 }
    2335    141638951 :               BITMAP_FREE (expanded_pts);
    2336              : 
    2337    141638951 :               solution_empty = bitmap_empty_p (solution);
    2338              : 
    2339    141638951 :               if (!solution_empty)
    2340              :                 {
    2341    141638951 :                   bitmap_iterator bi;
    2342    141638951 :                   unsigned eff_escaped_id = find (escaped_id);
    2343    141638951 :                   unsigned j;
    2344              : 
    2345              :                   /* Propagate solution to all successors.  */
    2346    141638951 :                   unsigned to_remove = ~0U;
    2347    357325740 :                   EXECUTE_IF_IN_NONNULL_BITMAP (graph->succs[i],
    2348              :                                                 0, j, bi)
    2349              :                     {
    2350    215686789 :                       if (to_remove != ~0U)
    2351              :                         {
    2352      2156444 :                           bitmap_clear_bit (graph->succs[i], to_remove);
    2353      2156444 :                           to_remove = ~0U;
    2354              :                         }
    2355    215686789 :                       unsigned int to = find (j);
    2356    215686789 :                       if (to != j)
    2357              :                         {
    2358              :                           /* Update the succ graph, avoiding duplicate
    2359              :                              work.  */
    2360      2130890 :                           to_remove = j;
    2361      2130890 :                           if (! bitmap_set_bit (graph->succs[i], to))
    2362       882107 :                             continue;
    2363              :                           /* We eventually end up processing 'to' twice
    2364              :                              as it is undefined whether bitmap iteration
    2365              :                              iterates over bits set during iteration.
    2366              :                              Play safe instead of doing tricks.  */
    2367              :                         }
    2368              :                       /* Don't try to propagate to ourselves.  */
    2369    214804682 :                       if (to == i)
    2370              :                         {
    2371       165721 :                           to_remove = j;
    2372       165721 :                           continue;
    2373              :                         }
    2374              :                       /* Early node unification can lead to edges from
    2375              :                          escaped - remove them.  */
    2376    214638961 :                       if (i == eff_escaped_id)
    2377              :                         {
    2378       166104 :                           to_remove = j;
    2379       166104 :                           if (bitmap_set_bit (get_varinfo (to)->solution,
    2380              :                                               escaped_id))
    2381        92876 :                             bitmap_set_bit (changed, to);
    2382       166104 :                           continue;
    2383              :                         }
    2384              : 
    2385    214472857 :                       if (bitmap_ior_into (get_varinfo (to)->solution, pts))
    2386     95344744 :                         bitmap_set_bit (changed, to);
    2387              :                     }
    2388     99167843 :                   if (to_remove != ~0U)
    2389       211852 :                     bitmap_clear_bit (graph->succs[i], to_remove);
    2390              :                 }
    2391              :             }
    2392              :         }
    2393      7833434 :       bitmap_obstack_release (&iteration_obstack);
    2394      7833434 :     }
    2395              : 
    2396      4415916 :   BITMAP_FREE (pts);
    2397      4415916 :   BITMAP_FREE (changed);
    2398      4415916 :   bitmap_obstack_release (&oldpta_obstack);
    2399      4415916 : }
    2400              : 
    2401              : void
    2402      4415916 : delete_graph (void)
    2403              : {
    2404      4415916 :   unsigned int i;
    2405    229396132 :   for (i = 0; i < graph->size; i++)
    2406    224980216 :     graph->complex[i].release ();
    2407      4415916 :   free (graph->complex);
    2408              : 
    2409      4415916 :   free (graph->succs);
    2410      4415916 :   free (graph->pe);
    2411      4415916 :   free (graph->pe_rep);
    2412      4415916 :   free (graph->indirect_cycles);
    2413              :   /* We are not doing free (graph->rep) since the representatives mapping is
    2414              :      needed outside of the solver too.  */
    2415      4415916 :   free (graph);
    2416      4415916 : }
    2417              : 
    2418              : /* Remove the REF and ADDRESS edges from GRAPH, as well as all the
    2419              :    predecessor edges.  */
    2420              : 
    2421              : static void
    2422      4415916 : remove_preds_and_fake_succs (constraint_graph_t graph)
    2423              : {
    2424      4415916 :   unsigned int i;
    2425              : 
    2426              :   /* Clear the implicit ref and address nodes from the successor
    2427              :      lists.  */
    2428    224980216 :   for (i = 1; i < FIRST_REF_NODE; i++)
    2429              :     {
    2430    220564300 :       if (graph->succs[i])
    2431     64396932 :         bitmap_clear_range (graph->succs[i], FIRST_REF_NODE,
    2432     64396932 :                             FIRST_REF_NODE * 2);
    2433              :     }
    2434              : 
    2435              :   /* Free the successor list for the non-ref nodes.  */
    2436    229396132 :   for (i = FIRST_REF_NODE + 1; i < graph->size; i++)
    2437              :     {
    2438    220564300 :       if (graph->succs[i])
    2439     11778409 :         BITMAP_FREE (graph->succs[i]);
    2440              :     }
    2441              : 
    2442              :   /* Now reallocate the size of the successor list as, and blow away
    2443              :      the predecessor bitmaps.  */
    2444      4415916 :   graph->size = varmap.length ();
    2445      4415916 :   graph->succs = XRESIZEVEC (bitmap, graph->succs, graph->size);
    2446              : 
    2447      4415916 :   free (graph->implicit_preds);
    2448      4415916 :   graph->implicit_preds = NULL;
    2449      4415916 :   free (graph->preds);
    2450      4415916 :   graph->preds = NULL;
    2451      4415916 :   bitmap_obstack_release (&predbitmap_obstack);
    2452      4415916 : }
    2453              : 
    2454              : namespace pointer_analysis {
    2455              : 
    2456              : /* Solve the constraint set.  The entry function of the solver.  */
    2457              : 
    2458              : void
    2459      4415916 : solve_constraints (void)
    2460              : {
    2461      4415916 :   class scc_info *si;
    2462              : 
    2463              :   /* Sort varinfos so that ones that cannot be pointed to are last.
    2464              :      This makes bitmaps more efficient.  */
    2465      4415916 :   unsigned int *map = XNEWVEC (unsigned int, varmap.length ());
    2466     44159160 :   for (unsigned i = 0; i < integer_id + 1; ++i)
    2467     39743244 :     map[i] = i;
    2468              :   /* Start with address-taken vars, followed by not address-taken vars
    2469              :      to move vars never appearing in the points-to solution bitmaps last.  */
    2470              :   unsigned j = integer_id + 1;
    2471    379305776 :   for (unsigned i = integer_id + 1; i < varmap.length (); ++i)
    2472    185236972 :     if (varmap[varmap[i]->head]->address_taken)
    2473     15187907 :       map[i] = j++;
    2474    189652888 :   for (unsigned i = integer_id + 1; i < varmap.length (); ++i)
    2475    185236972 :     if (! varmap[varmap[i]->head]->address_taken)
    2476    170049065 :       map[i] = j++;
    2477              :   /* Shuffle varmap according to map.  */
    2478    189652888 :   for (unsigned i = integer_id + 1; i < varmap.length (); ++i)
    2479              :     {
    2480    274741298 :       while (map[varmap[i]->id] != i)
    2481     89504326 :         std::swap (varmap[i], varmap[map[varmap[i]->id]]);
    2482    185236972 :       gcc_assert (bitmap_empty_p (varmap[i]->solution));
    2483    185236972 :       varmap[i]->id = i;
    2484    185236972 :       varmap[i]->next = map[varmap[i]->next];
    2485    185236972 :       varmap[i]->head = map[varmap[i]->head];
    2486              :     }
    2487              :   /* Finally rewrite constraints.  */
    2488    439574561 :   for (unsigned i = 0; i < constraints.length (); ++i)
    2489              :     {
    2490    435158645 :       constraints[i]->lhs.var = map[constraints[i]->lhs.var];
    2491    435158645 :       constraints[i]->rhs.var = map[constraints[i]->rhs.var];
    2492              :     }
    2493      4415916 :   free (map);
    2494              : 
    2495      4415916 :   if (dump_file)
    2496          484 :     fprintf (dump_file,
    2497              :              "\nCollapsing static cycles and doing variable "
    2498              :              "substitution\n");
    2499              : 
    2500      8831832 :   init_graph (varmap.length () * 2);
    2501              : 
    2502      4415916 :   if (dump_file)
    2503          484 :     fprintf (dump_file, "Building predecessor graph\n");
    2504      4415916 :   build_pred_graph ();
    2505              : 
    2506      4415916 :   if (dump_file)
    2507          484 :     fprintf (dump_file, "Detecting pointer and location "
    2508              :              "equivalences\n");
    2509      4415916 :   si = perform_var_substitution (graph);
    2510              : 
    2511      4415916 :   if (dump_file)
    2512          484 :     fprintf (dump_file, "Rewriting constraints and unifying "
    2513              :              "variables\n");
    2514      4415916 :   rewrite_constraints (graph, si);
    2515              : 
    2516      4415916 :   build_succ_graph ();
    2517              : 
    2518      4415916 :   free_var_substitution_info (si);
    2519              : 
    2520              :   /* Attach complex constraints to graph nodes.  */
    2521      4415916 :   move_complex_constraints (graph);
    2522              : 
    2523      4415916 :   if (dump_file)
    2524          484 :     fprintf (dump_file, "Uniting pointer but not location equivalent "
    2525              :              "variables\n");
    2526      4415916 :   unite_pointer_equivalences (graph);
    2527              : 
    2528      4415916 :   if (dump_file)
    2529          484 :     fprintf (dump_file, "Finding indirect cycles\n");
    2530      4415916 :   find_indirect_cycles (graph);
    2531              : 
    2532              :   /* Implicit nodes and predecessors are no longer necessary at this
    2533              :      point.  */
    2534      4415916 :   remove_preds_and_fake_succs (graph);
    2535              : 
    2536      4415916 :   if (dump_file && (dump_flags & TDF_GRAPH))
    2537              :     {
    2538            3 :       fprintf (dump_file, "\n\n// The constraint graph before solve-graph "
    2539              :                "in dot format:\n");
    2540            3 :       dump_constraint_graph (dump_file);
    2541            3 :       fprintf (dump_file, "\n\n");
    2542              :     }
    2543              : 
    2544      4415916 :   if (dump_file)
    2545          484 :     fprintf (dump_file, "Solving graph\n");
    2546              : 
    2547      4415916 :   solve_graph (graph);
    2548              : 
    2549      4415916 :   if (dump_file && (dump_flags & TDF_GRAPH))
    2550              :     {
    2551            3 :       fprintf (dump_file, "\n\n// The constraint graph after solve-graph "
    2552              :                "in dot format:\n");
    2553            3 :       dump_constraint_graph (dump_file);
    2554            3 :       fprintf (dump_file, "\n\n");
    2555              :     }
    2556              : 
    2557              :   /* The mapping node -> representative is one of the outputs of the
    2558              :      solver.  */
    2559      4415916 :   union_find_compress_all ();
    2560      4415916 :   var_rep = graph->rep;
    2561              : 
    2562      4415916 :   delete_graph ();
    2563      4415916 : }
    2564              : 
    2565              : } // namespace pointer_analysis
        

Generated by: LCOV version 2.4-beta

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