LCOV - code coverage report
Current view: top level - gcc/analyzer - svalue.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 73.0 % 1139 832
Test Date: 2025-06-28 16:12:38 Functions: 66.4 % 131 87
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Symbolic values.
       2                 :             :    Copyright (C) 2019-2025 Free Software Foundation, Inc.
       3                 :             :    Contributed by David Malcolm <dmalcolm@redhat.com>.
       4                 :             : 
       5                 :             : This file is part of GCC.
       6                 :             : 
       7                 :             : GCC is free software; you can redistribute it and/or modify it
       8                 :             : under the terms of the GNU General Public License as published by
       9                 :             : the Free Software Foundation; either version 3, or (at your option)
      10                 :             : any later version.
      11                 :             : 
      12                 :             : GCC is distributed in the hope that it will be useful, but
      13                 :             : WITHOUT ANY WARRANTY; without even the implied warranty of
      14                 :             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15                 :             : 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 "analyzer/common.h"
      22                 :             : 
      23                 :             : #include "tree-pretty-print.h"
      24                 :             : #include "gimple-pretty-print.h"
      25                 :             : #include "fold-const.h"
      26                 :             : #include "diagnostic.h"
      27                 :             : #include "tree-diagnostic.h"
      28                 :             : 
      29                 :             : #include "text-art/dump.h"
      30                 :             : 
      31                 :             : #include "analyzer/analyzer-logging.h"
      32                 :             : #include "analyzer/call-string.h"
      33                 :             : #include "analyzer/program-point.h"
      34                 :             : #include "analyzer/store.h"
      35                 :             : #include "analyzer/svalue.h"
      36                 :             : #include "analyzer/region-model.h"
      37                 :             : 
      38                 :             : #if ENABLE_ANALYZER
      39                 :             : 
      40                 :             : namespace ana {
      41                 :             : 
      42                 :             : static int cmp_csts_and_types (const_tree cst1, const_tree cst2);
      43                 :             : 
      44                 :             : /* class svalue and its various subclasses.  */
      45                 :             : 
      46                 :             : /* class svalue.  */
      47                 :             : 
      48                 :             : /* Dump a tree-like representation of this svalue and its constituent symbols
      49                 :             :    to stderr, using global_dc's colorization and theming options.
      50                 :             : 
      51                 :             :    For example:
      52                 :             :    . (gdb) call index_sval->dump()
      53                 :             :    . (27): ‘int’: initial_svalue
      54                 :             :    . ╰─ m_reg: (26): ‘int’: decl_region(‘x_10(D)’)
      55                 :             :    .    ╰─ parent: (9): frame_region(‘test_bitmask_2’, index: 0, depth: 1)
      56                 :             :    .       ╰─ parent: (1): stack region
      57                 :             :    .          ╰─ parent: (0): root region
      58                 :             :   */
      59                 :             : 
      60                 :             : DEBUG_FUNCTION void
      61                 :           0 : svalue::dump () const
      62                 :             : {
      63                 :           0 :   text_art::dump (*this);
      64                 :           0 : }
      65                 :             : 
      66                 :             : /* Dump a representation of this svalue to stderr.  */
      67                 :             : 
      68                 :             : DEBUG_FUNCTION void
      69                 :           0 : svalue::dump (bool simple) const
      70                 :             : {
      71                 :           0 :   tree_dump_pretty_printer pp (stderr);
      72                 :           0 :   dump_to_pp (&pp, simple);
      73                 :           0 :   pp_newline (&pp);
      74                 :           0 : }
      75                 :             : 
      76                 :             : /* Generate a textual representation of this svalue for debugging purposes.  */
      77                 :             : 
      78                 :             : label_text
      79                 :         374 : svalue::get_desc (bool simple) const
      80                 :             : {
      81                 :         374 :   pretty_printer pp;
      82                 :         374 :   pp_format_decoder (&pp) = default_tree_printer;
      83                 :         374 :   dump_to_pp (&pp, simple);
      84                 :         374 :   return label_text::take (xstrdup (pp_formatted_text (&pp)));
      85                 :         374 : }
      86                 :             : 
      87                 :             : /* Return a new json::string describing the svalue.  */
      88                 :             : 
      89                 :             : std::unique_ptr<json::value>
      90                 :          14 : svalue::to_json () const
      91                 :             : {
      92                 :          14 :   label_text desc = get_desc (true);
      93                 :          14 :   auto sval_js = std::make_unique<json::string> (desc.get ());
      94                 :          14 :   return sval_js;
      95                 :          14 : }
      96                 :             : 
      97                 :             : /* Class for optionally adding open/close paren pairs within
      98                 :             :    svalue::maybe_print_for_user.  */
      99                 :             : 
     100                 :             : class auto_add_parens
     101                 :             : {
     102                 :             : public:
     103                 :         141 :   auto_add_parens (pretty_printer *pp,
     104                 :             :                    const svalue *outer_sval,
     105                 :             :                    const svalue &inner_sval)
     106                 :         141 :   : m_pp (pp),
     107                 :         141 :     m_needs_parens (needs_parens_p (outer_sval, inner_sval))
     108                 :             :   {
     109                 :         141 :     if (m_needs_parens)
     110                 :          20 :       pp_string (m_pp, "(");
     111                 :         141 :   }
     112                 :         141 :   ~auto_add_parens ()
     113                 :             :   {
     114                 :         141 :     if (m_needs_parens)
     115                 :          20 :       pp_string (m_pp, ")");
     116                 :         141 :   }
     117                 :             : 
     118                 :             : private:
     119                 :         141 :   static bool needs_parens_p (const svalue *outer_sval,
     120                 :             :                               const svalue &inner_sval)
     121                 :             :   {
     122                 :         141 :     if (!outer_sval)
     123                 :             :       return false;
     124                 :         104 :     if (inner_sval.get_kind () == SK_BINOP)
     125                 :             :       return true;
     126                 :             :     return false;
     127                 :             :   }
     128                 :             : 
     129                 :             :   pretty_printer *m_pp;
     130                 :             :   bool m_needs_parens;
     131                 :             : };
     132                 :             : 
     133                 :             : /* Attempt to print a user-facing description of this svalue to PP,
     134                 :             :    using MODEL for extracting representative tree values if necessary.
     135                 :             :    Use OUTER_SVAL (which can be null) to determine if we need to wrap
     136                 :             :    this value in parentheses.  */
     137                 :             : 
     138                 :             : bool
     139                 :         141 : svalue::maybe_print_for_user (pretty_printer *pp,
     140                 :             :                               const region_model &model,
     141                 :             :                               const svalue *outer_sval) const
     142                 :             : {
     143                 :         141 :   auto_add_parens p (pp, outer_sval, *this);
     144                 :             : 
     145                 :         141 :   switch (get_kind ())
     146                 :             :     {
     147                 :             :     default:
     148                 :             :       break;
     149                 :          42 :     case SK_CONSTANT:
     150                 :          42 :       {
     151                 :          42 :         const constant_svalue *sval = (const constant_svalue *)this;
     152                 :          42 :         pp_printf (pp, "%E", sval->get_constant ());
     153                 :          42 :         return true;
     154                 :             :       }
     155                 :          34 :     case SK_INITIAL:
     156                 :          34 :       {
     157                 :          34 :         const initial_svalue *sval = (const initial_svalue *)this;
     158                 :          34 :         return sval->get_region ()->maybe_print_for_user (pp, model);
     159                 :             :       }
     160                 :          12 :     case SK_UNARYOP:
     161                 :          12 :       {
     162                 :          12 :         const unaryop_svalue *sval = (const unaryop_svalue *)this;
     163                 :          12 :         if (sval->get_op () == NOP_EXPR)
     164                 :             :           {
     165                 :          12 :             if (!sval->get_arg ()->maybe_print_for_user (pp, model, outer_sval))
     166                 :             :               return false;
     167                 :             :             return true;
     168                 :             :           }
     169                 :             :       }
     170                 :             :       break;
     171                 :          48 :     case SK_BINOP:
     172                 :          48 :       {
     173                 :          48 :         const binop_svalue *sval = (const binop_svalue *)this;
     174                 :          48 :         switch (sval->get_op ())
     175                 :             :           {
     176                 :             :           default:
     177                 :             :             break;
     178                 :             : 
     179                 :          48 :           case PLUS_EXPR:
     180                 :          48 :           case MINUS_EXPR:
     181                 :          48 :           case MULT_EXPR:
     182                 :          48 :             {
     183                 :          48 :               if (!sval->get_arg0 ()->maybe_print_for_user (pp, model, this))
     184                 :             :                 return false;
     185                 :          48 :               pp_printf (pp, " %s ", op_symbol_code (sval->get_op ()));
     186                 :          48 :               if (!sval->get_arg1 ()->maybe_print_for_user (pp, model, this))
     187                 :             :                 return false;
     188                 :             :               return true;
     189                 :             :             }
     190                 :             :           }
     191                 :             :       }
     192                 :             :       break;
     193                 :             :     }
     194                 :             : 
     195                 :           5 :   if (tree expr = model.get_representative_tree (this))
     196                 :             :     {
     197                 :           4 :       expr = remove_ssa_names (expr);
     198                 :           4 :       print_expr_for_user (pp, expr);
     199                 :           4 :       return true;
     200                 :             :     }
     201                 :             : 
     202                 :             :   return false;
     203                 :         141 : }
     204                 :             : 
     205                 :             : /* Use DWI to create a text_art::widget describing this svalue in
     206                 :             :    a tree-like form, using PREFIX as a prefix (e.g. for field names).
     207                 :             :    We do this via two vfuncs:
     208                 :             :    (a) print_dump_widget_label, to populate the text of a tree_widget, and
     209                 :             :    (b) add_dump_widget_children, to add children to the tree_widget.  */
     210                 :             : 
     211                 :             : std::unique_ptr<text_art::tree_widget>
     212                 :           0 : svalue::make_dump_widget (const text_art::dump_widget_info &dwi,
     213                 :             :                           const char *prefix) const
     214                 :             : {
     215                 :           0 :   pretty_printer pp;
     216                 :           0 :   pp_format_decoder (&pp) = default_tree_printer;
     217                 :           0 :   pp_show_color (&pp) = true;
     218                 :             : 
     219                 :           0 :   if (prefix)
     220                 :           0 :     pp_printf (&pp, "%s: ", prefix);
     221                 :             : 
     222                 :           0 :   pp_printf (&pp, "(%i): ", get_id ());
     223                 :           0 :   if (get_type ())
     224                 :           0 :     pp_printf (&pp, "%qT: ", get_type ());
     225                 :             : 
     226                 :           0 :   print_dump_widget_label (&pp);
     227                 :             : 
     228                 :           0 :   std::unique_ptr<text_art::tree_widget> w
     229                 :           0 :     (text_art::tree_widget::make (dwi, &pp));
     230                 :             : 
     231                 :           0 :   add_dump_widget_children (*w, dwi);
     232                 :             : 
     233                 :           0 :   return w;
     234                 :           0 : }
     235                 :             : 
     236                 :             : /* If this svalue is a constant_svalue, return the underlying tree constant.
     237                 :             :    Otherwise return NULL_TREE.  */
     238                 :             : 
     239                 :             : tree
     240                 :    11796144 : svalue::maybe_get_constant () const
     241                 :             : {
     242                 :    11796144 :   const svalue *sval = unwrap_any_unmergeable ();
     243                 :    11796144 :   if (const constant_svalue *cst_sval = sval->dyn_cast_constant_svalue ())
     244                 :     3462294 :     return cst_sval->get_constant ();
     245                 :             :   else
     246                 :             :     return NULL_TREE;
     247                 :             : }
     248                 :             : 
     249                 :             : /* If this svalue is a region_svalue, return the region it points to.
     250                 :             :    Otherwise return NULL.  */
     251                 :             : 
     252                 :             : const region *
     253                 :       92489 : svalue::maybe_get_region () const
     254                 :             : {
     255                 :       92489 :   if (const region_svalue *region_sval = dyn_cast_region_svalue ())
     256                 :       25806 :     return region_sval->get_pointee ();
     257                 :             :   else
     258                 :             :     return NULL;
     259                 :             : }
     260                 :             : 
     261                 :             : /* If this svalue is a cast (i.e a unaryop NOP_EXPR or VIEW_CONVERT_EXPR),
     262                 :             :    return the underlying svalue.
     263                 :             :    Otherwise return NULL.  */
     264                 :             : 
     265                 :             : const svalue *
     266                 :     9372123 : svalue::maybe_undo_cast () const
     267                 :             : {
     268                 :     9372123 :   if (const unaryop_svalue *unaryop_sval = dyn_cast_unaryop_svalue ())
     269                 :             :     {
     270                 :      147930 :       enum tree_code op = unaryop_sval->get_op ();
     271                 :      147930 :       if (op == NOP_EXPR || op == VIEW_CONVERT_EXPR)
     272                 :      134034 :         return unaryop_sval->get_arg ();
     273                 :             :     }
     274                 :             :   return NULL;
     275                 :             : }
     276                 :             : 
     277                 :             : /* If this svalue is an unmergeable decorator around another svalue, return
     278                 :             :    the underlying svalue.
     279                 :             :    Otherwise return this svalue.  */
     280                 :             : 
     281                 :             : const svalue *
     282                 :    15203070 : svalue::unwrap_any_unmergeable () const
     283                 :             : {
     284                 :    15203070 :   if (const unmergeable_svalue *unmergeable = dyn_cast_unmergeable_svalue ())
     285                 :        4547 :     return unmergeable->get_arg ();
     286                 :             :   return this;
     287                 :             : }
     288                 :             : 
     289                 :             : /* Attempt to merge THIS with OTHER, returning the merged svalue.
     290                 :             :    Return NULL if not mergeable.  */
     291                 :             : 
     292                 :             : const svalue *
     293                 :      294539 : svalue::can_merge_p (const svalue *other,
     294                 :             :                      region_model_manager *mgr,
     295                 :             :                      model_merger *merger) const
     296                 :             : {
     297                 :      294539 :   if (!(get_type () && other->get_type ()))
     298                 :             :     return NULL;
     299                 :             : 
     300                 :      244784 :   if (!types_compatible_p (get_type (), other->get_type ()))
     301                 :             :     return NULL;
     302                 :             : 
     303                 :             :   /* Reject attempts to merge unmergeable svalues.  */
     304                 :      234564 :   if ((get_kind () == SK_UNMERGEABLE)
     305                 :      234564 :       || (other->get_kind () == SK_UNMERGEABLE))
     306                 :        5260 :     return NULL;
     307                 :             : 
     308                 :             :   /* Reject attempts to merge poisoned svalues with other svalues
     309                 :             :      (either non-poisoned, or other kinds of poison), so that e.g.
     310                 :             :      we identify paths in which a variable is conditionally uninitialized.  */
     311                 :      229304 :   if (get_kind () == SK_POISONED
     312                 :      229304 :       || other->get_kind () == SK_POISONED)
     313                 :        2121 :     return NULL;
     314                 :             : 
     315                 :             :   /* Reject attempts to merge NULL pointers with not-NULL-pointers.  */
     316                 :      227183 :   if (POINTER_TYPE_P (get_type ()))
     317                 :             :     {
     318                 :       70998 :       bool null0 = false;
     319                 :       70998 :       bool null1 = false;
     320                 :       70998 :       if (tree cst0 = maybe_get_constant ())
     321                 :       13241 :         if (zerop (cst0))
     322                 :       70998 :           null0 = true;
     323                 :       70998 :       if (tree cst1 = other->maybe_get_constant ())
     324                 :       12354 :         if (zerop (cst1))
     325                 :       70998 :           null1 = true;
     326                 :       70998 :       if (null0 != null1)
     327                 :             :         return NULL;
     328                 :             :     }
     329                 :             : 
     330                 :             :   /* Reject merging svalues that have non-purgable sm-state,
     331                 :             :      to avoid falsely reporting memory leaks by merging them
     332                 :             :      with something else.  */
     333                 :      201903 :   if (!merger->mergeable_svalue_p (this))
     334                 :             :     return NULL;
     335                 :      198194 :   if (!merger->mergeable_svalue_p (other))
     336                 :             :     return NULL;
     337                 :             : 
     338                 :             :   /* Widening.  */
     339                 :             :   /* Merge: (new_cst, existing_cst) -> widen (existing, new).  */
     340                 :      196459 :   if (maybe_get_constant () && other->maybe_get_constant ())
     341                 :             :     {
     342                 :        2833 :       return mgr->get_or_create_widening_svalue (other->get_type (),
     343                 :             :                                                  merger->get_function_point (),
     344                 :        2833 :                                                  other, this);
     345                 :             :     }
     346                 :             : 
     347                 :             :   /* Merger of:
     348                 :             :          this: BINOP (X, OP, CST)
     349                 :             :         other: X, where X is non-widening
     350                 :             :            to: WIDENING (other, this).  */
     351                 :      193626 :   if (const binop_svalue *binop_sval = dyn_cast_binop_svalue ())
     352                 :       13322 :     if (binop_sval->get_arg0 () == other
     353                 :        1789 :         && binop_sval->get_arg1 ()->get_kind () == SK_CONSTANT
     354                 :       14904 :         && other->get_kind () != SK_WIDENING)
     355                 :         554 :       return mgr->get_or_create_widening_svalue (other->get_type (),
     356                 :             :                                                  merger->get_function_point (),
     357                 :         554 :                                                  other, this);
     358                 :             : 
     359                 :             :   /* Merge: (Widen(existing_val, V), existing_val) -> Widen (existing_val, V)
     360                 :             :      and thus get a fixed point.  */
     361                 :      193072 :   if (const widening_svalue *widen_sval = dyn_cast_widening_svalue ())
     362                 :             :     {
     363                 :       18927 :       if (other == widen_sval->get_base_svalue ())
     364                 :             :         return this;
     365                 :        3443 :       if (other == widen_sval->get_iter_svalue ())
     366                 :             :         return this;
     367                 :             :     }
     368                 :             : 
     369                 :      175003 :   if (const binop_svalue *binop_sval = dyn_cast_binop_svalue ())
     370                 :       12768 :     if (const widening_svalue *widen_arg0
     371                 :       12768 :         = binop_sval->get_arg0 ()->dyn_cast_widening_svalue ())
     372                 :             :       {
     373                 :        4348 :         if (other == binop_sval->get_arg1 ())
     374                 :             :           {
     375                 :             :             /* Merger of: (Widen(..., OTHER) BINOP X)
     376                 :             :                and      : OTHER
     377                 :             :                to       : (Widen(..., OTHER) BINOP X)
     378                 :             :                e.g. merge of Widen(0, 1) + 1 with 1 to the Widen(0, 1) + 1.  */
     379                 :             :             return this;
     380                 :             :           }
     381                 :             : 
     382                 :             :         /* Merger of : (Widen() BINOP X)
     383                 :             :            and       : Widen()
     384                 :             :            to        : Widen()
     385                 :             :            e.g. merge of Widen(0, 1) + 1 and Widen(0, 1) to Widen(0, 1).
     386                 :             :            However, we want to update constraints for this case, since we're
     387                 :             :            considering another iteration.
     388                 :             :            Presumably we also want to ensure that it converges; we don't want
     389                 :             :            a descending chain of constraints.  */
     390                 :        2676 :         if (other == widen_arg0)
     391                 :             :           {
     392                 :        1028 :             merger->on_widening_reuse (widen_arg0);
     393                 :        1028 :             return widen_arg0;
     394                 :             :           }
     395                 :             : 
     396                 :             :         /* Merger of:
     397                 :             :             this: BINOP(WIDENING(BASE, BINOP(BASE, X)), X)
     398                 :             :            other: BINOP(BASE, X)
     399                 :             :               to: WIDENING(BASE, BINOP(BASE, X)).  */
     400                 :        1648 :         if (widen_arg0->get_iter_svalue () == other)
     401                 :        1480 :           if (const binop_svalue *other_binop_sval
     402                 :         740 :                 = other->dyn_cast_binop_svalue ())
     403                 :         518 :             if (other_binop_sval->get_arg0 () == widen_arg0->get_base_svalue ()
     404                 :         518 :                 && other_binop_sval->get_arg1 () == binop_sval->get_arg1 ())
     405                 :             :               return widen_arg0;
     406                 :             :       }
     407                 :             : 
     408                 :      171785 :   return mgr->get_or_create_unknown_svalue (get_type ());
     409                 :             : }
     410                 :             : 
     411                 :             : /* Determine if this svalue is either within LIVE_SVALUES, or is implicitly
     412                 :             :    live with respect to LIVE_SVALUES and MODEL.
     413                 :             :    LIVE_SVALUES can be NULL, in which case determine if this svalue is
     414                 :             :    intrinsically live.  */
     415                 :             : 
     416                 :             : bool
     417                 :     6431955 : svalue::live_p (const svalue_set *live_svalues,
     418                 :             :                 const region_model *model) const
     419                 :             : {
     420                 :             :   /* Determine if SVAL is explicitly live.  */
     421                 :     6431955 :   if (live_svalues)
     422                 :     6429890 :     if (const_cast<svalue_set *> (live_svalues)->contains (this))
     423                 :             :       return true;
     424                 :             : 
     425                 :             :   /* Otherwise, determine if SVAL is implicitly live due to being made of
     426                 :             :      other live svalues.  */
     427                 :     2398513 :   return implicitly_live_p (live_svalues, model);
     428                 :             : }
     429                 :             : 
     430                 :             : /* Base implementation of svalue::implicitly_live_p.  */
     431                 :             : 
     432                 :             : bool
     433                 :      233270 : svalue::implicitly_live_p (const svalue_set *, const region_model *) const
     434                 :             : {
     435                 :      233270 :   return false;
     436                 :             : }
     437                 :             : 
     438                 :             : /* Comparator for imposing a deterministic order on constants that are
     439                 :             :    of the same type.  */
     440                 :             : 
     441                 :             : static int
     442                 :     1357213 : cmp_csts_same_type (const_tree cst1, const_tree cst2)
     443                 :             : {
     444                 :     1357213 :   gcc_assert (TREE_TYPE (cst1) == TREE_TYPE (cst2));
     445                 :     1357213 :   gcc_assert (TREE_CODE (cst1) == TREE_CODE (cst2));
     446                 :     1357213 :   switch (TREE_CODE (cst1))
     447                 :             :     {
     448                 :           0 :     default:
     449                 :           0 :       gcc_unreachable ();
     450                 :     1356773 :     case INTEGER_CST:
     451                 :     1356773 :       return tree_int_cst_compare (cst1, cst2);
     452                 :           0 :     case STRING_CST:
     453                 :           0 :       if (TREE_STRING_LENGTH (cst1) < TREE_STRING_LENGTH (cst2))
     454                 :             :         return -1;
     455                 :           0 :       if (TREE_STRING_LENGTH (cst1) > TREE_STRING_LENGTH (cst2))
     456                 :             :         return 1;
     457                 :           0 :       return memcmp (TREE_STRING_POINTER (cst1),
     458                 :           0 :                      TREE_STRING_POINTER (cst2),
     459                 :           0 :                      TREE_STRING_LENGTH (cst1));
     460                 :          52 :     case RAW_DATA_CST:
     461                 :          52 :       if (RAW_DATA_LENGTH (cst1) < RAW_DATA_LENGTH (cst2))
     462                 :             :         return -1;
     463                 :          52 :       if (RAW_DATA_LENGTH (cst1) > RAW_DATA_LENGTH (cst2))
     464                 :             :         return 1;
     465                 :          52 :       return memcmp (RAW_DATA_POINTER (cst1),
     466                 :          52 :                      RAW_DATA_POINTER (cst2),
     467                 :          52 :                      RAW_DATA_LENGTH (cst1));
     468                 :         296 :     case REAL_CST:
     469                 :             :       /* Impose an arbitrary but deterministic order.  */
     470                 :         296 :       return memcmp (TREE_REAL_CST_PTR (cst1),
     471                 :         296 :                      TREE_REAL_CST_PTR (cst2),
     472                 :         296 :                      sizeof (real_value));
     473                 :          92 :     case COMPLEX_CST:
     474                 :          92 :       if (int cmp_real = cmp_csts_and_types (TREE_REALPART (cst1),
     475                 :          92 :                                              TREE_REALPART (cst2)))
     476                 :             :         return cmp_real;
     477                 :          44 :       return cmp_csts_and_types (TREE_IMAGPART (cst1), TREE_IMAGPART (cst2));
     478                 :           0 :     case VECTOR_CST:
     479                 :           0 :       if (int cmp_log2_npatterns
     480                 :           0 :             = ((int)VECTOR_CST_LOG2_NPATTERNS (cst1)
     481                 :           0 :                - (int)VECTOR_CST_LOG2_NPATTERNS (cst2)))
     482                 :             :         return cmp_log2_npatterns;
     483                 :           0 :       if (int cmp_nelts_per_pattern
     484                 :           0 :             = ((int)VECTOR_CST_NELTS_PER_PATTERN (cst1)
     485                 :           0 :                - (int)VECTOR_CST_NELTS_PER_PATTERN (cst2)))
     486                 :             :         return cmp_nelts_per_pattern;
     487                 :           0 :       unsigned encoded_nelts = vector_cst_encoded_nelts (cst1);
     488                 :           0 :       for (unsigned i = 0; i < encoded_nelts; i++)
     489                 :             :         {
     490                 :           0 :           const_tree elt1 = VECTOR_CST_ENCODED_ELT (cst1, i);
     491                 :           0 :           const_tree elt2 = VECTOR_CST_ENCODED_ELT (cst2, i);
     492                 :           0 :           if (int el_cmp = cmp_csts_and_types (elt1, elt2))
     493                 :             :             return el_cmp;
     494                 :             :         }
     495                 :             :       return 0;
     496                 :             :     }
     497                 :             : }
     498                 :             : 
     499                 :             : /* Comparator for imposing a deterministic order on constants that might
     500                 :             :    not be of the same type.  */
     501                 :             : 
     502                 :             : static int
     503                 :     1357229 : cmp_csts_and_types (const_tree cst1, const_tree cst2)
     504                 :             : {
     505                 :     1357229 :   int t1 = TYPE_UID (TREE_TYPE (cst1));
     506                 :     1357229 :   int t2 = TYPE_UID (TREE_TYPE (cst2));
     507                 :     1357229 :   if (int cmp_type = t1 - t2)
     508                 :             :     return cmp_type;
     509                 :     1357213 :   return cmp_csts_same_type (cst1, cst2);
     510                 :             : }
     511                 :             : 
     512                 :             : /* Comparator for imposing a deterministic order on svalues.  */
     513                 :             : 
     514                 :             : int
     515                 :    27205956 : svalue::cmp_ptr (const svalue *sval1, const svalue *sval2)
     516                 :             : {
     517                 :    28191618 :   if (sval1 == sval2)
     518                 :             :     return 0;
     519                 :    27139316 :   if (int cmp_kind = sval1->get_kind () - sval2->get_kind ())
     520                 :             :     return cmp_kind;
     521                 :     9605098 :   int t1 = sval1->get_type () ? TYPE_UID (sval1->get_type ()) : -1;
     522                 :     9605098 :   int t2 = sval2->get_type () ? TYPE_UID (sval2->get_type ()) : -1;
     523                 :     9605098 :   if (int cmp_type = t1 - t2)
     524                 :             :     return cmp_type;
     525                 :     5120139 :   switch (sval1->get_kind ())
     526                 :             :     {
     527                 :           0 :     default:
     528                 :           0 :       gcc_unreachable ();
     529                 :      982325 :     case SK_REGION:
     530                 :      982325 :       {
     531                 :      982325 :         const region_svalue *region_sval1 = (const region_svalue *)sval1;
     532                 :      982325 :         const region_svalue *region_sval2 = (const region_svalue *)sval2;
     533                 :      982325 :         return region::cmp_ids (region_sval1->get_pointee (),
     534                 :     1964650 :                                 region_sval2->get_pointee ());
     535                 :             :       }
     536                 :     1357093 :       break;
     537                 :     1357093 :     case SK_CONSTANT:
     538                 :     1357093 :       {
     539                 :     1357093 :         const constant_svalue *constant_sval1 = (const constant_svalue *)sval1;
     540                 :     1357093 :         const constant_svalue *constant_sval2 = (const constant_svalue *)sval2;
     541                 :     1357093 :         const_tree cst1 = constant_sval1->get_constant ();
     542                 :     1357093 :         const_tree cst2 = constant_sval2->get_constant ();
     543                 :             :         /* The svalues have the same type, but the underlying trees
     544                 :             :            might not (for the case where both svalues are typeless).  */
     545                 :     1357093 :         return cmp_csts_and_types (cst1, cst2);
     546                 :             :       }
     547                 :           0 :       break;
     548                 :           0 :     case SK_UNKNOWN:
     549                 :           0 :       {
     550                 :           0 :         gcc_assert (sval1 == sval2);
     551                 :             :         return 0;
     552                 :             :       }
     553                 :           0 :       break;
     554                 :           0 :     case SK_POISONED:
     555                 :           0 :       {
     556                 :           0 :         const poisoned_svalue *poisoned_sval1 = (const poisoned_svalue *)sval1;
     557                 :           0 :         const poisoned_svalue *poisoned_sval2 = (const poisoned_svalue *)sval2;
     558                 :           0 :         return (static_cast<int> (poisoned_sval1->get_poison_kind ())
     559                 :           0 :                 - static_cast<int> (poisoned_sval2->get_poison_kind ()));
     560                 :             :       }
     561                 :           0 :       break;
     562                 :           0 :     case SK_SETJMP:
     563                 :           0 :       {
     564                 :           0 :         const setjmp_svalue *setjmp_sval1 = (const setjmp_svalue *)sval1;
     565                 :           0 :         const setjmp_svalue *setjmp_sval2 = (const setjmp_svalue *)sval2;
     566                 :           0 :         const setjmp_record &rec1 = setjmp_sval1->get_setjmp_record ();
     567                 :           0 :         const setjmp_record &rec2 = setjmp_sval2->get_setjmp_record ();
     568                 :           0 :         return setjmp_record::cmp (rec1, rec2);
     569                 :             :       }
     570                 :     1414656 :       break;
     571                 :     1414656 :     case SK_INITIAL:
     572                 :     1414656 :       {
     573                 :     1414656 :         const initial_svalue *initial_sval1 = (const initial_svalue *)sval1;
     574                 :     1414656 :         const initial_svalue *initial_sval2 = (const initial_svalue *)sval2;
     575                 :     1414656 :         return region::cmp_ids (initial_sval1->get_region (),
     576                 :     2829312 :                                 initial_sval2->get_region ());
     577                 :             :       }
     578                 :       38263 :       break;
     579                 :       38263 :     case SK_UNARYOP:
     580                 :       38263 :       {
     581                 :       38263 :         const unaryop_svalue *unaryop_sval1 = (const unaryop_svalue *)sval1;
     582                 :       38263 :         const unaryop_svalue *unaryop_sval2 = (const unaryop_svalue *)sval2;
     583                 :       38263 :         if (int op_cmp = unaryop_sval1->get_op () - unaryop_sval2->get_op ())
     584                 :             :           return op_cmp;
     585                 :       38223 :         return svalue::cmp_ptr (unaryop_sval1->get_arg (),
     586                 :       38223 :                                 unaryop_sval2->get_arg ());
     587                 :             :       }
     588                 :     1125575 :       break;
     589                 :     1125575 :     case SK_BINOP:
     590                 :     1125575 :       {
     591                 :     1125575 :         const binop_svalue *binop_sval1 = (const binop_svalue *)sval1;
     592                 :     1125575 :         const binop_svalue *binop_sval2 = (const binop_svalue *)sval2;
     593                 :     1125575 :         if (int op_cmp = binop_sval1->get_op () - binop_sval2->get_op ())
     594                 :             :           return op_cmp;
     595                 :     1110429 :         if (int arg0_cmp = svalue::cmp_ptr (binop_sval1->get_arg0 (),
     596                 :             :                                             binop_sval2->get_arg0 ()))
     597                 :             :           return arg0_cmp;
     598                 :      946938 :         return svalue::cmp_ptr (binop_sval1->get_arg1 (),
     599                 :      946938 :                                 binop_sval2->get_arg1 ());
     600                 :             :       }
     601                 :        8344 :       break;
     602                 :        8344 :     case SK_SUB:
     603                 :        8344 :       {
     604                 :        8344 :         const sub_svalue *sub_sval1 = (const sub_svalue *)sval1;
     605                 :        8344 :         const sub_svalue *sub_sval2 = (const sub_svalue *)sval2;
     606                 :        8344 :         if (int parent_cmp = svalue::cmp_ptr (sub_sval1->get_parent (),
     607                 :             :                                               sub_sval2->get_parent ()))
     608                 :             :           return parent_cmp;
     609                 :        8344 :         return region::cmp_ids (sub_sval1->get_subregion (),
     610                 :       16688 :                                 sub_sval2->get_subregion ());
     611                 :             :       }
     612                 :         469 :       break;
     613                 :         469 :     case SK_REPEATED:
     614                 :         469 :       {
     615                 :         469 :         const repeated_svalue *repeated_sval1 = (const repeated_svalue *)sval1;
     616                 :         469 :         const repeated_svalue *repeated_sval2 = (const repeated_svalue *)sval2;
     617                 :         469 :         return svalue::cmp_ptr (repeated_sval1->get_inner_svalue (),
     618                 :         469 :                                 repeated_sval2->get_inner_svalue ());
     619                 :             :       }
     620                 :        1152 :       break;
     621                 :        1152 :     case SK_BITS_WITHIN:
     622                 :        1152 :       {
     623                 :        1152 :         const bits_within_svalue *bits_within_sval1
     624                 :             :           = (const bits_within_svalue *)sval1;
     625                 :        1152 :         const bits_within_svalue *bits_within_sval2
     626                 :             :           = (const bits_within_svalue *)sval2;
     627                 :        1152 :         if (int cmp = bit_range::cmp (bits_within_sval1->get_bits (),
     628                 :             :                                        bits_within_sval2->get_bits ()))
     629                 :             :           return cmp;
     630                 :           0 :         return svalue::cmp_ptr (bits_within_sval1->get_inner_svalue (),
     631                 :           0 :                                 bits_within_sval2->get_inner_svalue ());
     632                 :             :       }
     633                 :           0 :       break;
     634                 :           0 :     case SK_UNMERGEABLE:
     635                 :           0 :       {
     636                 :           0 :         const unmergeable_svalue *unmergeable_sval1
     637                 :             :           = (const unmergeable_svalue *)sval1;
     638                 :           0 :         const unmergeable_svalue *unmergeable_sval2
     639                 :             :           = (const unmergeable_svalue *)sval2;
     640                 :           0 :         return svalue::cmp_ptr (unmergeable_sval1->get_arg (),
     641                 :           0 :                                 unmergeable_sval2->get_arg ());
     642                 :             :       }
     643                 :           0 :       break;
     644                 :           0 :     case SK_PLACEHOLDER:
     645                 :           0 :       {
     646                 :           0 :         const placeholder_svalue *placeholder_sval1
     647                 :             :           = (const placeholder_svalue *)sval1;
     648                 :           0 :         const placeholder_svalue *placeholder_sval2
     649                 :             :           = (const placeholder_svalue *)sval2;
     650                 :           0 :         return strcmp (placeholder_sval1->get_name (),
     651                 :           0 :                        placeholder_sval2->get_name ());
     652                 :             :       }
     653                 :        2592 :       break;
     654                 :        2592 :     case SK_WIDENING:
     655                 :        2592 :       {
     656                 :        2592 :         const widening_svalue *widening_sval1 = (const widening_svalue *)sval1;
     657                 :        2592 :         const widening_svalue *widening_sval2 = (const widening_svalue *)sval2;
     658                 :        2592 :         if (int point_cmp = function_point::cmp (widening_sval1->get_point (),
     659                 :             :                                                  widening_sval2->get_point ()))
     660                 :             :           return point_cmp;
     661                 :        2592 :         if (int base_cmp = svalue::cmp_ptr (widening_sval1->get_base_svalue (),
     662                 :             :                                             widening_sval2->get_base_svalue ()))
     663                 :             :           return base_cmp;
     664                 :          32 :         return svalue::cmp_ptr (widening_sval1->get_iter_svalue (),
     665                 :          32 :                                 widening_sval2->get_iter_svalue ());
     666                 :             :       }
     667                 :          52 :       break;
     668                 :          52 :     case SK_COMPOUND:
     669                 :          52 :       {
     670                 :          52 :         const compound_svalue *compound_sval1 = (const compound_svalue *)sval1;
     671                 :          52 :         const compound_svalue *compound_sval2 = (const compound_svalue *)sval2;
     672                 :          52 :         return binding_map::cmp (compound_sval1->get_map (),
     673                 :          52 :                                  compound_sval2->get_map ());
     674                 :             :       }
     675                 :      189514 :       break;
     676                 :      189514 :     case SK_CONJURED:
     677                 :      189514 :       {
     678                 :      189514 :         const conjured_svalue *conjured_sval1 = (const conjured_svalue *)sval1;
     679                 :      189514 :         const conjured_svalue *conjured_sval2 = (const conjured_svalue *)sval2;
     680                 :      189514 :         if (int stmt_cmp = (conjured_sval1->get_stmt ()->uid
     681                 :      189514 :                             - conjured_sval2->get_stmt ()->uid))
     682                 :             :           return stmt_cmp;
     683                 :       51891 :         return region::cmp_ids (conjured_sval1->get_id_region (),
     684                 :      103782 :                                 conjured_sval2->get_id_region ());
     685                 :             :       }
     686                 :          24 :       break;
     687                 :          24 :     case SK_ASM_OUTPUT:
     688                 :          24 :       {
     689                 :          24 :         const asm_output_svalue *asm_output_sval1
     690                 :             :           = (const asm_output_svalue *)sval1;
     691                 :          24 :         const asm_output_svalue *asm_output_sval2
     692                 :             :           = (const asm_output_svalue *)sval2;
     693                 :          24 :         if (int asm_string_cmp = strcmp (asm_output_sval1->get_asm_string (),
     694                 :             :                                          asm_output_sval2->get_asm_string ()))
     695                 :             :           return asm_string_cmp;
     696                 :          24 :         if (int output_idx_cmp = ((int)asm_output_sval1->get_output_idx ()
     697                 :          24 :                                   - (int)asm_output_sval2->get_output_idx ()))
     698                 :             :           return output_idx_cmp;
     699                 :          24 :         if (int cmp = ((int)asm_output_sval1->get_num_inputs ()
     700                 :          24 :                        - (int)asm_output_sval2->get_num_inputs ()))
     701                 :             :           return cmp;
     702                 :          24 :         for (unsigned i = 0; i < asm_output_sval1->get_num_inputs (); i++)
     703                 :          24 :           if (int input_cmp
     704                 :          24 :               = svalue::cmp_ptr (asm_output_sval1->get_input (i),
     705                 :             :                                  asm_output_sval2->get_input (i)))
     706                 :             :             return input_cmp;
     707                 :             :         return 0;
     708                 :             :       }
     709                 :          80 :       break;
     710                 :          80 :     case SK_CONST_FN_RESULT:
     711                 :          80 :       {
     712                 :          80 :         const const_fn_result_svalue *const_fn_result_sval1
     713                 :             :           = (const const_fn_result_svalue *)sval1;
     714                 :          80 :         const const_fn_result_svalue *const_fn_result_sval2
     715                 :             :           = (const const_fn_result_svalue *)sval2;
     716                 :          80 :         int d1 = DECL_UID (const_fn_result_sval1->get_fndecl ());
     717                 :          80 :         int d2 = DECL_UID (const_fn_result_sval2->get_fndecl ());
     718                 :          80 :         if (int cmp_fndecl = d1 - d2)
     719                 :             :           return cmp_fndecl;
     720                 :          64 :         if (int cmp = ((int)const_fn_result_sval1->get_num_inputs ()
     721                 :          64 :                        - (int)const_fn_result_sval2->get_num_inputs ()))
     722                 :             :           return cmp;
     723                 :          48 :         for (unsigned i = 0; i < const_fn_result_sval1->get_num_inputs (); i++)
     724                 :          48 :           if (int input_cmp
     725                 :          48 :               = svalue::cmp_ptr (const_fn_result_sval1->get_input (i),
     726                 :             :                                  const_fn_result_sval2->get_input (i)))
     727                 :             :             return input_cmp;
     728                 :             :         return 0;
     729                 :             :       }
     730                 :             :     }
     731                 :             : }
     732                 :             : 
     733                 :             : /* Comparator for use by vec<const svalue *>::qsort.  */
     734                 :             : 
     735                 :             : int
     736                 :     2017283 : svalue::cmp_ptr_ptr (const void *p1, const void *p2)
     737                 :             : {
     738                 :     2017283 :   const svalue *sval1 = *(const svalue * const *)p1;
     739                 :     2017283 :   const svalue *sval2 = *(const svalue * const *)p2;
     740                 :     2017283 :   return cmp_ptr (sval1, sval2);
     741                 :             : }
     742                 :             : 
     743                 :             : /* Subclass of visitor for use in implementing svalue::involves_p.  */
     744                 :             : 
     745                 :             : class involvement_visitor : public visitor
     746                 :             : {
     747                 :             : public:
     748                 :      910856 :   involvement_visitor (const svalue *needle)
     749                 :      910856 :   : m_needle (needle), m_found (false) {}
     750                 :             : 
     751                 :      474299 :   void visit_initial_svalue (const initial_svalue *candidate) final override
     752                 :             :   {
     753                 :      474299 :     if (candidate == m_needle)
     754                 :          60 :       m_found = true;
     755                 :      474299 :   }
     756                 :             : 
     757                 :      339830 :   void visit_conjured_svalue (const conjured_svalue *candidate) final override
     758                 :             :   {
     759                 :      339830 :     if (candidate == m_needle)
     760                 :        6863 :       m_found = true;
     761                 :      339830 :   }
     762                 :             : 
     763                 :        8260 :   void visit_widening_svalue (const widening_svalue *candidate) final override
     764                 :             :   {
     765                 :        8260 :     if (candidate == m_needle)
     766                 :        1430 :       m_found = true;
     767                 :        8260 :   }
     768                 :             : 
     769                 :      910856 :   bool found_p () const { return m_found; }
     770                 :             : 
     771                 :             : private:
     772                 :             :   const svalue *m_needle;
     773                 :             :   bool m_found;
     774                 :             : };
     775                 :             : 
     776                 :             : /* Return true iff this svalue is defined in terms of OTHER.  */
     777                 :             : 
     778                 :             : bool
     779                 :      910856 : svalue::involves_p (const svalue *other) const
     780                 :             : {
     781                 :             :   /* Currently only implemented for these kinds.  */
     782                 :      910856 :   gcc_assert (other->get_kind () == SK_INITIAL
     783                 :             :               || other->get_kind () == SK_CONJURED
     784                 :             :               || other->get_kind () == SK_WIDENING);
     785                 :             : 
     786                 :      910856 :   involvement_visitor v (other);
     787                 :      910856 :   accept (&v);
     788                 :      910856 :   return v.found_p ();
     789                 :             : }
     790                 :             : 
     791                 :             : /* Extract SUBRANGE from this value, of type TYPE.  */
     792                 :             : 
     793                 :             : const svalue *
     794                 :       23811 : svalue::extract_bit_range (tree type,
     795                 :             :                            const bit_range &subrange,
     796                 :             :                            region_model_manager *mgr) const
     797                 :             : {
     798                 :       23811 :   return mgr->get_or_create_bits_within (type, subrange, this);
     799                 :             : }
     800                 :             : 
     801                 :             : /* Base implementation of svalue::maybe_fold_bits_within vfunc.  */
     802                 :             : 
     803                 :             : const svalue *
     804                 :        1442 : svalue::maybe_fold_bits_within (tree,
     805                 :             :                                 const bit_range &,
     806                 :             :                                 region_model_manager *) const
     807                 :             : {
     808                 :             :   /* By default, don't fold.  */
     809                 :        1442 :   return NULL;
     810                 :             : }
     811                 :             : 
     812                 :             : /* Base implementation of svalue::all_zeroes_p.
     813                 :             :    Return true if this value is known to be all zeroes.  */
     814                 :             : 
     815                 :             : bool
     816                 :       77935 : svalue::all_zeroes_p () const
     817                 :             : {
     818                 :       77935 :   return false;
     819                 :             : }
     820                 :             : 
     821                 :             : /* If this svalue is a pointer, attempt to determine the base region it points
     822                 :             :    to.  Return NULL on any problems.  */
     823                 :             : 
     824                 :             : const region *
     825                 :       23011 : svalue::maybe_get_deref_base_region () const
     826                 :             : {
     827                 :       23011 :   const svalue *iter = this;
     828                 :       23315 :   while (1)
     829                 :             :     {
     830                 :       23163 :       switch (iter->get_kind ())
     831                 :             :         {
     832                 :             :         default:
     833                 :             :           return NULL;
     834                 :             : 
     835                 :        9914 :         case SK_REGION:
     836                 :        9914 :           {
     837                 :        9914 :             const region_svalue *region_sval
     838                 :        9914 :               = as_a <const region_svalue *> (iter);
     839                 :        9914 :             return region_sval->get_pointee ()->get_base_region ();
     840                 :             :           }
     841                 :             : 
     842                 :         374 :         case SK_BINOP:
     843                 :         374 :           {
     844                 :         374 :             const binop_svalue *binop_sval
     845                 :         374 :               = as_a <const binop_svalue *> (iter);
     846                 :         374 :             switch (binop_sval->get_op ())
     847                 :             :               {
     848                 :         152 :               case POINTER_PLUS_EXPR:
     849                 :             :                 /* If we have a symbolic value expressing pointer arithmetic,
     850                 :             :                    use the LHS.  */
     851                 :         152 :                 iter = binop_sval->get_arg0 ();
     852                 :         152 :                 continue;
     853                 :             : 
     854                 :             :               default:
     855                 :             :                 return NULL;
     856                 :             :               }
     857                 :             :             return NULL;
     858                 :             :           }
     859                 :             :         }
     860                 :         152 :     }
     861                 :             : }
     862                 :             : 
     863                 :             : /* If this svalue is a pointer to the typeinfo instance for a particular
     864                 :             :    type, return that type.  Otherwise return NULL_TREE.  */
     865                 :             : 
     866                 :             : tree
     867                 :         633 : svalue::maybe_get_type_from_typeinfo () const
     868                 :             : {
     869                 :         633 :   if (const region *reg = maybe_get_region ())
     870                 :         447 :     if (const decl_region *decl_reg = reg->dyn_cast_decl_region ())
     871                 :         447 :       return TREE_TYPE (DECL_NAME (decl_reg->get_decl ()));
     872                 :             : 
     873                 :             :   return NULL_TREE;
     874                 :             : }
     875                 :             : 
     876                 :             : /* class region_svalue : public svalue.  */
     877                 :             : 
     878                 :             : /* Implementation of svalue::dump_to_pp vfunc for region_svalue.  */
     879                 :             : 
     880                 :             : void
     881                 :        7292 : region_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
     882                 :             : {
     883                 :        7292 :   if (simple)
     884                 :             :     {
     885                 :        6678 :       pp_string (pp, "&");
     886                 :        6678 :       m_reg->dump_to_pp (pp, simple);
     887                 :             :     }
     888                 :             :   else
     889                 :             :     {
     890                 :         614 :       pp_string (pp, "region_svalue(");
     891                 :         614 :       if (get_type ())
     892                 :             :         {
     893                 :         614 :           print_quoted_type (pp, get_type ());
     894                 :         614 :           pp_string (pp, ", ");
     895                 :             :         }
     896                 :         614 :       m_reg->dump_to_pp (pp, simple);
     897                 :         614 :       pp_string (pp, ")");
     898                 :             :     }
     899                 :        7292 : }
     900                 :             : 
     901                 :             : /* Implementation of svalue::print_dump_widget_label vfunc for
     902                 :             :    region_svalue.  */
     903                 :             : 
     904                 :             : void
     905                 :           0 : region_svalue::print_dump_widget_label (pretty_printer *pp) const
     906                 :             : {
     907                 :           0 :   pp_printf (pp, "region_svalue: %qs", "&");
     908                 :           0 : }
     909                 :             : 
     910                 :             : /* Implementation of svalue::add_dump_widget_children vfunc for
     911                 :             :    region_svalue.  */
     912                 :             : 
     913                 :             : void
     914                 :           0 : region_svalue::
     915                 :             : add_dump_widget_children (text_art::tree_widget &w,
     916                 :             :                           const text_art::dump_widget_info &dwi) const
     917                 :             : {
     918                 :           0 :   w.add_child (m_reg->make_dump_widget (dwi));
     919                 :           0 : }
     920                 :             : 
     921                 :             : /* Implementation of svalue::accept vfunc for region_svalue.  */
     922                 :             : 
     923                 :             : void
     924                 :      975489 : region_svalue::accept (visitor *v) const
     925                 :             : {
     926                 :      975489 :   m_reg->accept (v);
     927                 :      975489 :   v->visit_region_svalue (this);
     928                 :      975489 : }
     929                 :             : 
     930                 :             : /* Implementation of svalue::implicitly_live_p vfunc for region_svalue.  */
     931                 :             : 
     932                 :             : bool
     933                 :      144983 : region_svalue::implicitly_live_p (const svalue_set *,
     934                 :             :                                   const region_model *model) const
     935                 :             : {
     936                 :             :   /* Pointers into clusters that have escaped should be treated as live.  */
     937                 :      144983 :   const region *base_reg = get_pointee ()->get_base_region ();
     938                 :      144983 :   const store *store = model->get_store ();
     939                 :      144983 :   if (const binding_cluster *c = store->get_cluster (base_reg))
     940                 :      124624 :     if (c->escaped_p ())
     941                 :             :         return true;
     942                 :             : 
     943                 :             :   return false;
     944                 :             : }
     945                 :             : 
     946                 :             : /* Evaluate the condition LHS OP RHS.
     947                 :             :    Subroutine of region_model::eval_condition for when we have a pair of
     948                 :             :    pointers.  */
     949                 :             : 
     950                 :             : tristate
     951                 :         349 : region_svalue::eval_condition (const region_svalue *lhs,
     952                 :             :                                enum tree_code op,
     953                 :             :                                const region_svalue *rhs)
     954                 :             : {
     955                 :             :   /* See if they point to the same region.  */
     956                 :         349 :   const region *lhs_reg = lhs->get_pointee ();
     957                 :         349 :   const region *rhs_reg = rhs->get_pointee ();
     958                 :         349 :   bool ptr_equality = lhs_reg == rhs_reg;
     959                 :         349 :   switch (op)
     960                 :             :     {
     961                 :           0 :     default:
     962                 :           0 :       gcc_unreachable ();
     963                 :             : 
     964                 :          71 :     case EQ_EXPR:
     965                 :          71 :       if (ptr_equality)
     966                 :           0 :         return tristate::TS_TRUE;
     967                 :             :       else
     968                 :          71 :         return tristate::TS_FALSE;
     969                 :         270 :       break;
     970                 :             : 
     971                 :         270 :     case NE_EXPR:
     972                 :         270 :       if (ptr_equality)
     973                 :           0 :         return tristate::TS_FALSE;
     974                 :             :       else
     975                 :         270 :         return tristate::TS_TRUE;
     976                 :           4 :       break;
     977                 :             : 
     978                 :           4 :     case GE_EXPR:
     979                 :           4 :     case LE_EXPR:
     980                 :           4 :       if (ptr_equality)
     981                 :           0 :         return tristate::TS_TRUE;
     982                 :             :       break;
     983                 :             : 
     984                 :           4 :     case GT_EXPR:
     985                 :           4 :     case LT_EXPR:
     986                 :           4 :       if (ptr_equality)
     987                 :           0 :         return tristate::TS_FALSE;
     988                 :             :       break;
     989                 :             :     }
     990                 :             : 
     991                 :           8 :   return tristate::TS_UNKNOWN;
     992                 :             : }
     993                 :             : 
     994                 :             : /* class constant_svalue : public svalue.  */
     995                 :             : 
     996                 :             : /* Implementation of svalue::dump_to_pp vfunc for constant_svalue.  */
     997                 :             : 
     998                 :             : void
     999                 :       13096 : constant_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    1000                 :             : {
    1001                 :       13096 :   if (simple)
    1002                 :             :     {
    1003                 :       12444 :       pp_string (pp, "(");
    1004                 :       12444 :       dump_tree (pp, get_type ());
    1005                 :       12444 :       pp_string (pp, ")");
    1006                 :       12444 :       dump_tree (pp, m_cst_expr);
    1007                 :             :     }
    1008                 :             :   else
    1009                 :             :     {
    1010                 :         652 :       pp_string (pp, "constant_svalue(");
    1011                 :         652 :       if (get_type ())
    1012                 :             :         {
    1013                 :         652 :           print_quoted_type (pp, get_type ());
    1014                 :         652 :           pp_string (pp, ", ");
    1015                 :             :         }
    1016                 :         652 :       dump_tree (pp, m_cst_expr);
    1017                 :         652 :       pp_string (pp, ")");
    1018                 :             :     }
    1019                 :       13096 : }
    1020                 :             : 
    1021                 :             : /* Implementation of svalue::print_dump_widget_label vfunc for
    1022                 :             :    constant_svalue.  */
    1023                 :             : 
    1024                 :             : void
    1025                 :           0 : constant_svalue::print_dump_widget_label (pretty_printer *pp) const
    1026                 :             : {
    1027                 :           0 :   pp_printf (pp, "constant_svalue (%qE)", m_cst_expr);
    1028                 :           0 : }
    1029                 :             : 
    1030                 :             : /* Implementation of svalue::add_dump_widget_children vfunc for
    1031                 :             :    constant_svalue.  */
    1032                 :             : 
    1033                 :             : void
    1034                 :           0 : constant_svalue::
    1035                 :             : add_dump_widget_children (text_art::tree_widget &,
    1036                 :             :                           const text_art::dump_widget_info &) const
    1037                 :             : {
    1038                 :             :   /* No children.  */
    1039                 :           0 : }
    1040                 :             : 
    1041                 :             : /* Implementation of svalue::accept vfunc for constant_svalue.  */
    1042                 :             : 
    1043                 :             : void
    1044                 :     2428741 : constant_svalue::accept (visitor *v) const
    1045                 :             : {
    1046                 :     2428741 :   v->visit_constant_svalue (this);
    1047                 :     2428741 : }
    1048                 :             : 
    1049                 :             : /* Implementation of svalue::implicitly_live_p vfunc for constant_svalue.
    1050                 :             :    Constants are implicitly live.  */
    1051                 :             : 
    1052                 :             : bool
    1053                 :      331076 : constant_svalue::implicitly_live_p (const svalue_set *,
    1054                 :             :                                     const region_model *) const
    1055                 :             : {
    1056                 :      331076 :   return true;
    1057                 :             : }
    1058                 :             : 
    1059                 :             : /* Given EXPR, a non-NULL expression of boolean type, convert to
    1060                 :             :    a tristate based on whether this is known to be true, false,
    1061                 :             :    or is not known.  */
    1062                 :             : 
    1063                 :             : static tristate
    1064                 :       10317 : tristate_from_boolean_tree_node (tree expr)
    1065                 :             : {
    1066                 :       10317 :   gcc_assert (TREE_TYPE (expr) == boolean_type_node);
    1067                 :             : 
    1068                 :       10317 :   if (expr == boolean_true_node)
    1069                 :        6736 :     return tristate (tristate::TS_TRUE);
    1070                 :        3581 :   else if (expr == boolean_false_node)
    1071                 :        3581 :     return tristate (tristate::TS_FALSE);
    1072                 :             :   else
    1073                 :           0 :     return tristate (tristate::TS_UNKNOWN);
    1074                 :             : }
    1075                 :             : 
    1076                 :             : /* Evaluate the condition LHS OP RHS.
    1077                 :             :    Subroutine of region_model::eval_condition for when we have a pair of
    1078                 :             :    constants.  */
    1079                 :             : 
    1080                 :             : tristate
    1081                 :       10902 : constant_svalue::eval_condition (const constant_svalue *lhs,
    1082                 :             :                                  enum tree_code op,
    1083                 :             :                                  const constant_svalue *rhs)
    1084                 :             : {
    1085                 :       10902 :   tree lhs_const = lhs->get_constant ();
    1086                 :       10902 :   tree rhs_const = rhs->get_constant ();
    1087                 :             : 
    1088                 :       10902 :   gcc_assert (CONSTANT_CLASS_P (lhs_const));
    1089                 :       10902 :   gcc_assert (CONSTANT_CLASS_P (rhs_const));
    1090                 :             : 
    1091                 :       10902 :   if ((lhs->get_type () == NULL_TREE || rhs->get_type () == NULL_TREE)
    1092                 :         361 :       && TREE_CODE (lhs_const) == INTEGER_CST
    1093                 :       11263 :       && TREE_CODE (rhs_const) == INTEGER_CST
    1094                 :             :       )
    1095                 :             :     {
    1096                 :         361 :      if (tree tree_cmp = const_binop (op, boolean_type_node,
    1097                 :             :                                       lhs_const, rhs_const))
    1098                 :             :        {
    1099                 :         361 :          tristate ts = tristate_from_boolean_tree_node (tree_cmp);
    1100                 :         361 :          if (ts.is_known ())
    1101                 :         361 :            return ts;
    1102                 :             :        }
    1103                 :             :     }
    1104                 :             : 
    1105                 :             :   /* Check for comparable types.  */
    1106                 :       10541 :   if (types_compatible_p (TREE_TYPE (lhs_const), TREE_TYPE (rhs_const)))
    1107                 :             :     {
    1108                 :        9956 :       tree tree_cmp
    1109                 :        9956 :         = fold_binary (op, boolean_type_node, lhs_const, rhs_const);
    1110                 :        9956 :       tristate ts = tristate_from_boolean_tree_node (tree_cmp);
    1111                 :        9956 :       if (ts.is_known ())
    1112                 :        9956 :         return ts;
    1113                 :             :     }
    1114                 :         585 :   return tristate::TS_UNKNOWN;
    1115                 :             : }
    1116                 :             : 
    1117                 :             : /* Implementation of svalue::maybe_fold_bits_within vfunc
    1118                 :             :    for constant_svalue.  */
    1119                 :             : 
    1120                 :             : const svalue *
    1121                 :         433 : constant_svalue::maybe_fold_bits_within (tree type,
    1122                 :             :                                          const bit_range &bits,
    1123                 :             :                                          region_model_manager *mgr) const
    1124                 :             : {
    1125                 :             :   /* Bits within an all-zero value are also all zero.  */
    1126                 :         433 :   if (zerop (m_cst_expr))
    1127                 :             :     {
    1128                 :          93 :       if (type)
    1129                 :          92 :         return mgr->get_or_create_cast (type, this);
    1130                 :             :       else
    1131                 :           1 :         return this;
    1132                 :             :     }
    1133                 :             : 
    1134                 :             :   /* Handle the case of extracting a single bit. */
    1135                 :         480 :   if (bits.m_size_in_bits == 1
    1136                 :         203 :       && TREE_CODE (m_cst_expr) == INTEGER_CST
    1137                 :         203 :       && type
    1138                 :         203 :       && INTEGRAL_TYPE_P (type)
    1139                 :         543 :       && tree_fits_uhwi_p (m_cst_expr))
    1140                 :             :     {
    1141                 :         200 :       unsigned HOST_WIDE_INT bit = bits.m_start_bit_offset.to_uhwi ();
    1142                 :         200 :       unsigned HOST_WIDE_INT mask = (1 << bit);
    1143                 :         200 :       unsigned HOST_WIDE_INT val_as_hwi = tree_to_uhwi (m_cst_expr);
    1144                 :         200 :       unsigned HOST_WIDE_INT masked_val = val_as_hwi & mask;
    1145                 :         200 :       int result = masked_val ? 1 : 0;
    1146                 :         200 :       return mgr->get_or_create_int_cst (type, result);
    1147                 :             :     }
    1148                 :             : 
    1149                 :             :   /* Otherwise, don't fold.  */
    1150                 :             :   return NULL;
    1151                 :             : }
    1152                 :             : 
    1153                 :             : /* Implementation of svalue::all_zeroes_p for constant_svalue.  */
    1154                 :             : 
    1155                 :             : bool
    1156                 :       98852 : constant_svalue::all_zeroes_p () const
    1157                 :             : {
    1158                 :       98852 :   return zerop (m_cst_expr);
    1159                 :             : }
    1160                 :             : 
    1161                 :             : /* class unknown_svalue : public svalue.  */
    1162                 :             : 
    1163                 :             : /* Implementation of svalue::dump_to_pp vfunc for unknown_svalue.  */
    1164                 :             : 
    1165                 :             : void
    1166                 :        3270 : unknown_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    1167                 :             : {
    1168                 :        3270 :   if (simple)
    1169                 :             :     {
    1170                 :        2633 :       pp_string (pp, "UNKNOWN(");
    1171                 :        2633 :       if (get_type ())
    1172                 :        2632 :         dump_tree (pp, get_type ());
    1173                 :        2633 :       pp_character (pp, ')');
    1174                 :             :     }
    1175                 :             :   else
    1176                 :             :     {
    1177                 :         637 :       pp_string (pp, "unknown_svalue(");
    1178                 :         637 :       if (get_type ())
    1179                 :         637 :         dump_tree (pp, get_type ());
    1180                 :         637 :       pp_character (pp, ')');
    1181                 :             :     }
    1182                 :        3270 : }
    1183                 :             : 
    1184                 :             : /* Implementation of svalue::print_dump_widget_label vfunc for
    1185                 :             :    unknown_svalue.  */
    1186                 :             : 
    1187                 :             : void
    1188                 :           0 : unknown_svalue::print_dump_widget_label (pretty_printer *pp) const
    1189                 :             : {
    1190                 :           0 :   pp_printf (pp, "unknown_svalue");
    1191                 :           0 : }
    1192                 :             : 
    1193                 :             : /* Implementation of svalue::add_dump_widget_children vfunc for
    1194                 :             :    unknown_svalue.  */
    1195                 :             : 
    1196                 :             : void
    1197                 :           0 : unknown_svalue::
    1198                 :             : add_dump_widget_children (text_art::tree_widget &,
    1199                 :             :                           const text_art::dump_widget_info &) const
    1200                 :             : {
    1201                 :             :   /* No children.  */
    1202                 :           0 : }
    1203                 :             : 
    1204                 :             : /* Implementation of svalue::accept vfunc for unknown_svalue.  */
    1205                 :             : 
    1206                 :             : void
    1207                 :     2073335 : unknown_svalue::accept (visitor *v) const
    1208                 :             : {
    1209                 :     2073335 :   v->visit_unknown_svalue (this);
    1210                 :     2073335 : }
    1211                 :             : 
    1212                 :             : /* Implementation of svalue::maybe_fold_bits_within vfunc
    1213                 :             :    for unknown_svalue.  */
    1214                 :             : 
    1215                 :             : const svalue *
    1216                 :       12907 : unknown_svalue::maybe_fold_bits_within (tree type,
    1217                 :             :                                         const bit_range &,
    1218                 :             :                                         region_model_manager *mgr) const
    1219                 :             : {
    1220                 :             :   /* Bits within an unknown_svalue are themselves unknown.  */
    1221                 :       12907 :   return mgr->get_or_create_unknown_svalue (type);
    1222                 :             : }
    1223                 :             : 
    1224                 :             : /* Get a string for KIND for use in debug dumps.  */
    1225                 :             : 
    1226                 :             : const char *
    1227                 :           9 : poison_kind_to_str (enum poison_kind kind)
    1228                 :             : {
    1229                 :           9 :   switch (kind)
    1230                 :             :     {
    1231                 :           0 :     default:
    1232                 :           0 :       gcc_unreachable ();
    1233                 :             :     case poison_kind::uninit:
    1234                 :             :       return "uninit";
    1235                 :           0 :     case poison_kind::freed:
    1236                 :           0 :       return "freed";
    1237                 :           0 :     case poison_kind::deleted:
    1238                 :           0 :       return "deleted";
    1239                 :           0 :     case poison_kind::popped_stack:
    1240                 :           0 :       return "popped stack";
    1241                 :             :     }
    1242                 :             : }
    1243                 :             : 
    1244                 :             : /* class poisoned_svalue : public svalue.  */
    1245                 :             : 
    1246                 :             : /* Implementation of svalue::dump_to_pp vfunc for poisoned_svalue.  */
    1247                 :             : 
    1248                 :             : void
    1249                 :           1 : poisoned_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    1250                 :             : {
    1251                 :           1 :   if (simple)
    1252                 :             :     {
    1253                 :           1 :       pp_string (pp, "POISONED(");
    1254                 :           1 :       print_quoted_type (pp, get_type ());
    1255                 :           1 :       pp_printf (pp, ", %s)", poison_kind_to_str (m_kind));
    1256                 :             :     }
    1257                 :             :   else
    1258                 :             :     {
    1259                 :           0 :       pp_string (pp, "poisoned_svalue(");
    1260                 :           0 :       print_quoted_type (pp, get_type ());
    1261                 :           0 :       pp_printf (pp, ", %s)", poison_kind_to_str (m_kind));
    1262                 :             :     }
    1263                 :           1 : }
    1264                 :             : 
    1265                 :             : /* Implementation of svalue::print_dump_widget_label vfunc for
    1266                 :             :    poisoned_svalue.  */
    1267                 :             : 
    1268                 :             : void
    1269                 :           0 : poisoned_svalue::print_dump_widget_label (pretty_printer *pp) const
    1270                 :             : {
    1271                 :           0 :   pp_printf (pp, "poisoned_svalue(%s)", poison_kind_to_str (m_kind));
    1272                 :           0 : }
    1273                 :             : 
    1274                 :             : /* Implementation of svalue::add_dump_widget_children vfunc for
    1275                 :             :    poisoned_svalue.  */
    1276                 :             : 
    1277                 :             : void
    1278                 :           0 : poisoned_svalue::
    1279                 :             : add_dump_widget_children (text_art::tree_widget &,
    1280                 :             :                           const text_art::dump_widget_info &) const
    1281                 :             : {
    1282                 :             :   /* No children.  */
    1283                 :           0 : }
    1284                 :             : 
    1285                 :             : /* Implementation of svalue::accept vfunc for poisoned_svalue.  */
    1286                 :             : 
    1287                 :             : void
    1288                 :       15712 : poisoned_svalue::accept (visitor *v) const
    1289                 :             : {
    1290                 :       15712 :   v->visit_poisoned_svalue (this);
    1291                 :       15712 : }
    1292                 :             : 
    1293                 :             : /* Implementation of svalue::maybe_fold_bits_within vfunc
    1294                 :             :    for poisoned_svalue.  */
    1295                 :             : 
    1296                 :             : const svalue *
    1297                 :        6704 : poisoned_svalue::maybe_fold_bits_within (tree type,
    1298                 :             :                                          const bit_range &,
    1299                 :             :                                          region_model_manager *mgr) const
    1300                 :             : {
    1301                 :             :   /* Bits within a poisoned value are also poisoned.  */
    1302                 :        6704 :   return mgr->get_or_create_poisoned_svalue (m_kind, type);
    1303                 :             : }
    1304                 :             : 
    1305                 :             : /* class setjmp_svalue's implementation is in engine.cc, so that it can use
    1306                 :             :    the declaration of exploded_node.  */
    1307                 :             : 
    1308                 :             : /* class initial_svalue : public svalue.  */
    1309                 :             : 
    1310                 :             : /* Implementation of svalue::dump_to_pp vfunc for initial_svalue.  */
    1311                 :             : 
    1312                 :             : void
    1313                 :       10263 : initial_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    1314                 :             : {
    1315                 :       10263 :   if (simple)
    1316                 :             :     {
    1317                 :       10143 :       pp_string (pp, "INIT_VAL(");
    1318                 :       10143 :       m_reg->dump_to_pp (pp, simple);
    1319                 :       10143 :       pp_string (pp, ")");
    1320                 :             :     }
    1321                 :             :   else
    1322                 :             :     {
    1323                 :         120 :       pp_string (pp, "initial_svalue(");
    1324                 :         120 :       if (get_type ())
    1325                 :             :         {
    1326                 :         120 :           print_quoted_type (pp, get_type ());
    1327                 :         120 :           pp_string (pp, ", ");
    1328                 :             :         }
    1329                 :         120 :       m_reg->dump_to_pp (pp, simple);
    1330                 :         120 :       pp_string (pp, ")");
    1331                 :             :     }
    1332                 :       10263 : }
    1333                 :             : 
    1334                 :             : /* Implementation of svalue::print_dump_widget_label vfunc for
    1335                 :             :    initial_svalue.  */
    1336                 :             : 
    1337                 :             : void
    1338                 :           0 : initial_svalue::print_dump_widget_label (pretty_printer *pp) const
    1339                 :             : {
    1340                 :           0 :   pp_printf (pp, "initial_svalue");
    1341                 :           0 : }
    1342                 :             : 
    1343                 :             : /* Implementation of svalue::add_dump_widget_children vfunc for
    1344                 :             :    initial_svalue.  */
    1345                 :             : 
    1346                 :             : void
    1347                 :           0 : initial_svalue::
    1348                 :             : add_dump_widget_children (text_art::tree_widget &w,
    1349                 :             :                           const text_art::dump_widget_info &dwi) const
    1350                 :             : {
    1351                 :           0 :   w.add_child (m_reg->make_dump_widget (dwi, "m_reg"));
    1352                 :           0 : }
    1353                 :             : 
    1354                 :             : /* Implementation of svalue::accept vfunc for initial_svalue.  */
    1355                 :             : 
    1356                 :             : void
    1357                 :     2055702 : initial_svalue::accept (visitor *v) const
    1358                 :             : {
    1359                 :     2055702 :   m_reg->accept (v);
    1360                 :     2055702 :   v->visit_initial_svalue (this);
    1361                 :     2055702 : }
    1362                 :             : 
    1363                 :             : /* Implementation of svalue::implicitly_live_p vfunc for initial_svalue.  */
    1364                 :             : 
    1365                 :             : bool
    1366                 :     2391464 : initial_svalue::implicitly_live_p (const svalue_set *,
    1367                 :             :                                    const region_model *model) const
    1368                 :             : {
    1369                 :             :   /* This svalue may be implicitly live if the region still implicitly
    1370                 :             :      has its initial value and is reachable.  */
    1371                 :             : 
    1372                 :             :   /* It must be a region that exists; we don't want to consider
    1373                 :             :      INIT_VAL(R) as still being implicitly reachable if R is in
    1374                 :             :      a popped stack frame.  */
    1375                 :     2391464 :   if (model->region_exists_p (m_reg))
    1376                 :             :     {
    1377                 :     2375400 :       const svalue *reg_sval = model->get_store_value (m_reg, NULL);
    1378                 :     2375400 :       if (reg_sval == this)
    1379                 :             :         return true;
    1380                 :             :     }
    1381                 :             : 
    1382                 :             :   /* Assume that the initial values of params for the top level frame
    1383                 :             :      are still live, because (presumably) they're still
    1384                 :             :      live in the external caller.  */
    1385                 :      198228 :   if (initial_value_of_param_p ())
    1386                 :       15170 :     if (const frame_region *frame_reg = m_reg->maybe_get_frame_region ())
    1387                 :       15170 :       if (frame_reg->get_calling_frame () == NULL)
    1388                 :             :         return true;
    1389                 :             : 
    1390                 :             :   return false;
    1391                 :             : }
    1392                 :             : 
    1393                 :             : /* Return true if this is the initial value of a function parameter.  */
    1394                 :             : 
    1395                 :             : bool
    1396                 :      201686 : initial_svalue::initial_value_of_param_p () const
    1397                 :             : {
    1398                 :      201686 :   if (tree reg_decl = m_reg->maybe_get_decl ())
    1399                 :      109270 :     if (TREE_CODE (reg_decl) == SSA_NAME)
    1400                 :             :       {
    1401                 :       15223 :         tree ssa_name = reg_decl;
    1402                 :       15223 :         if (SSA_NAME_IS_DEFAULT_DEF (ssa_name)
    1403                 :       15223 :             && SSA_NAME_VAR (ssa_name)
    1404                 :       30446 :             && TREE_CODE (SSA_NAME_VAR (ssa_name)) == PARM_DECL)
    1405                 :       15202 :           return true;
    1406                 :             :       }
    1407                 :             :   return false;
    1408                 :             : }
    1409                 :             : 
    1410                 :             : /* class unaryop_svalue : public svalue.  */
    1411                 :             : 
    1412                 :             : /* Implementation of svalue::dump_to_pp vfunc for unaryop_svalue.  */
    1413                 :             : 
    1414                 :             : void
    1415                 :        3481 : unaryop_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    1416                 :             : {
    1417                 :        3481 :   if (simple)
    1418                 :             :     {
    1419                 :        3305 :       if (m_op == VIEW_CONVERT_EXPR || m_op == NOP_EXPR)
    1420                 :             :         {
    1421                 :        3297 :           pp_string (pp, "CAST(");
    1422                 :        3297 :           dump_tree (pp, get_type ());
    1423                 :        3297 :           pp_string (pp, ", ");
    1424                 :        3297 :           m_arg->dump_to_pp (pp, simple);
    1425                 :        3297 :           pp_character (pp, ')');
    1426                 :             :         }
    1427                 :             :       else
    1428                 :             :         {
    1429                 :           8 :           pp_character (pp, '(');
    1430                 :           8 :           pp_string (pp, get_tree_code_name (m_op));
    1431                 :             :           //pp_string (pp, op_symbol_code (m_op));
    1432                 :           8 :           m_arg->dump_to_pp (pp, simple);
    1433                 :           8 :           pp_character (pp, ')');
    1434                 :             :         }
    1435                 :             :     }
    1436                 :             :   else
    1437                 :             :     {
    1438                 :         176 :       pp_string (pp, "unaryop_svalue (");
    1439                 :         176 :       pp_string (pp, get_tree_code_name (m_op));
    1440                 :         176 :       pp_string (pp, ", ");
    1441                 :         176 :       m_arg->dump_to_pp (pp, simple);
    1442                 :         176 :       pp_character (pp, ')');
    1443                 :             :     }
    1444                 :        3481 : }
    1445                 :             : 
    1446                 :             : /* Implementation of svalue::print_dump_widget_label vfunc for
    1447                 :             :    unaryop_svalue.  */
    1448                 :             : 
    1449                 :             : void
    1450                 :           0 : unaryop_svalue::print_dump_widget_label (pretty_printer *pp) const
    1451                 :             : {
    1452                 :           0 :   pp_printf (pp,
    1453                 :             :              "unaryop_svalue(%s)",
    1454                 :           0 :              get_tree_code_name (m_op));
    1455                 :           0 : }
    1456                 :             : 
    1457                 :             : /* Implementation of svalue::add_dump_widget_children vfunc for
    1458                 :             :    unaryop_svalue.  */
    1459                 :             : 
    1460                 :             : void
    1461                 :           0 : unaryop_svalue::
    1462                 :             : add_dump_widget_children (text_art::tree_widget &w,
    1463                 :             :                           const text_art::dump_widget_info &dwi) const
    1464                 :             : {
    1465                 :           0 :   w.add_child (m_arg->make_dump_widget (dwi));
    1466                 :           0 : }
    1467                 :             : 
    1468                 :             : /* Implementation of svalue::accept vfunc for unaryop_svalue.  */
    1469                 :             : 
    1470                 :             : void
    1471                 :      689197 : unaryop_svalue::accept (visitor *v) const
    1472                 :             : {
    1473                 :      689197 :   m_arg->accept (v);
    1474                 :      689197 :   v->visit_unaryop_svalue (this);
    1475                 :      689197 : }
    1476                 :             : 
    1477                 :             : /* Implementation of svalue::implicitly_live_p vfunc for unaryop_svalue.  */
    1478                 :             : 
    1479                 :             : bool
    1480                 :      232742 : unaryop_svalue::implicitly_live_p (const svalue_set *live_svalues,
    1481                 :             :                                    const region_model *model) const
    1482                 :             : {
    1483                 :      232742 :   return get_arg ()->live_p (live_svalues, model);
    1484                 :             : }
    1485                 :             : 
    1486                 :             : /* Implementation of svalue::maybe_fold_bits_within vfunc
    1487                 :             :    for unaryop_svalue.  */
    1488                 :             : 
    1489                 :             : const svalue *
    1490                 :         946 : unaryop_svalue::maybe_fold_bits_within (tree type,
    1491                 :             :                                         const bit_range &,
    1492                 :             :                                         region_model_manager *mgr) const
    1493                 :             : {
    1494                 :         946 :   switch (m_op)
    1495                 :             :     {
    1496                 :             :     default:
    1497                 :             :       break;
    1498                 :         946 :     case NOP_EXPR:
    1499                 :             :       /* A cast of zero is zero.  */
    1500                 :         946 :       if (tree cst = m_arg->maybe_get_constant ())
    1501                 :         946 :         if (zerop (cst))
    1502                 :             :           {
    1503                 :         946 :             if (type)
    1504                 :         136 :               return mgr->get_or_create_cast (type, this);
    1505                 :             :             else
    1506                 :         810 :               return this;
    1507                 :             :           }
    1508                 :             :       break;
    1509                 :             :     }
    1510                 :             :   /* Otherwise, don't fold.  */
    1511                 :             :   return NULL;
    1512                 :             : }
    1513                 :             : 
    1514                 :             : /* class binop_svalue : public svalue.  */
    1515                 :             : 
    1516                 :             : /* Return whether OP be printed as an infix operator.  */
    1517                 :             : 
    1518                 :             : static bool
    1519                 :        6437 : infix_p (enum tree_code op)
    1520                 :             : {
    1521                 :           0 :   switch (op)
    1522                 :             :     {
    1523                 :             :     default:
    1524                 :             :       return true;
    1525                 :           2 :     case MAX_EXPR:
    1526                 :           2 :     case MIN_EXPR:
    1527                 :           0 :       return false;
    1528                 :             :     }
    1529                 :             : }
    1530                 :             : 
    1531                 :             : /* Implementation of svalue::dump_to_pp vfunc for binop_svalue.  */
    1532                 :             : 
    1533                 :             : void
    1534                 :        6887 : binop_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    1535                 :             : {
    1536                 :        6887 :   if (simple)
    1537                 :             :     {
    1538                 :        6437 :       if (infix_p (m_op))
    1539                 :             :         {
    1540                 :             :           /* Print "(A OP B)".  */
    1541                 :        6435 :           pp_character (pp, '(');
    1542                 :        6435 :           m_arg0->dump_to_pp (pp, simple);
    1543                 :        6435 :           pp_string (pp, op_symbol_code (m_op));
    1544                 :        6435 :           m_arg1->dump_to_pp (pp, simple);
    1545                 :        6435 :           pp_character (pp, ')');
    1546                 :             :         }
    1547                 :             :       else
    1548                 :             :         {
    1549                 :             :           /* Print "OP(A, B)".  */
    1550                 :           2 :           pp_string (pp, op_symbol_code (m_op));
    1551                 :           2 :           pp_character (pp, '(');
    1552                 :           2 :           m_arg0->dump_to_pp (pp, simple);
    1553                 :           2 :           pp_string (pp, ", ");
    1554                 :           2 :           m_arg1->dump_to_pp (pp, simple);
    1555                 :           2 :           pp_character (pp, ')');
    1556                 :             :         }
    1557                 :             :     }
    1558                 :             :   else
    1559                 :             :     {
    1560                 :         450 :       pp_string (pp, "binop_svalue (");
    1561                 :         450 :       pp_string (pp, get_tree_code_name (m_op));
    1562                 :         450 :       pp_string (pp, ", ");
    1563                 :         450 :       m_arg0->dump_to_pp (pp, simple);
    1564                 :         450 :       pp_string (pp, ", ");
    1565                 :         450 :       m_arg1->dump_to_pp (pp, simple);
    1566                 :         450 :       pp_character (pp, ')');
    1567                 :             :     }
    1568                 :        6887 : }
    1569                 :             : 
    1570                 :             : /* Implementation of svalue::print_dump_widget_label vfunc for
    1571                 :             :    binop_svalue.  */
    1572                 :             : 
    1573                 :             : void
    1574                 :           0 : binop_svalue::print_dump_widget_label (pretty_printer *pp) const
    1575                 :             : {
    1576                 :           0 :   pp_printf (pp,
    1577                 :             :              "binop_svalue(%s: %qs)",
    1578                 :           0 :              get_tree_code_name (m_op),
    1579                 :           0 :              op_symbol_code (m_op));
    1580                 :           0 : }
    1581                 :             : 
    1582                 :             : /* Implementation of svalue::add_dump_widget_children vfunc for
    1583                 :             :    binop_svalue.  */
    1584                 :             : 
    1585                 :             : void
    1586                 :           0 : binop_svalue::
    1587                 :             : add_dump_widget_children (text_art::tree_widget &w,
    1588                 :             :                           const text_art::dump_widget_info &dwi) const
    1589                 :             : {
    1590                 :           0 :   w.add_child (m_arg0->make_dump_widget (dwi));
    1591                 :           0 :   w.add_child (m_arg1->make_dump_widget (dwi));
    1592                 :           0 : }
    1593                 :             : 
    1594                 :             : /* Implementation of svalue::accept vfunc for binop_svalue.  */
    1595                 :             : 
    1596                 :             : void
    1597                 :     1125058 : binop_svalue::accept (visitor *v) const
    1598                 :             : {
    1599                 :     1125058 :   m_arg0->accept (v);
    1600                 :     1125058 :   m_arg1->accept (v);
    1601                 :     1125058 :   v->visit_binop_svalue (this);
    1602                 :     1125058 : }
    1603                 :             : 
    1604                 :             : /* Implementation of svalue::implicitly_live_p vfunc for binop_svalue.  */
    1605                 :             : 
    1606                 :             : bool
    1607                 :      523604 : binop_svalue::implicitly_live_p (const svalue_set *live_svalues,
    1608                 :             :                                  const region_model *model) const
    1609                 :             : {
    1610                 :      523604 :   return (get_arg0 ()->live_p (live_svalues, model)
    1611                 :      523604 :           && get_arg1 ()->live_p (live_svalues, model));
    1612                 :             : }
    1613                 :             : 
    1614                 :             : /* class sub_svalue : public svalue.  */
    1615                 :             : 
    1616                 :             : /* sub_svalue'c ctor.  */
    1617                 :             : 
    1618                 :        2481 : sub_svalue::sub_svalue (symbol::id_t id,
    1619                 :             :                         tree type, const svalue *parent_svalue,
    1620                 :        2481 :                         const region *subregion)
    1621                 :             : : svalue (complexity::from_pair (parent_svalue->get_complexity (),
    1622                 :             :                                  subregion->get_complexity ()),
    1623                 :             :           id,
    1624                 :             :           type),
    1625                 :        2481 :   m_parent_svalue (parent_svalue), m_subregion (subregion)
    1626                 :             : {
    1627                 :        2481 :   gcc_assert (parent_svalue->can_have_associated_state_p ());
    1628                 :        2481 : }
    1629                 :             : 
    1630                 :             : /* Implementation of svalue::dump_to_pp vfunc for sub_svalue.  */
    1631                 :             : 
    1632                 :             : void
    1633                 :        1328 : sub_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    1634                 :             : {
    1635                 :        1328 :   if (simple)
    1636                 :             :     {
    1637                 :        1284 :       pp_string (pp, "SUB(");
    1638                 :        1284 :       m_parent_svalue->dump_to_pp (pp, simple);
    1639                 :        1284 :       pp_string (pp, ", ");
    1640                 :        1284 :       m_subregion->dump_to_pp (pp, simple);
    1641                 :        1284 :       pp_character (pp, ')');
    1642                 :             :     }
    1643                 :             :   else
    1644                 :             :     {
    1645                 :          44 :       pp_string (pp, "sub_svalue (");
    1646                 :          44 :       pp_string (pp, ", ");
    1647                 :          44 :       m_parent_svalue->dump_to_pp (pp, simple);
    1648                 :          44 :       pp_string (pp, ", ");
    1649                 :          44 :       m_subregion->dump_to_pp (pp, simple);
    1650                 :          44 :       pp_character (pp, ')');
    1651                 :             :     }
    1652                 :        1328 : }
    1653                 :             : 
    1654                 :             : /* Implementation of svalue::print_dump_widget_label vfunc for
    1655                 :             :    sub_svalue.  */
    1656                 :             : 
    1657                 :             : void
    1658                 :           0 : sub_svalue::print_dump_widget_label (pretty_printer *pp) const
    1659                 :             : {
    1660                 :           0 :   pp_printf (pp, "sub_svalue");
    1661                 :           0 : }
    1662                 :             : 
    1663                 :             : /* Implementation of svalue::add_dump_widget_children vfunc for
    1664                 :             :    sub_svalue.  */
    1665                 :             : 
    1666                 :             : void
    1667                 :           0 : sub_svalue::
    1668                 :             : add_dump_widget_children (text_art::tree_widget &w,
    1669                 :             :                           const text_art::dump_widget_info &dwi) const
    1670                 :             : {
    1671                 :           0 :   w.add_child (m_parent_svalue->make_dump_widget (dwi, "m_parent_svalue"));
    1672                 :           0 :   w.add_child (m_subregion->make_dump_widget (dwi, "m_subregion"));
    1673                 :           0 : }
    1674                 :             : 
    1675                 :             : /* Implementation of svalue::accept vfunc for sub_svalue.  */
    1676                 :             : 
    1677                 :             : void
    1678                 :      289174 : sub_svalue::accept (visitor *v) const
    1679                 :             : {
    1680                 :      289174 :   m_parent_svalue->accept (v);
    1681                 :      289174 :   m_subregion->accept (v);
    1682                 :      289174 :   v->visit_sub_svalue (this);
    1683                 :      289174 : }
    1684                 :             : 
    1685                 :             : /* Implementation of svalue::implicitly_live_p vfunc for sub_svalue.  */
    1686                 :             : 
    1687                 :             : bool
    1688                 :       58560 : sub_svalue::implicitly_live_p (const svalue_set *live_svalues,
    1689                 :             :                                const region_model *model) const
    1690                 :             : {
    1691                 :       58560 :   return get_parent ()->live_p (live_svalues, model);
    1692                 :             : }
    1693                 :             : 
    1694                 :             : /* class repeated_svalue : public svalue.  */
    1695                 :             : 
    1696                 :             : /* repeated_svalue'c ctor.  */
    1697                 :             : 
    1698                 :         501 : repeated_svalue::repeated_svalue (symbol::id_t id,
    1699                 :             :                                   tree type,
    1700                 :             :                                   const svalue *outer_size,
    1701                 :         501 :                                   const svalue *inner_svalue)
    1702                 :         501 : : svalue (complexity::from_pair (outer_size, inner_svalue), id, type),
    1703                 :         501 :   m_outer_size (outer_size),
    1704                 :        1002 :   m_inner_svalue (inner_svalue)
    1705                 :             : {
    1706                 :         501 :   gcc_assert (outer_size->can_have_associated_state_p ());
    1707                 :         501 :   gcc_assert (inner_svalue->can_have_associated_state_p ());
    1708                 :         501 : }
    1709                 :             : 
    1710                 :             : /* Implementation of svalue::dump_to_pp vfunc for repeated_svalue.  */
    1711                 :             : 
    1712                 :             : void
    1713                 :           0 : repeated_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    1714                 :             : {
    1715                 :           0 :   if (simple)
    1716                 :             :     {
    1717                 :           0 :       pp_string (pp, "REPEATED(");
    1718                 :           0 :       if (get_type ())
    1719                 :             :         {
    1720                 :           0 :           print_quoted_type (pp, get_type ());
    1721                 :           0 :           pp_string (pp, ", ");
    1722                 :             :         }
    1723                 :           0 :       pp_string (pp, "outer_size: ");
    1724                 :           0 :       m_outer_size->dump_to_pp (pp, simple);
    1725                 :           0 :       pp_string (pp, ", inner_val: ");
    1726                 :           0 :       m_inner_svalue->dump_to_pp (pp, simple);
    1727                 :           0 :       pp_character (pp, ')');
    1728                 :             :     }
    1729                 :             :   else
    1730                 :             :     {
    1731                 :           0 :       pp_string (pp, "repeated_svalue (");
    1732                 :           0 :       if (get_type ())
    1733                 :             :         {
    1734                 :           0 :           print_quoted_type (pp, get_type ());
    1735                 :           0 :           pp_string (pp, ", ");
    1736                 :             :         }
    1737                 :           0 :       pp_string (pp, "outer_size: ");
    1738                 :           0 :       m_outer_size->dump_to_pp (pp, simple);
    1739                 :           0 :       pp_string (pp, ", inner_val: ");
    1740                 :           0 :       m_inner_svalue->dump_to_pp (pp, simple);
    1741                 :           0 :       pp_character (pp, ')');
    1742                 :             :     }
    1743                 :           0 : }
    1744                 :             : 
    1745                 :             : /* Implementation of svalue::print_dump_widget_label vfunc for
    1746                 :             :    repeated_svalue.  */
    1747                 :             : 
    1748                 :             : void
    1749                 :           0 : repeated_svalue::print_dump_widget_label (pretty_printer *pp) const
    1750                 :             : {
    1751                 :           0 :   pp_printf (pp, "repeated_svalue");
    1752                 :           0 : }
    1753                 :             : 
    1754                 :             : /* Implementation of svalue::add_dump_widget_children vfunc for
    1755                 :             :    repeated_svalue.  */
    1756                 :             : 
    1757                 :             : void
    1758                 :           0 : repeated_svalue::
    1759                 :             : add_dump_widget_children (text_art::tree_widget &w,
    1760                 :             :                           const text_art::dump_widget_info &dwi) const
    1761                 :             : {
    1762                 :           0 :   w.add_child (m_outer_size->make_dump_widget (dwi, "m_outer_size"));
    1763                 :           0 :   w.add_child (m_inner_svalue->make_dump_widget (dwi, "m_inner_svalue"));
    1764                 :           0 : }
    1765                 :             : 
    1766                 :             : /* Implementation of svalue::accept vfunc for repeated_svalue.  */
    1767                 :             : 
    1768                 :             : void
    1769                 :       65919 : repeated_svalue::accept (visitor *v) const
    1770                 :             : {
    1771                 :       65919 :   m_inner_svalue->accept (v);
    1772                 :       65919 :   v->visit_repeated_svalue (this);
    1773                 :       65919 : }
    1774                 :             : 
    1775                 :             : /* Implementation of svalue::all_zeroes_p for repeated_svalue.  */
    1776                 :             : 
    1777                 :             : bool
    1778                 :        2170 : repeated_svalue::all_zeroes_p () const
    1779                 :             : {
    1780                 :        2170 :   return m_inner_svalue->all_zeroes_p ();
    1781                 :             : }
    1782                 :             : 
    1783                 :             : /* Implementation of svalue::maybe_fold_bits_within vfunc
    1784                 :             :    for repeated_svalue.  */
    1785                 :             : 
    1786                 :             : const svalue *
    1787                 :        1872 : repeated_svalue::maybe_fold_bits_within (tree type,
    1788                 :             :                                          const bit_range &bits,
    1789                 :             :                                          region_model_manager *mgr) const
    1790                 :             : {
    1791                 :        1872 :   const svalue *innermost_sval = m_inner_svalue;
    1792                 :             :   /* Fold
    1793                 :             :        BITS_WITHIN (range, REPEATED_SVALUE (ZERO))
    1794                 :             :      to:
    1795                 :             :        REPEATED_SVALUE (ZERO).  */
    1796                 :        1872 :   if (all_zeroes_p ())
    1797                 :             :     {
    1798                 :        1564 :       byte_range bytes (0,0);
    1799                 :        1564 :       if (bits.as_byte_range (&bytes))
    1800                 :             :         {
    1801                 :        1564 :           const svalue *byte_size
    1802                 :        1564 :             = mgr->get_or_create_int_cst (size_type_node,
    1803                 :        1564 :                                           bytes.m_size_in_bytes.to_uhwi ());
    1804                 :        1564 :           return mgr->get_or_create_repeated_svalue (type, byte_size,
    1805                 :        1564 :                                                      innermost_sval);
    1806                 :             :         }
    1807                 :             :     }
    1808                 :             : 
    1809                 :             :   /* Fold:
    1810                 :             :        BITS_WITHIN (range, REPEATED_SVALUE (INNERMOST_SVALUE))
    1811                 :             :      to:
    1812                 :             :        BITS_WITHIN (range - offset, INNERMOST_SVALUE)
    1813                 :             :      if range is fully within one instance of INNERMOST_SVALUE.  */
    1814                 :         308 :   if (tree innermost_type = innermost_sval->get_type ())
    1815                 :             :     {
    1816                 :         308 :       bit_size_t element_bit_size;
    1817                 :         308 :       if (int_size_in_bits (innermost_type, &element_bit_size)
    1818                 :         308 :           && element_bit_size > 0)
    1819                 :             :         {
    1820                 :         308 :           HOST_WIDE_INT start_idx
    1821                 :         308 :             = (bits.get_start_bit_offset ()
    1822                 :         308 :                / element_bit_size).to_shwi ();
    1823                 :         308 :           HOST_WIDE_INT last_idx
    1824                 :         308 :             = (bits.get_last_bit_offset ()
    1825                 :         308 :                / element_bit_size).to_shwi ();
    1826                 :         308 :           if (start_idx == last_idx)
    1827                 :             :             {
    1828                 :         288 :               bit_offset_t start_of_element
    1829                 :         288 :                 = start_idx * element_bit_size;
    1830                 :         288 :               bit_range range_within_element
    1831                 :         288 :                 (bits.m_start_bit_offset - start_of_element,
    1832                 :         288 :                  bits.m_size_in_bits);
    1833                 :         288 :               return mgr->get_or_create_bits_within (type,
    1834                 :             :                                                      range_within_element,
    1835                 :             :                                                      innermost_sval);
    1836                 :             :             }
    1837                 :             :         }
    1838                 :             :     }
    1839                 :             : 
    1840                 :             :   return NULL;
    1841                 :             : }
    1842                 :             : 
    1843                 :             : /* class bits_within_svalue : public svalue.  */
    1844                 :             : 
    1845                 :             : /* bits_within_svalue'c ctor.  */
    1846                 :             : 
    1847                 :         673 : bits_within_svalue::bits_within_svalue (symbol::id_t id,
    1848                 :             :                                         tree type,
    1849                 :             :                                         const bit_range &bits,
    1850                 :         673 :                                         const svalue *inner_svalue)
    1851                 :         673 : : svalue (complexity (inner_svalue), id, type),
    1852                 :         673 :   m_bits (bits),
    1853                 :         673 :   m_inner_svalue (inner_svalue)
    1854                 :             : {
    1855                 :         673 :   gcc_assert (inner_svalue->can_have_associated_state_p ());
    1856                 :         673 : }
    1857                 :             : 
    1858                 :             : /* Implementation of svalue::dump_to_pp vfunc for bits_within_svalue.  */
    1859                 :             : 
    1860                 :             : void
    1861                 :         661 : bits_within_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    1862                 :             : {
    1863                 :         661 :   if (simple)
    1864                 :             :     {
    1865                 :         540 :       pp_string (pp, "BITS_WITHIN(");
    1866                 :         540 :       if (get_type ())
    1867                 :             :         {
    1868                 :           0 :           print_quoted_type (pp, get_type ());
    1869                 :           0 :           pp_string (pp, ", ");
    1870                 :             :         }
    1871                 :         540 :       m_bits.dump_to_pp (pp);
    1872                 :         540 :       pp_string (pp, ", inner_val: ");
    1873                 :         540 :       m_inner_svalue->dump_to_pp (pp, simple);
    1874                 :         540 :       pp_character (pp, ')');
    1875                 :             :     }
    1876                 :             :   else
    1877                 :             :     {
    1878                 :         121 :       pp_string (pp, "bits_within_svalue (");
    1879                 :         121 :       if (get_type ())
    1880                 :             :         {
    1881                 :           0 :           print_quoted_type (pp, get_type ());
    1882                 :           0 :           pp_string (pp, ", ");
    1883                 :             :         }
    1884                 :         121 :       m_bits.dump_to_pp (pp);
    1885                 :         121 :       pp_string (pp, ", inner_val: ");
    1886                 :         121 :       m_inner_svalue->dump_to_pp (pp, simple);
    1887                 :         121 :       pp_character (pp, ')');
    1888                 :             :     }
    1889                 :         661 : }
    1890                 :             : 
    1891                 :             : /* Implementation of svalue::print_dump_widget_label vfunc for
    1892                 :             :    bits_within_svalue.  */
    1893                 :             : 
    1894                 :             : void
    1895                 :           0 : bits_within_svalue::print_dump_widget_label (pretty_printer *pp) const
    1896                 :             : {
    1897                 :           0 :   pp_printf (pp, "bits_within_svalue: ");
    1898                 :           0 :   m_bits.dump_to_pp (pp);
    1899                 :           0 : }
    1900                 :             : 
    1901                 :             : /* Implementation of svalue::add_dump_widget_children vfunc for
    1902                 :             :    bits_within_svalue.  */
    1903                 :             : 
    1904                 :             : void
    1905                 :           0 : bits_within_svalue::
    1906                 :             : add_dump_widget_children (text_art::tree_widget &w,
    1907                 :             :                           const text_art::dump_widget_info &dwi) const
    1908                 :             : {
    1909                 :           0 :   w.add_child (m_inner_svalue->make_dump_widget (dwi, "m_inner_svalue"));
    1910                 :           0 : }
    1911                 :             : 
    1912                 :             : /* Implementation of svalue::maybe_fold_bits_within vfunc
    1913                 :             :    for bits_within_svalue.  */
    1914                 :             : 
    1915                 :             : const svalue *
    1916                 :         536 : bits_within_svalue::maybe_fold_bits_within (tree type,
    1917                 :             :                                             const bit_range &bits,
    1918                 :             :                                             region_model_manager *mgr) const
    1919                 :             : {
    1920                 :             :   /* Fold:
    1921                 :             :        BITS_WITHIN (range1, BITS_WITHIN (range2, VAL))
    1922                 :             :      to:
    1923                 :             :        BITS_WITHIN (range1 in range 2, VAL).  */
    1924                 :        1072 :   bit_range offset_bits (m_bits.get_start_bit_offset ()
    1925                 :         536 :                          + bits.m_start_bit_offset,
    1926                 :         536 :                          bits.m_size_in_bits);
    1927                 :         536 :   return mgr->get_or_create_bits_within (type, offset_bits, m_inner_svalue);
    1928                 :             : }
    1929                 :             : 
    1930                 :             : /* Implementation of svalue::accept vfunc for bits_within_svalue.  */
    1931                 :             : 
    1932                 :             : void
    1933                 :       21385 : bits_within_svalue::accept (visitor *v) const
    1934                 :             : {
    1935                 :       21385 :   m_inner_svalue->accept (v);
    1936                 :       21385 :   v->visit_bits_within_svalue (this);
    1937                 :       21385 : }
    1938                 :             : 
    1939                 :             : /* Implementation of svalue::implicitly_live_p vfunc for bits_within_svalue.  */
    1940                 :             : 
    1941                 :             : bool
    1942                 :         838 : bits_within_svalue::implicitly_live_p (const svalue_set *live_svalues,
    1943                 :             :                                        const region_model *model) const
    1944                 :             : {
    1945                 :         838 :   return m_inner_svalue->live_p (live_svalues, model);
    1946                 :             : }
    1947                 :             : 
    1948                 :             : /* class widening_svalue : public svalue.  */
    1949                 :             : 
    1950                 :             : /* Implementation of svalue::dump_to_pp vfunc for widening_svalue.  */
    1951                 :             : 
    1952                 :             : void
    1953                 :        2325 : widening_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    1954                 :             : {
    1955                 :        2325 :   if (simple)
    1956                 :             :     {
    1957                 :        2120 :       pp_string (pp, "WIDENING(");
    1958                 :        2120 :       pp_character (pp, '{');
    1959                 :        2120 :       m_point.print (pp, format (false));
    1960                 :        2120 :       pp_string (pp, "}, ");
    1961                 :        2120 :       m_base_sval->dump_to_pp (pp, simple);
    1962                 :        2120 :       pp_string (pp, ", ");
    1963                 :        2120 :       m_iter_sval->dump_to_pp (pp, simple);
    1964                 :        2120 :       pp_character (pp, ')');
    1965                 :             :     }
    1966                 :             :   else
    1967                 :             :     {
    1968                 :         205 :       pp_string (pp, "widening_svalue (");
    1969                 :         205 :       pp_string (pp, ", ");
    1970                 :         205 :       pp_character (pp, '{');
    1971                 :         205 :       m_point.print (pp, format (false));
    1972                 :         205 :       pp_string (pp, "}, ");
    1973                 :         205 :       m_base_sval->dump_to_pp (pp, simple);
    1974                 :         205 :       pp_string (pp, ", ");
    1975                 :         205 :       m_iter_sval->dump_to_pp (pp, simple);
    1976                 :         205 :       pp_character (pp, ')');
    1977                 :             :     }
    1978                 :        2325 : }
    1979                 :             : 
    1980                 :             : /* Implementation of svalue::print_dump_widget_label vfunc for
    1981                 :             :    widening_svalue.  */
    1982                 :             : 
    1983                 :             : void
    1984                 :           0 : widening_svalue::print_dump_widget_label (pretty_printer *pp) const
    1985                 :             : {
    1986                 :           0 :   pp_printf (pp, "widening_svalue at ");
    1987                 :           0 :   m_point.print (pp, format (false));
    1988                 :           0 : }
    1989                 :             : 
    1990                 :             : /* Implementation of svalue::add_dump_widget_children vfunc for
    1991                 :             :    widening_svalue.  */
    1992                 :             : 
    1993                 :             : void
    1994                 :           0 : widening_svalue::
    1995                 :             : add_dump_widget_children (text_art::tree_widget &w,
    1996                 :             :                           const text_art::dump_widget_info &dwi) const
    1997                 :             : {
    1998                 :           0 :   w.add_child (m_base_sval->make_dump_widget (dwi, "m_base_sval"));
    1999                 :           0 :   w.add_child (m_iter_sval->make_dump_widget (dwi, "m_iter_sval"));
    2000                 :           0 : }
    2001                 :             : 
    2002                 :             : /* Implementation of svalue::accept vfunc for widening_svalue.  */
    2003                 :             : 
    2004                 :             : void
    2005                 :      131141 : widening_svalue::accept (visitor *v) const
    2006                 :             : {
    2007                 :      131141 :   m_base_sval->accept (v);
    2008                 :      131141 :   m_iter_sval->accept (v);
    2009                 :      131141 :   v->visit_widening_svalue (this);
    2010                 :      131141 : }
    2011                 :             : 
    2012                 :             : /* Attempt to determine in which direction this value is changing
    2013                 :             :    w.r.t. the initial value.  */
    2014                 :             : 
    2015                 :             : enum widening_svalue::direction_t
    2016                 :        1932 : widening_svalue::get_direction () const
    2017                 :             : {
    2018                 :        1932 :   tree base_cst = m_base_sval->maybe_get_constant ();
    2019                 :        1932 :   if (base_cst == NULL_TREE)
    2020                 :             :     return DIR_UNKNOWN;
    2021                 :        1932 :   tree iter_cst = m_iter_sval->maybe_get_constant ();
    2022                 :        1932 :   if (iter_cst == NULL_TREE)
    2023                 :             :     return DIR_UNKNOWN;
    2024                 :             : 
    2025                 :        1932 :   tree iter_gt_base = fold_binary (GT_EXPR, boolean_type_node,
    2026                 :             :                                    iter_cst, base_cst);
    2027                 :        1932 :   if (iter_gt_base == boolean_true_node)
    2028                 :             :     return DIR_ASCENDING;
    2029                 :             : 
    2030                 :         485 :   tree iter_lt_base = fold_binary (LT_EXPR, boolean_type_node,
    2031                 :             :                                    iter_cst, base_cst);
    2032                 :         485 :   if (iter_lt_base == boolean_true_node)
    2033                 :             :     return DIR_DESCENDING;
    2034                 :             : 
    2035                 :             :   return DIR_UNKNOWN;
    2036                 :             : }
    2037                 :             : 
    2038                 :             : /* Compare this value against constant RHS_CST.  */
    2039                 :             : 
    2040                 :             : tristate
    2041                 :        3150 : widening_svalue::eval_condition_without_cm (enum tree_code op,
    2042                 :             :                                             tree rhs_cst) const
    2043                 :             : {
    2044                 :        3150 :   tree base_cst = m_base_sval->maybe_get_constant ();
    2045                 :        3150 :   if (base_cst == NULL_TREE)
    2046                 :        1226 :     return tristate::TS_UNKNOWN;
    2047                 :        1924 :   tree iter_cst = m_iter_sval->maybe_get_constant ();
    2048                 :        1924 :   if (iter_cst == NULL_TREE)
    2049                 :           0 :     return tristate::TS_UNKNOWN;
    2050                 :             : 
    2051                 :        1924 :   switch (get_direction ())
    2052                 :             :     {
    2053                 :           0 :     default:
    2054                 :           0 :       gcc_unreachable ();
    2055                 :        1439 :     case DIR_ASCENDING:
    2056                 :             :       /* LHS is in [base_cst, +ve infinity), assuming no overflow.  */
    2057                 :        1439 :       switch (op)
    2058                 :             :         {
    2059                 :         300 :         case LE_EXPR:
    2060                 :         300 :         case LT_EXPR:
    2061                 :         300 :           {
    2062                 :             :             /* [BASE, +INF) OP RHS:
    2063                 :             :                This is either true or false at +ve ininity,
    2064                 :             :                It can be true for points X where X OP RHS, so we have either
    2065                 :             :                "false", or "unknown".  */
    2066                 :         300 :             tree base_op_rhs = fold_binary (op, boolean_type_node,
    2067                 :             :                                             base_cst, rhs_cst);
    2068                 :         300 :             if (base_op_rhs == boolean_true_node)
    2069                 :         272 :               return tristate::TS_UNKNOWN;
    2070                 :             :             else
    2071                 :          28 :               return tristate::TS_FALSE;
    2072                 :             :           }
    2073                 :             : 
    2074                 :         801 :         case GE_EXPR:
    2075                 :         801 :         case GT_EXPR:
    2076                 :         801 :           {
    2077                 :             :             /* [BASE, +INF) OP RHS:
    2078                 :             :                This is true at +ve infinity.  It will be true everywhere
    2079                 :             :                in the range if BASE >= RHS.  */
    2080                 :         801 :             tree base_op_rhs = fold_binary (op, boolean_type_node,
    2081                 :             :                                             base_cst, rhs_cst);
    2082                 :         801 :             if (base_op_rhs == boolean_true_node)
    2083                 :          93 :               return tristate::TS_TRUE;
    2084                 :             :             else
    2085                 :         708 :               return tristate::TS_UNKNOWN;
    2086                 :             :           }
    2087                 :             : 
    2088                 :         167 :         case EQ_EXPR:
    2089                 :         167 :           {
    2090                 :             :             /* [BASE, +INF) == RHS:
    2091                 :             :                Could this be true at any point in the range?  If so we
    2092                 :             :                have "unknown", otherwise we have "false".  */
    2093                 :         167 :             tree base_le_rhs = fold_binary (LE_EXPR, boolean_type_node,
    2094                 :             :                                             base_cst, rhs_cst);
    2095                 :         167 :             if (base_le_rhs == boolean_true_node)
    2096                 :         159 :               return tristate::TS_UNKNOWN;
    2097                 :             :             else
    2098                 :           8 :               return tristate::TS_FALSE;
    2099                 :             :           }
    2100                 :             : 
    2101                 :         171 :         case NE_EXPR:
    2102                 :         171 :           {
    2103                 :             :             /* [BASE, +INF) != RHS:
    2104                 :             :                Could we have equality at any point in the range?  If so we
    2105                 :             :                have "unknown", otherwise we have "true".  */
    2106                 :         171 :             tree base_le_rhs = fold_binary (LE_EXPR, boolean_type_node,
    2107                 :             :                                             base_cst, rhs_cst);
    2108                 :         171 :             if (base_le_rhs == boolean_true_node)
    2109                 :         163 :               return tristate::TS_UNKNOWN;
    2110                 :             :             else
    2111                 :           8 :               return tristate::TS_TRUE;
    2112                 :             :           }
    2113                 :             : 
    2114                 :           0 :         default:
    2115                 :           0 :           return tristate::TS_UNKNOWN;
    2116                 :             :         }
    2117                 :             : 
    2118                 :         453 :     case DIR_DESCENDING:
    2119                 :             :       /* LHS is in (-ve infinity, base_cst], assuming no overflow.  */
    2120                 :         453 :       return tristate::TS_UNKNOWN;
    2121                 :             : 
    2122                 :          32 :     case DIR_UNKNOWN:
    2123                 :          32 :       return tristate::TS_UNKNOWN;
    2124                 :             :     }
    2125                 :             : }
    2126                 :             : 
    2127                 :             : /* class placeholder_svalue : public svalue.  */
    2128                 :             : 
    2129                 :             : /* Implementation of svalue::dump_to_pp vfunc for placeholder_svalue.  */
    2130                 :             : 
    2131                 :             : void
    2132                 :           0 : placeholder_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    2133                 :             : {
    2134                 :           0 :   if (simple)
    2135                 :           0 :     pp_printf (pp, "PLACEHOLDER(%qs)", m_name);
    2136                 :             :   else
    2137                 :           0 :     pp_printf (pp, "placeholder_svalue (%qs)", m_name);
    2138                 :           0 : }
    2139                 :             : 
    2140                 :             : /* Implementation of svalue::print_dump_widget_label vfunc for
    2141                 :             :    placeholder_svalue.  */
    2142                 :             : 
    2143                 :             : void
    2144                 :           0 : placeholder_svalue::print_dump_widget_label (pretty_printer *pp) const
    2145                 :             : {
    2146                 :           0 :   pp_printf (pp, "placeholder_svalue: %qs", m_name);
    2147                 :           0 : }
    2148                 :             : 
    2149                 :             : /* Implementation of svalue::add_dump_widget_children vfunc for
    2150                 :             :    placeholder_svalue.  */
    2151                 :             : 
    2152                 :             : void
    2153                 :           0 : placeholder_svalue::
    2154                 :             : add_dump_widget_children (text_art::tree_widget &,
    2155                 :             :                           const text_art::dump_widget_info &) const
    2156                 :             : {
    2157                 :             :   /* No children.  */
    2158                 :           0 : }
    2159                 :             : 
    2160                 :             : /* Implementation of svalue::accept vfunc for placeholder_svalue.  */
    2161                 :             : 
    2162                 :             : void
    2163                 :       55076 : placeholder_svalue::accept (visitor *v) const
    2164                 :             : {
    2165                 :       55076 :   v->visit_placeholder_svalue (this);
    2166                 :       55076 : }
    2167                 :             : 
    2168                 :             : /* class unmergeable_svalue : public svalue.  */
    2169                 :             : 
    2170                 :             : /* Implementation of svalue::dump_to_pp vfunc for unmergeable_svalue.  */
    2171                 :             : 
    2172                 :             : void
    2173                 :           0 : unmergeable_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    2174                 :             : {
    2175                 :           0 :   if (simple)
    2176                 :             :     {
    2177                 :           0 :       pp_string (pp, "UNMERGEABLE(");
    2178                 :           0 :       m_arg->dump_to_pp (pp, simple);
    2179                 :           0 :       pp_character (pp, ')');
    2180                 :             :     }
    2181                 :             :   else
    2182                 :             :     {
    2183                 :           0 :       pp_string (pp, "unmergeable_svalue (");
    2184                 :           0 :       m_arg->dump_to_pp (pp, simple);
    2185                 :           0 :       pp_character (pp, ')');
    2186                 :             :     }
    2187                 :           0 : }
    2188                 :             : 
    2189                 :             : /* Implementation of svalue::print_dump_widget_label vfunc for
    2190                 :             :    unmergeable_svalue.  */
    2191                 :             : 
    2192                 :             : void
    2193                 :           0 : unmergeable_svalue::print_dump_widget_label (pretty_printer *pp) const
    2194                 :             : {
    2195                 :           0 :   pp_printf (pp, "unmergeable_svalue");
    2196                 :           0 : }
    2197                 :             : 
    2198                 :             : /* Implementation of svalue::add_dump_widget_children vfunc for
    2199                 :             :    unmergeable_svalue.  */
    2200                 :             : 
    2201                 :             : void
    2202                 :           0 : unmergeable_svalue::
    2203                 :             : add_dump_widget_children (text_art::tree_widget &w,
    2204                 :             :                           const text_art::dump_widget_info &dwi) const
    2205                 :             : {
    2206                 :           0 :   w.add_child (m_arg->make_dump_widget (dwi));
    2207                 :           0 : }
    2208                 :             : 
    2209                 :             : /* Implementation of svalue::accept vfunc for unmergeable_svalue.  */
    2210                 :             : 
    2211                 :             : void
    2212                 :       10684 : unmergeable_svalue::accept (visitor *v) const
    2213                 :             : {
    2214                 :       10684 :   m_arg->accept (v);
    2215                 :       10684 :   v->visit_unmergeable_svalue (this);
    2216                 :       10684 : }
    2217                 :             : 
    2218                 :             : /* Implementation of svalue::implicitly_live_p vfunc for unmergeable_svalue.  */
    2219                 :             : 
    2220                 :             : bool
    2221                 :         951 : unmergeable_svalue::implicitly_live_p (const svalue_set *live_svalues,
    2222                 :             :                                        const region_model *model) const
    2223                 :             : {
    2224                 :         951 :   return get_arg ()->live_p (live_svalues, model);
    2225                 :             : }
    2226                 :             : 
    2227                 :             : /* class compound_svalue : public svalue.  */
    2228                 :             : 
    2229                 :         657 : compound_svalue::compound_svalue (symbol::id_t id,
    2230                 :             :                                   tree type,
    2231                 :         657 :                                   const binding_map &map)
    2232                 :         657 : : svalue (calc_complexity (map), id, type), m_map (map)
    2233                 :             : {
    2234                 :             : #if CHECKING_P
    2235                 :        4653 :   for (iterator_t iter = begin (); iter != end (); ++iter)
    2236                 :             :     {
    2237                 :             :       /* All keys within the underlying binding_map are required to be concrete,
    2238                 :             :          not symbolic.  */
    2239                 :        1998 :       const binding_key *key = (*iter).first;
    2240                 :        1998 :       gcc_assert (key->concrete_p ());
    2241                 :             : 
    2242                 :             :       /* We don't nest compound svalues.  */
    2243                 :        1998 :       const svalue *sval = (*iter).second;
    2244                 :        1998 :       gcc_assert (sval->get_kind () != SK_COMPOUND);
    2245                 :             :     }
    2246                 :             : #endif
    2247                 :         657 : }
    2248                 :             : 
    2249                 :             : /* Implementation of svalue::dump_to_pp vfunc for compound_svalue.  */
    2250                 :             : 
    2251                 :             : void
    2252                 :           0 : compound_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    2253                 :             : {
    2254                 :           0 :   if (simple)
    2255                 :             :     {
    2256                 :           0 :       pp_string (pp, "COMPOUND(");
    2257                 :           0 :       if (get_type ())
    2258                 :             :         {
    2259                 :           0 :           print_quoted_type (pp, get_type ());
    2260                 :           0 :           pp_string (pp, ", ");
    2261                 :             :         }
    2262                 :           0 :       pp_character (pp, '{');
    2263                 :           0 :       m_map.dump_to_pp (pp, simple, false);
    2264                 :           0 :       pp_string (pp, "})");
    2265                 :             :     }
    2266                 :             :   else
    2267                 :             :     {
    2268                 :           0 :       pp_string (pp, "compound_svalue (");
    2269                 :           0 :       if (get_type ())
    2270                 :             :         {
    2271                 :           0 :           print_quoted_type (pp, get_type ());
    2272                 :           0 :           pp_string (pp, ", ");
    2273                 :             :         }
    2274                 :           0 :       pp_character (pp, '{');
    2275                 :           0 :       m_map.dump_to_pp (pp, simple, false);
    2276                 :           0 :       pp_string (pp, "})");
    2277                 :             :     }
    2278                 :           0 : }
    2279                 :             : 
    2280                 :             : /* Implementation of svalue::print_dump_widget_label vfunc for
    2281                 :             :    compound_svalue.  */
    2282                 :             : 
    2283                 :             : void
    2284                 :           0 : compound_svalue::print_dump_widget_label (pretty_printer *pp) const
    2285                 :             : {
    2286                 :           0 :   pp_printf (pp, "compound_svalue");
    2287                 :           0 : }
    2288                 :             : 
    2289                 :             : /* Implementation of svalue::add_dump_widget_children vfunc for
    2290                 :             :    compound_svalue.  */
    2291                 :             : 
    2292                 :             : void
    2293                 :           0 : compound_svalue::
    2294                 :             : add_dump_widget_children (text_art::tree_widget &w,
    2295                 :             :                           const text_art::dump_widget_info &dwi) const
    2296                 :             : {
    2297                 :           0 :   m_map.add_to_tree_widget (w, dwi);
    2298                 :           0 : }
    2299                 :             : 
    2300                 :             : /* Implementation of svalue::accept vfunc for compound_svalue.  */
    2301                 :             : 
    2302                 :             : void
    2303                 :          42 : compound_svalue::accept (visitor *v) const
    2304                 :             : {
    2305                 :         126 :   for (binding_map::iterator_t iter = m_map.begin ();
    2306                 :         210 :        iter != m_map.end (); ++iter)
    2307                 :             :     {
    2308                 :             :       //(*iter).first.accept (v);
    2309                 :          84 :       (*iter).second->accept (v);
    2310                 :             :     }
    2311                 :          42 :   v->visit_compound_svalue (this);
    2312                 :          42 : }
    2313                 :             : 
    2314                 :             : /* Calculate what the complexity of a compound_svalue instance for MAP
    2315                 :             :    will be, based on the svalues bound within MAP.  */
    2316                 :             : 
    2317                 :             : complexity
    2318                 :         657 : compound_svalue::calc_complexity (const binding_map &map)
    2319                 :             : {
    2320                 :         657 :   unsigned num_child_nodes = 0;
    2321                 :         657 :   unsigned max_child_depth = 0;
    2322                 :         657 :   for (binding_map::iterator_t iter = map.begin ();
    2323                 :        2655 :        iter != map.end (); ++iter)
    2324                 :             :     {
    2325                 :        1998 :       const complexity &sval_c = (*iter).second->get_complexity ();
    2326                 :        1998 :       num_child_nodes += sval_c.m_num_nodes;
    2327                 :        1998 :       max_child_depth = MAX (max_child_depth, sval_c.m_max_depth);
    2328                 :             :     }
    2329                 :         657 :   return complexity (num_child_nodes + 1, max_child_depth + 1);
    2330                 :             : }
    2331                 :             : 
    2332                 :             : /* Implementation of svalue::maybe_fold_bits_within vfunc
    2333                 :             :    for compound_svalue.  */
    2334                 :             : 
    2335                 :             : const svalue *
    2336                 :          56 : compound_svalue::maybe_fold_bits_within (tree type,
    2337                 :             :                                          const bit_range &bits,
    2338                 :             :                                          region_model_manager *mgr) const
    2339                 :             : {
    2340                 :          56 :   binding_map result_map;
    2341                 :         456 :   for (auto iter : m_map)
    2342                 :             :     {
    2343                 :         200 :       const binding_key *key = iter.first;
    2344                 :         400 :       if (const concrete_binding *conc_key
    2345                 :         200 :           = key->dyn_cast_concrete_binding ())
    2346                 :             :         {
    2347                 :             :           /* Ignore concrete bindings outside BITS.  */
    2348                 :         200 :           if (!conc_key->get_bit_range ().intersects_p (bits))
    2349                 :          28 :             continue;
    2350                 :             : 
    2351                 :         172 :           const svalue *sval = iter.second;
    2352                 :             :           /* Get the position of conc_key relative to BITS.  */
    2353                 :         172 :           bit_range result_location (conc_key->get_start_bit_offset ()
    2354                 :         172 :                                      - bits.get_start_bit_offset (),
    2355                 :         172 :                                      conc_key->get_size_in_bits ());
    2356                 :             :           /* If conc_key starts after BITS, trim off leading bits
    2357                 :             :              from the svalue and adjust binding location.  */
    2358                 :         172 :           if (result_location.m_start_bit_offset < 0)
    2359                 :             :             {
    2360                 :           0 :               bit_size_t leading_bits_to_drop
    2361                 :           0 :                 = -result_location.m_start_bit_offset;
    2362                 :           0 :               result_location = bit_range
    2363                 :           0 :                 (0, result_location.m_size_in_bits - leading_bits_to_drop);
    2364                 :           0 :               bit_range bits_within_sval (leading_bits_to_drop,
    2365                 :           0 :                                           result_location.m_size_in_bits);
    2366                 :             :               /* Trim off leading bits from iter_sval.  */
    2367                 :           0 :               sval = mgr->get_or_create_bits_within (NULL_TREE,
    2368                 :             :                                                      bits_within_sval,
    2369                 :             :                                                      sval);
    2370                 :             :             }
    2371                 :             :           /* If conc_key finishes after BITS, trim off trailing bits
    2372                 :             :              from the svalue and adjust binding location.  */
    2373                 :         344 :           if (conc_key->get_next_bit_offset ()
    2374                 :         344 :               > bits.get_next_bit_offset ())
    2375                 :             :             {
    2376                 :          44 :               bit_size_t trailing_bits_to_drop
    2377                 :          44 :                 = (conc_key->get_next_bit_offset ()
    2378                 :          44 :                    - bits.get_next_bit_offset ());
    2379                 :          44 :               result_location = bit_range
    2380                 :             :                 (result_location.m_start_bit_offset,
    2381                 :          44 :                  result_location.m_size_in_bits - trailing_bits_to_drop);
    2382                 :          44 :               bit_range bits_within_sval (0,
    2383                 :          44 :                                           result_location.m_size_in_bits);
    2384                 :             :               /* Trim off leading bits from iter_sval.  */
    2385                 :          44 :               sval = mgr->get_or_create_bits_within (NULL_TREE,
    2386                 :             :                                                      bits_within_sval,
    2387                 :             :                                                      sval);
    2388                 :             :             }
    2389                 :         172 :           const concrete_binding *offset_conc_key
    2390                 :             :             = mgr->get_store_manager ()->get_concrete_binding
    2391                 :         172 :                 (result_location);
    2392                 :         172 :           result_map.put (offset_conc_key, sval);
    2393                 :             :         }
    2394                 :             :       else
    2395                 :             :         /* If we have any symbolic keys we can't get it as bits.  */
    2396                 :           0 :         return NULL;
    2397                 :             :     }
    2398                 :          56 :   return mgr->get_or_create_compound_svalue (type, result_map);
    2399                 :          56 : }
    2400                 :             : 
    2401                 :             : /* class conjured_svalue : public svalue.  */
    2402                 :             : 
    2403                 :             : /* Implementation of svalue::dump_to_pp vfunc for conjured_svalue.  */
    2404                 :             : 
    2405                 :             : void
    2406                 :        3447 : conjured_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    2407                 :             : {
    2408                 :        3447 :   if (simple)
    2409                 :             :     {
    2410                 :        3021 :       pp_string (pp, "CONJURED(");
    2411                 :        3021 :       pp_gimple_stmt_1 (pp, m_stmt, 0, (dump_flags_t)0);
    2412                 :        3021 :       pp_string (pp, ", ");
    2413                 :        3021 :       m_id_reg->dump_to_pp (pp, simple);
    2414                 :        3021 :       pp_character (pp, ')');
    2415                 :             :     }
    2416                 :             :   else
    2417                 :             :     {
    2418                 :         426 :       pp_string (pp, "conjured_svalue (");
    2419                 :         426 :       if (get_type ())
    2420                 :             :         {
    2421                 :         426 :           print_quoted_type (pp, get_type ());
    2422                 :         426 :           pp_string (pp, ", ");
    2423                 :             :         }
    2424                 :         426 :       pp_gimple_stmt_1 (pp, m_stmt, 0, (dump_flags_t)0);
    2425                 :         426 :       pp_string (pp, ", ");
    2426                 :         426 :       m_id_reg->dump_to_pp (pp, simple);
    2427                 :         426 :       pp_character (pp, ')');
    2428                 :             :     }
    2429                 :        3447 : }
    2430                 :             : 
    2431                 :             : /* Implementation of svalue::print_dump_widget_label vfunc for
    2432                 :             :    conjured_svalue.  */
    2433                 :             : 
    2434                 :             : void
    2435                 :           0 : conjured_svalue::print_dump_widget_label (pretty_printer *pp) const
    2436                 :             : {
    2437                 :           0 :   pp_printf (pp, "conjured_svalue (");
    2438                 :           0 :   pp_gimple_stmt_1 (pp, m_stmt, 0, (dump_flags_t)0);
    2439                 :           0 :   if (m_idx != 0)
    2440                 :           0 :     pp_printf (pp, ", %i", m_idx);
    2441                 :           0 :   pp_character (pp, ')');
    2442                 :           0 : }
    2443                 :             : 
    2444                 :             : /* Implementation of svalue::add_dump_widget_children vfunc for
    2445                 :             :    conjured_svalue.  */
    2446                 :             : 
    2447                 :             : void
    2448                 :           0 : conjured_svalue::
    2449                 :             : add_dump_widget_children (text_art::tree_widget &w,
    2450                 :             :                           const text_art::dump_widget_info &dwi) const
    2451                 :             : {
    2452                 :           0 :   w.add_child (m_id_reg->make_dump_widget (dwi));
    2453                 :           0 : }
    2454                 :             : 
    2455                 :             : /* Implementation of svalue::accept vfunc for conjured_svalue.  */
    2456                 :             : 
    2457                 :             : void
    2458                 :     1806948 : conjured_svalue::accept (visitor *v) const
    2459                 :             : {
    2460                 :     1806948 :   m_id_reg->accept (v);
    2461                 :     1806948 :   v->visit_conjured_svalue (this);
    2462                 :     1806948 : }
    2463                 :             : 
    2464                 :             : /* Return true iff this conjured_svalue is for the LHS of the
    2465                 :             :    stmt that conjured it.  */
    2466                 :             : 
    2467                 :             : bool
    2468                 :           0 : conjured_svalue::lhs_value_p () const
    2469                 :             : {
    2470                 :           0 :   if (tree decl = m_id_reg->maybe_get_decl ())
    2471                 :           0 :     return decl == gimple_get_lhs (m_stmt);
    2472                 :             :   return false;
    2473                 :             : }
    2474                 :             : 
    2475                 :             : /* class asm_output_svalue : public svalue.  */
    2476                 :             : 
    2477                 :             : /* Implementation of svalue::dump_to_pp vfunc for asm_output_svalue.  */
    2478                 :             : 
    2479                 :             : void
    2480                 :          76 : asm_output_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    2481                 :             : {
    2482                 :          76 :   if (simple)
    2483                 :             :     {
    2484                 :          76 :       pp_printf (pp, "ASM_OUTPUT(%qs, %%%i, {",
    2485                 :             :                  get_asm_string (),
    2486                 :             :                  get_output_idx ());
    2487                 :         216 :       for (unsigned i = 0; i < m_num_inputs; i++)
    2488                 :             :         {
    2489                 :         140 :           if (i > 0)
    2490                 :          64 :             pp_string (pp, ", ");
    2491                 :         140 :           dump_input (pp, 0, m_input_arr[i], simple);
    2492                 :             :         }
    2493                 :          76 :       pp_string (pp, "})");
    2494                 :             :     }
    2495                 :             :   else
    2496                 :             :     {
    2497                 :           0 :       pp_printf (pp, "asm_output_svalue (%qs, %%%i, {",
    2498                 :             :                  get_asm_string (),
    2499                 :             :                  get_output_idx ());
    2500                 :           0 :       for (unsigned i = 0; i < m_num_inputs; i++)
    2501                 :             :         {
    2502                 :           0 :           if (i > 0)
    2503                 :           0 :             pp_string (pp, ", ");
    2504                 :           0 :           dump_input (pp, 0, m_input_arr[i], simple);
    2505                 :             :         }
    2506                 :           0 :       pp_string (pp, "})");
    2507                 :             :     }
    2508                 :          76 : }
    2509                 :             : 
    2510                 :             : /* Implementation of svalue::print_dump_widget_label vfunc for
    2511                 :             :    asm_output_svalue.  */
    2512                 :             : 
    2513                 :             : void
    2514                 :           0 : asm_output_svalue::print_dump_widget_label (pretty_printer *pp) const
    2515                 :             : {
    2516                 :           0 :   pp_printf (pp, "asm_output_svalue(%qs, %%%i)",
    2517                 :             :              get_asm_string (),
    2518                 :             :              get_output_idx ());
    2519                 :           0 : }
    2520                 :             : 
    2521                 :             : /* Implementation of svalue::add_dump_widget_children vfunc for
    2522                 :             :    asm_output_svalue.  */
    2523                 :             : 
    2524                 :             : void
    2525                 :           0 : asm_output_svalue::
    2526                 :             : add_dump_widget_children (text_art::tree_widget &w,
    2527                 :             :                           const text_art::dump_widget_info &dwi) const
    2528                 :             : {
    2529                 :           0 :   for (unsigned i = 0; i < m_num_inputs; i++)
    2530                 :             :     {
    2531                 :           0 :       pretty_printer pp;
    2532                 :           0 :       pp_printf (&pp, "arg %i", i);
    2533                 :           0 :       w.add_child (m_input_arr[i]->make_dump_widget (dwi,
    2534                 :             :                                                      pp_formatted_text (&pp)));
    2535                 :           0 :     }
    2536                 :           0 : }
    2537                 :             : 
    2538                 :             : /* Subroutine of asm_output_svalue::dump_to_pp.  */
    2539                 :             : 
    2540                 :             : void
    2541                 :         140 : asm_output_svalue::dump_input (pretty_printer *pp,
    2542                 :             :                                unsigned input_idx,
    2543                 :             :                                const svalue *sval,
    2544                 :             :                                bool simple) const
    2545                 :             : {
    2546                 :         140 :   pp_printf (pp, "%%%i: ", input_idx_to_asm_idx (input_idx));
    2547                 :         140 :   sval->dump_to_pp (pp, simple);
    2548                 :         140 : }
    2549                 :             : 
    2550                 :             : /* Convert INPUT_IDX from an index into the array of inputs
    2551                 :             :    into the index of all operands for the asm stmt.  */
    2552                 :             : 
    2553                 :             : unsigned
    2554                 :         140 : asm_output_svalue::input_idx_to_asm_idx (unsigned input_idx) const
    2555                 :             : {
    2556                 :         140 :   return input_idx + m_num_outputs;
    2557                 :             : }
    2558                 :             : 
    2559                 :             : /* Implementation of svalue::accept vfunc for asm_output_svalue.  */
    2560                 :             : 
    2561                 :             : void
    2562                 :        6988 : asm_output_svalue::accept (visitor *v) const
    2563                 :             : {
    2564                 :       19067 :   for (unsigned i = 0; i < m_num_inputs; i++)
    2565                 :       12079 :     m_input_arr[i]->accept (v);
    2566                 :        6988 :   v->visit_asm_output_svalue (this);
    2567                 :        6988 : }
    2568                 :             : 
    2569                 :             : /* class const_fn_result_svalue : public svalue.  */
    2570                 :             : 
    2571                 :             : /* Implementation of svalue::dump_to_pp vfunc for const_fn_result_svalue.  */
    2572                 :             : 
    2573                 :             : void
    2574                 :        3332 : const_fn_result_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    2575                 :             : {
    2576                 :        3332 :   if (simple)
    2577                 :             :     {
    2578                 :        2889 :       pp_printf (pp, "CONST_FN_RESULT(%qD, {", m_fndecl);
    2579                 :        2889 :       for (unsigned i = 0; i < m_num_inputs; i++)
    2580                 :             :         {
    2581                 :           0 :           if (i > 0)
    2582                 :           0 :             pp_string (pp, ", ");
    2583                 :           0 :           dump_input (pp, i, m_input_arr[i], simple);
    2584                 :             :         }
    2585                 :        2889 :       pp_string (pp, "})");
    2586                 :             :     }
    2587                 :             :   else
    2588                 :             :     {
    2589                 :         443 :       pp_printf (pp, "CONST_FN_RESULT(%qD, {", m_fndecl);
    2590                 :         443 :       for (unsigned i = 0; i < m_num_inputs; i++)
    2591                 :             :         {
    2592                 :           0 :           if (i > 0)
    2593                 :           0 :             pp_string (pp, ", ");
    2594                 :           0 :           dump_input (pp, i, m_input_arr[i], simple);
    2595                 :             :         }
    2596                 :         443 :       pp_string (pp, "})");
    2597                 :             :     }
    2598                 :        3332 : }
    2599                 :             : 
    2600                 :             : /* Implementation of svalue::print_dump_widget_label vfunc for
    2601                 :             :    const_fn_result_svalue.  */
    2602                 :             : 
    2603                 :             : void
    2604                 :           0 : const_fn_result_svalue::print_dump_widget_label (pretty_printer *pp) const
    2605                 :             : {
    2606                 :           0 :   pp_printf (pp, "const_fn_result_svalue: %qD", m_fndecl);
    2607                 :           0 : }
    2608                 :             : 
    2609                 :             : /* Implementation of svalue::add_dump_widget_children vfunc for
    2610                 :             :    const_fn_result_svalue.  */
    2611                 :             : 
    2612                 :             : void
    2613                 :           0 : const_fn_result_svalue::
    2614                 :             : add_dump_widget_children (text_art::tree_widget &w,
    2615                 :             :                           const text_art::dump_widget_info &dwi) const
    2616                 :             : {
    2617                 :           0 :   for (unsigned i = 0; i < m_num_inputs; i++)
    2618                 :             :     {
    2619                 :           0 :       pretty_printer pp;
    2620                 :           0 :       pp_printf (&pp, "arg %i", i);
    2621                 :           0 :       w.add_child (m_input_arr[i]->make_dump_widget (dwi,
    2622                 :             :                                                      pp_formatted_text (&pp)));
    2623                 :           0 :     }
    2624                 :           0 : }
    2625                 :             : 
    2626                 :             : /* Subroutine of const_fn_result_svalue::dump_to_pp.  */
    2627                 :             : 
    2628                 :             : void
    2629                 :           0 : const_fn_result_svalue::dump_input (pretty_printer *pp,
    2630                 :             :                                     unsigned input_idx,
    2631                 :             :                                     const svalue *sval,
    2632                 :             :                                     bool simple) const
    2633                 :             : {
    2634                 :           0 :   pp_printf (pp, "arg%i: ", input_idx);
    2635                 :           0 :   sval->dump_to_pp (pp, simple);
    2636                 :           0 : }
    2637                 :             : 
    2638                 :             : /* Implementation of svalue::accept vfunc for const_fn_result_svalue.  */
    2639                 :             : 
    2640                 :             : void
    2641                 :       24562 : const_fn_result_svalue::accept (visitor *v) const
    2642                 :             : {
    2643                 :       45902 :   for (unsigned i = 0; i < m_num_inputs; i++)
    2644                 :       21340 :     m_input_arr[i]->accept (v);
    2645                 :       24562 :   v->visit_const_fn_result_svalue (this);
    2646                 :       24562 : }
    2647                 :             : 
    2648                 :             : } // namespace ana
    2649                 :             : 
    2650                 :             : #endif /* #if ENABLE_ANALYZER */
        

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