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