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