LCOV - code coverage report
Current view: top level - gcc/analyzer - svalue.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 73.0 % 1135 828
Test Date: 2025-03-15 13:07:15 Functions: 66.2 % 130 86
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

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