Home | History | Annotate | Line # | Download | only in analyzer
      1      1.1  mrg /* Tracking equivalence classes and constraints at a point on an execution path.
      2  1.1.1.2  mrg    Copyright (C) 2019-2022 Free Software Foundation, Inc.
      3      1.1  mrg    Contributed by David Malcolm <dmalcolm (at) redhat.com>.
      4      1.1  mrg 
      5      1.1  mrg This file is part of GCC.
      6      1.1  mrg 
      7      1.1  mrg GCC is free software; you can redistribute it and/or modify it
      8      1.1  mrg under the terms of the GNU General Public License as published by
      9      1.1  mrg the Free Software Foundation; either version 3, or (at your option)
     10      1.1  mrg any later version.
     11      1.1  mrg 
     12      1.1  mrg GCC is distributed in the hope that it will be useful, but
     13      1.1  mrg WITHOUT ANY WARRANTY; without even the implied warranty of
     14      1.1  mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15      1.1  mrg General Public License for more details.
     16      1.1  mrg 
     17      1.1  mrg You should have received a copy of the GNU General Public License
     18      1.1  mrg along with GCC; see the file COPYING3.  If not see
     19      1.1  mrg <http://www.gnu.org/licenses/>.  */
     20      1.1  mrg 
     21      1.1  mrg #include "config.h"
     22      1.1  mrg #include "system.h"
     23      1.1  mrg #include "coretypes.h"
     24      1.1  mrg #include "tree.h"
     25      1.1  mrg #include "function.h"
     26      1.1  mrg #include "basic-block.h"
     27      1.1  mrg #include "gimple.h"
     28      1.1  mrg #include "gimple-iterator.h"
     29      1.1  mrg #include "fold-const.h"
     30      1.1  mrg #include "selftest.h"
     31      1.1  mrg #include "diagnostic-core.h"
     32      1.1  mrg #include "graphviz.h"
     33      1.1  mrg #include "function.h"
     34  1.1.1.2  mrg #include "json.h"
     35      1.1  mrg #include "analyzer/analyzer.h"
     36      1.1  mrg #include "ordered-hash-map.h"
     37      1.1  mrg #include "options.h"
     38      1.1  mrg #include "cgraph.h"
     39      1.1  mrg #include "cfg.h"
     40      1.1  mrg #include "digraph.h"
     41      1.1  mrg #include "analyzer/supergraph.h"
     42      1.1  mrg #include "sbitmap.h"
     43      1.1  mrg #include "bitmap.h"
     44      1.1  mrg #include "tristate.h"
     45  1.1.1.2  mrg #include "analyzer/analyzer-logging.h"
     46  1.1.1.2  mrg #include "analyzer/call-string.h"
     47  1.1.1.2  mrg #include "analyzer/program-point.h"
     48  1.1.1.2  mrg #include "analyzer/store.h"
     49      1.1  mrg #include "analyzer/region-model.h"
     50      1.1  mrg #include "analyzer/constraint-manager.h"
     51      1.1  mrg #include "analyzer/analyzer-selftests.h"
     52  1.1.1.2  mrg #include "tree-pretty-print.h"
     53      1.1  mrg 
     54      1.1  mrg #if ENABLE_ANALYZER
     55      1.1  mrg 
     56      1.1  mrg namespace ana {
     57      1.1  mrg 
     58  1.1.1.2  mrg static tristate
     59  1.1.1.2  mrg compare_constants (tree lhs_const, enum tree_code op, tree rhs_const)
     60      1.1  mrg {
     61  1.1.1.2  mrg   tree comparison
     62  1.1.1.2  mrg     = fold_binary (op, boolean_type_node, lhs_const, rhs_const);
     63  1.1.1.2  mrg   if (comparison == boolean_true_node)
     64  1.1.1.2  mrg     return tristate (tristate::TS_TRUE);
     65  1.1.1.2  mrg   if (comparison == boolean_false_node)
     66  1.1.1.2  mrg     return tristate (tristate::TS_FALSE);
     67  1.1.1.2  mrg   return tristate (tristate::TS_UNKNOWN);
     68  1.1.1.2  mrg }
     69      1.1  mrg 
     70  1.1.1.2  mrg /* Return true iff CST is below the maximum value for its type.  */
     71      1.1  mrg 
     72  1.1.1.2  mrg static bool
     73  1.1.1.2  mrg can_plus_one_p (tree cst)
     74  1.1.1.2  mrg {
     75  1.1.1.2  mrg   gcc_assert (CONSTANT_CLASS_P (cst));
     76  1.1.1.2  mrg   return tree_int_cst_lt (cst, TYPE_MAX_VALUE (TREE_TYPE (cst)));
     77  1.1.1.2  mrg }
     78      1.1  mrg 
     79  1.1.1.2  mrg /* Return (CST + 1).  */
     80      1.1  mrg 
     81  1.1.1.2  mrg static tree
     82  1.1.1.2  mrg plus_one (tree cst)
     83      1.1  mrg {
     84  1.1.1.2  mrg   gcc_assert (CONSTANT_CLASS_P (cst));
     85  1.1.1.2  mrg   gcc_assert (can_plus_one_p (cst));
     86  1.1.1.2  mrg   tree result = fold_build2 (PLUS_EXPR, TREE_TYPE (cst),
     87  1.1.1.2  mrg 			     cst, integer_one_node);
     88  1.1.1.2  mrg   gcc_assert (CONSTANT_CLASS_P (result));
     89  1.1.1.2  mrg   return result;
     90  1.1.1.2  mrg }
     91      1.1  mrg 
     92  1.1.1.2  mrg /* Return true iff CST is above the minimum value for its type.  */
     93      1.1  mrg 
     94  1.1.1.2  mrg static bool
     95  1.1.1.2  mrg can_minus_one_p (tree cst)
     96  1.1.1.2  mrg {
     97  1.1.1.2  mrg   gcc_assert (CONSTANT_CLASS_P (cst));
     98  1.1.1.2  mrg   return tree_int_cst_lt (TYPE_MIN_VALUE (TREE_TYPE (cst)), cst);
     99  1.1.1.2  mrg }
    100      1.1  mrg 
    101  1.1.1.2  mrg /* Return (CST - 1).  */
    102  1.1.1.2  mrg 
    103  1.1.1.2  mrg static tree
    104  1.1.1.2  mrg minus_one (tree cst)
    105  1.1.1.2  mrg {
    106  1.1.1.2  mrg   gcc_assert (CONSTANT_CLASS_P (cst));
    107  1.1.1.2  mrg   gcc_assert (can_minus_one_p (cst));
    108  1.1.1.2  mrg   tree result = fold_build2 (MINUS_EXPR, TREE_TYPE (cst),
    109  1.1.1.2  mrg 			     cst, integer_one_node);
    110  1.1.1.2  mrg   gcc_assert (CONSTANT_CLASS_P (result));
    111  1.1.1.2  mrg   return result;
    112  1.1.1.2  mrg }
    113      1.1  mrg 
    114      1.1  mrg /* struct bound.  */
    115      1.1  mrg 
    116      1.1  mrg /* Ensure that this bound is closed by converting an open bound to a
    117      1.1  mrg    closed one.  */
    118      1.1  mrg 
    119      1.1  mrg void
    120  1.1.1.2  mrg bound::ensure_closed (enum bound_kind bound_kind)
    121      1.1  mrg {
    122      1.1  mrg   if (!m_closed)
    123      1.1  mrg     {
    124      1.1  mrg       /* Offset by 1 in the appropriate direction.
    125      1.1  mrg 	 For example, convert 3 < x into 4 <= x,
    126      1.1  mrg 	 and convert x < 5 into x <= 4.  */
    127      1.1  mrg       gcc_assert (CONSTANT_CLASS_P (m_constant));
    128  1.1.1.2  mrg       m_constant = fold_build2 (bound_kind == BK_UPPER ? MINUS_EXPR : PLUS_EXPR,
    129      1.1  mrg 				TREE_TYPE (m_constant),
    130      1.1  mrg 				m_constant, integer_one_node);
    131      1.1  mrg       gcc_assert (CONSTANT_CLASS_P (m_constant));
    132      1.1  mrg       m_closed = true;
    133      1.1  mrg     }
    134      1.1  mrg }
    135      1.1  mrg 
    136      1.1  mrg /* Get "<=" vs "<" for this bound.  */
    137      1.1  mrg 
    138      1.1  mrg const char *
    139      1.1  mrg bound::get_relation_as_str () const
    140      1.1  mrg {
    141      1.1  mrg   if (m_closed)
    142      1.1  mrg     return "<=";
    143      1.1  mrg   else
    144      1.1  mrg     return "<";
    145      1.1  mrg }
    146      1.1  mrg 
    147      1.1  mrg /* struct range.  */
    148      1.1  mrg 
    149      1.1  mrg /* Dump this range to PP, which must support %E for tree.  */
    150      1.1  mrg 
    151      1.1  mrg void
    152  1.1.1.2  mrg range::dump_to_pp (pretty_printer *pp) const
    153  1.1.1.2  mrg {
    154  1.1.1.2  mrg   if (m_lower_bound.m_constant)
    155  1.1.1.2  mrg     {
    156  1.1.1.2  mrg       if (m_upper_bound.m_constant)
    157  1.1.1.2  mrg 	pp_printf (pp, "%qE %s x %s %qE",
    158  1.1.1.2  mrg 		   m_lower_bound.m_constant,
    159  1.1.1.2  mrg 		   m_lower_bound.get_relation_as_str (),
    160  1.1.1.2  mrg 		   m_upper_bound.get_relation_as_str (),
    161  1.1.1.2  mrg 		   m_upper_bound.m_constant);
    162  1.1.1.2  mrg       else
    163  1.1.1.2  mrg 	pp_printf (pp, "%qE %s x",
    164  1.1.1.2  mrg 		   m_lower_bound.m_constant,
    165  1.1.1.2  mrg 		   m_lower_bound.get_relation_as_str ());
    166  1.1.1.2  mrg     }
    167  1.1.1.2  mrg   else
    168  1.1.1.2  mrg     {
    169  1.1.1.2  mrg       if (m_upper_bound.m_constant)
    170  1.1.1.2  mrg 	pp_printf (pp, "x %s %qE",
    171  1.1.1.2  mrg 		   m_upper_bound.get_relation_as_str (),
    172  1.1.1.2  mrg 		   m_upper_bound.m_constant);
    173  1.1.1.2  mrg       else
    174  1.1.1.2  mrg 	pp_string (pp, "x");
    175  1.1.1.2  mrg     }
    176  1.1.1.2  mrg }
    177  1.1.1.2  mrg 
    178  1.1.1.2  mrg /* Dump this range to stderr.  */
    179  1.1.1.2  mrg 
    180  1.1.1.2  mrg DEBUG_FUNCTION void
    181  1.1.1.2  mrg range::dump () const
    182      1.1  mrg {
    183  1.1.1.2  mrg   pretty_printer pp;
    184  1.1.1.2  mrg   pp_format_decoder (&pp) = default_tree_printer;
    185  1.1.1.2  mrg   pp_show_color (&pp) = pp_show_color (global_dc->printer);
    186  1.1.1.2  mrg   pp.buffer->stream = stderr;
    187  1.1.1.2  mrg   dump_to_pp (&pp);
    188  1.1.1.2  mrg   pp_newline (&pp);
    189  1.1.1.2  mrg   pp_flush (&pp);
    190      1.1  mrg }
    191      1.1  mrg 
    192      1.1  mrg /* Determine if there is only one possible value for this range.
    193  1.1.1.2  mrg    If so, return the constant; otherwise, return NULL_TREE.  */
    194      1.1  mrg 
    195  1.1.1.2  mrg tree
    196  1.1.1.2  mrg range::constrained_to_single_element ()
    197      1.1  mrg {
    198  1.1.1.2  mrg   if (m_lower_bound.m_constant == NULL_TREE
    199  1.1.1.2  mrg       || m_upper_bound.m_constant == NULL_TREE)
    200  1.1.1.2  mrg     return NULL_TREE;
    201  1.1.1.2  mrg 
    202      1.1  mrg   if (!INTEGRAL_TYPE_P (TREE_TYPE (m_lower_bound.m_constant)))
    203  1.1.1.2  mrg     return NULL_TREE;
    204      1.1  mrg   if (!INTEGRAL_TYPE_P (TREE_TYPE (m_upper_bound.m_constant)))
    205  1.1.1.2  mrg     return NULL_TREE;
    206      1.1  mrg 
    207      1.1  mrg   /* Convert any open bounds to closed bounds.  */
    208  1.1.1.2  mrg   m_lower_bound.ensure_closed (BK_LOWER);
    209  1.1.1.2  mrg   m_upper_bound.ensure_closed (BK_UPPER);
    210      1.1  mrg 
    211      1.1  mrg   // Are they equal?
    212      1.1  mrg   tree comparison = fold_binary (EQ_EXPR, boolean_type_node,
    213      1.1  mrg 				 m_lower_bound.m_constant,
    214      1.1  mrg 				 m_upper_bound.m_constant);
    215      1.1  mrg   if (comparison == boolean_true_node)
    216  1.1.1.2  mrg     return m_lower_bound.m_constant;
    217  1.1.1.2  mrg   else
    218  1.1.1.2  mrg     return NULL_TREE;
    219  1.1.1.2  mrg }
    220  1.1.1.2  mrg 
    221  1.1.1.2  mrg /* Eval the condition "X OP RHS_CONST" for X within the range.  */
    222  1.1.1.2  mrg 
    223  1.1.1.2  mrg tristate
    224  1.1.1.2  mrg range::eval_condition (enum tree_code op, tree rhs_const) const
    225  1.1.1.2  mrg {
    226  1.1.1.2  mrg   range copy (*this);
    227  1.1.1.2  mrg   if (tree single_element = copy.constrained_to_single_element ())
    228  1.1.1.2  mrg     return compare_constants (single_element, op, rhs_const);
    229  1.1.1.2  mrg 
    230  1.1.1.2  mrg   switch (op)
    231  1.1.1.2  mrg     {
    232  1.1.1.2  mrg     case EQ_EXPR:
    233  1.1.1.2  mrg       if (below_lower_bound (rhs_const))
    234  1.1.1.2  mrg 	return tristate (tristate::TS_FALSE);
    235  1.1.1.2  mrg       if (above_upper_bound (rhs_const))
    236  1.1.1.2  mrg 	return tristate (tristate::TS_FALSE);
    237  1.1.1.2  mrg       break;
    238  1.1.1.2  mrg 
    239  1.1.1.2  mrg     case LT_EXPR:
    240  1.1.1.2  mrg     case LE_EXPR:
    241  1.1.1.2  mrg       /* Qn: "X </<= RHS_CONST".  */
    242  1.1.1.2  mrg       /* If RHS_CONST > upper bound, then it's true.
    243  1.1.1.2  mrg 	 If RHS_CONST < lower bound, then it's false.
    244  1.1.1.2  mrg 	 Otherwise unknown.  */
    245  1.1.1.2  mrg       if (above_upper_bound (rhs_const))
    246  1.1.1.2  mrg 	return tristate (tristate::TS_TRUE);
    247  1.1.1.2  mrg       if (below_lower_bound (rhs_const))
    248  1.1.1.2  mrg 	return tristate (tristate::TS_FALSE);
    249  1.1.1.2  mrg       break;
    250  1.1.1.2  mrg 
    251  1.1.1.2  mrg     case NE_EXPR:
    252  1.1.1.2  mrg       /* Qn: "X != RHS_CONST".  */
    253  1.1.1.2  mrg       /* If RHS_CONST < lower bound, then it's true.
    254  1.1.1.2  mrg 	 If RHS_CONST > upper bound, then it's false.
    255  1.1.1.2  mrg 	 Otherwise unknown.  */
    256  1.1.1.2  mrg       if (below_lower_bound (rhs_const))
    257  1.1.1.2  mrg 	return tristate (tristate::TS_TRUE);
    258  1.1.1.2  mrg       if (above_upper_bound (rhs_const))
    259  1.1.1.2  mrg 	return tristate (tristate::TS_TRUE);
    260  1.1.1.2  mrg       break;
    261  1.1.1.2  mrg 
    262  1.1.1.2  mrg     case GE_EXPR:
    263  1.1.1.2  mrg     case GT_EXPR:
    264  1.1.1.2  mrg       /* Qn: "X >=/> RHS_CONST".  */
    265  1.1.1.2  mrg       if (above_upper_bound (rhs_const))
    266  1.1.1.2  mrg 	return tristate (tristate::TS_FALSE);
    267  1.1.1.2  mrg       if (below_lower_bound (rhs_const))
    268  1.1.1.2  mrg 	return tristate (tristate::TS_TRUE);
    269  1.1.1.2  mrg       break;
    270  1.1.1.2  mrg 
    271  1.1.1.2  mrg     default:
    272  1.1.1.2  mrg       gcc_unreachable ();
    273  1.1.1.2  mrg       break;
    274  1.1.1.2  mrg     }
    275  1.1.1.2  mrg   return tristate (tristate::TS_UNKNOWN);
    276  1.1.1.2  mrg }
    277  1.1.1.2  mrg 
    278  1.1.1.2  mrg /* Return true if RHS_CONST is below the lower bound of this range.  */
    279  1.1.1.2  mrg 
    280  1.1.1.2  mrg bool
    281  1.1.1.2  mrg range::below_lower_bound (tree rhs_const) const
    282  1.1.1.2  mrg {
    283  1.1.1.2  mrg   if (!m_lower_bound.m_constant)
    284  1.1.1.2  mrg     return false;
    285  1.1.1.2  mrg 
    286  1.1.1.2  mrg   return compare_constants (rhs_const,
    287  1.1.1.2  mrg 			    m_lower_bound.m_closed ? LT_EXPR : LE_EXPR,
    288  1.1.1.2  mrg 			    m_lower_bound.m_constant).is_true ();
    289  1.1.1.2  mrg }
    290  1.1.1.2  mrg 
    291  1.1.1.2  mrg /* Return true if RHS_CONST is above the upper bound of this range.  */
    292  1.1.1.2  mrg 
    293  1.1.1.2  mrg bool
    294  1.1.1.2  mrg range::above_upper_bound (tree rhs_const) const
    295  1.1.1.2  mrg {
    296  1.1.1.2  mrg   if (!m_upper_bound.m_constant)
    297  1.1.1.2  mrg     return false;
    298  1.1.1.2  mrg 
    299  1.1.1.2  mrg   return compare_constants (rhs_const,
    300  1.1.1.2  mrg 			    m_upper_bound.m_closed ? GT_EXPR : GE_EXPR,
    301  1.1.1.2  mrg 			    m_upper_bound.m_constant).is_true ();
    302  1.1.1.2  mrg }
    303  1.1.1.2  mrg 
    304  1.1.1.2  mrg /* Attempt to add B to the bound of the given kind of this range.
    305  1.1.1.2  mrg    Return true if feasible; false if infeasible.  */
    306  1.1.1.2  mrg 
    307  1.1.1.2  mrg bool
    308  1.1.1.2  mrg range::add_bound (bound b, enum bound_kind bound_kind)
    309  1.1.1.2  mrg {
    310  1.1.1.2  mrg   b.ensure_closed (bound_kind);
    311  1.1.1.2  mrg 
    312  1.1.1.2  mrg   switch (bound_kind)
    313  1.1.1.2  mrg     {
    314  1.1.1.2  mrg     default:
    315  1.1.1.2  mrg       gcc_unreachable ();
    316  1.1.1.2  mrg     case BK_LOWER:
    317  1.1.1.2  mrg       /* Discard redundant bounds.  */
    318  1.1.1.2  mrg       if (m_lower_bound.m_constant)
    319  1.1.1.2  mrg 	{
    320  1.1.1.2  mrg 	  m_lower_bound.ensure_closed (BK_LOWER);
    321  1.1.1.2  mrg 	  if (tree_int_cst_le (b.m_constant,
    322  1.1.1.2  mrg 			       m_lower_bound.m_constant))
    323  1.1.1.2  mrg 	    return true;
    324  1.1.1.2  mrg 	}
    325  1.1.1.2  mrg       if (m_upper_bound.m_constant)
    326  1.1.1.2  mrg 	{
    327  1.1.1.2  mrg 	  m_upper_bound.ensure_closed (BK_UPPER);
    328  1.1.1.2  mrg 	  /* Reject B <= V <= UPPER when B > UPPER.  */
    329  1.1.1.2  mrg 	  if (!tree_int_cst_le (b.m_constant,
    330  1.1.1.2  mrg 				m_upper_bound.m_constant))
    331  1.1.1.2  mrg 	    return false;
    332  1.1.1.2  mrg 	}
    333  1.1.1.2  mrg       m_lower_bound = b;
    334  1.1.1.2  mrg       break;
    335  1.1.1.2  mrg 
    336  1.1.1.2  mrg     case BK_UPPER:
    337  1.1.1.2  mrg       /* Discard redundant bounds.  */
    338  1.1.1.2  mrg       if (m_upper_bound.m_constant)
    339  1.1.1.2  mrg 	{
    340  1.1.1.2  mrg 	  m_upper_bound.ensure_closed (BK_UPPER);
    341  1.1.1.2  mrg 	  if (!tree_int_cst_lt (b.m_constant,
    342  1.1.1.2  mrg 				m_upper_bound.m_constant))
    343  1.1.1.2  mrg 	    return true;
    344  1.1.1.2  mrg 	}
    345  1.1.1.2  mrg       if (m_lower_bound.m_constant)
    346  1.1.1.2  mrg 	{
    347  1.1.1.2  mrg 	  m_lower_bound.ensure_closed (BK_LOWER);
    348  1.1.1.2  mrg 	  /* Reject LOWER <= V <= B when LOWER > B.  */
    349  1.1.1.2  mrg 	  if (!tree_int_cst_le (m_lower_bound.m_constant,
    350  1.1.1.2  mrg 				b.m_constant))
    351  1.1.1.2  mrg 	    return false;
    352  1.1.1.2  mrg 	}
    353  1.1.1.2  mrg       m_upper_bound = b;
    354  1.1.1.2  mrg       break;
    355  1.1.1.2  mrg     }
    356  1.1.1.2  mrg 
    357  1.1.1.2  mrg   return true;
    358  1.1.1.2  mrg }
    359  1.1.1.2  mrg 
    360  1.1.1.2  mrg /* Attempt to add (RANGE OP RHS_CONST) as a bound to this range.
    361  1.1.1.2  mrg    Return true if feasible; false if infeasible.  */
    362  1.1.1.2  mrg 
    363  1.1.1.2  mrg bool
    364  1.1.1.2  mrg range::add_bound (enum tree_code op, tree rhs_const)
    365  1.1.1.2  mrg {
    366  1.1.1.2  mrg   switch (op)
    367  1.1.1.2  mrg     {
    368  1.1.1.2  mrg     default:
    369  1.1.1.2  mrg       return true;
    370  1.1.1.2  mrg     case LT_EXPR:
    371  1.1.1.2  mrg       /* "V < RHS_CONST"  */
    372  1.1.1.2  mrg       return add_bound (bound (rhs_const, false), BK_UPPER);
    373  1.1.1.2  mrg     case LE_EXPR:
    374  1.1.1.2  mrg       /* "V <= RHS_CONST"  */
    375  1.1.1.2  mrg       return add_bound (bound (rhs_const, true), BK_UPPER);
    376  1.1.1.2  mrg     case GE_EXPR:
    377  1.1.1.2  mrg       /* "V >= RHS_CONST"  */
    378  1.1.1.2  mrg       return add_bound (bound (rhs_const, true), BK_LOWER);
    379  1.1.1.2  mrg     case GT_EXPR:
    380  1.1.1.2  mrg       /* "V > RHS_CONST"  */
    381  1.1.1.2  mrg       return add_bound (bound (rhs_const, false), BK_LOWER);
    382  1.1.1.2  mrg     }
    383  1.1.1.2  mrg }
    384  1.1.1.2  mrg 
    385  1.1.1.2  mrg /* struct bounded_range.  */
    386  1.1.1.2  mrg 
    387  1.1.1.2  mrg bounded_range::bounded_range (const_tree lower, const_tree upper)
    388  1.1.1.2  mrg : m_lower (const_cast<tree> (lower)),
    389  1.1.1.2  mrg   m_upper (const_cast<tree> (upper))
    390  1.1.1.2  mrg {
    391  1.1.1.2  mrg   if (lower && upper)
    392  1.1.1.2  mrg     {
    393  1.1.1.2  mrg       gcc_assert (TREE_CODE (m_lower) == INTEGER_CST);
    394  1.1.1.2  mrg       gcc_assert (TREE_CODE (m_upper) == INTEGER_CST);
    395  1.1.1.2  mrg       /* We should have lower <= upper.  */
    396  1.1.1.2  mrg       gcc_assert (!tree_int_cst_lt (m_upper, m_lower));
    397  1.1.1.2  mrg     }
    398  1.1.1.2  mrg   else
    399  1.1.1.2  mrg     {
    400  1.1.1.2  mrg       /* Purely for pending on-stack values, for
    401  1.1.1.2  mrg 	 writing back to.  */
    402  1.1.1.2  mrg       gcc_assert (m_lower == NULL_TREE);
    403  1.1.1.2  mrg       gcc_assert (m_lower == NULL_TREE);
    404  1.1.1.2  mrg     }
    405  1.1.1.2  mrg }
    406  1.1.1.2  mrg 
    407  1.1.1.2  mrg static void
    408  1.1.1.2  mrg dump_cst (pretty_printer *pp, tree cst, bool show_types)
    409  1.1.1.2  mrg {
    410  1.1.1.2  mrg   gcc_assert (cst);
    411  1.1.1.2  mrg   if (show_types)
    412  1.1.1.2  mrg     {
    413  1.1.1.2  mrg       pp_character (pp, '(');
    414  1.1.1.2  mrg       dump_generic_node (pp, TREE_TYPE (cst), 0, (dump_flags_t)0, false);
    415  1.1.1.2  mrg       pp_character (pp, ')');
    416  1.1.1.2  mrg     }
    417  1.1.1.2  mrg   dump_generic_node (pp, cst, 0, (dump_flags_t)0, false);
    418  1.1.1.2  mrg }
    419  1.1.1.2  mrg 
    420  1.1.1.2  mrg /* Dump this object to PP.  */
    421  1.1.1.2  mrg 
    422  1.1.1.2  mrg void
    423  1.1.1.2  mrg bounded_range::dump_to_pp (pretty_printer *pp, bool show_types) const
    424  1.1.1.2  mrg {
    425  1.1.1.2  mrg   if (tree_int_cst_equal (m_lower, m_upper))
    426  1.1.1.2  mrg     dump_cst (pp, m_lower, show_types);
    427  1.1.1.2  mrg   else
    428  1.1.1.2  mrg     {
    429  1.1.1.2  mrg       pp_character (pp, '[');
    430  1.1.1.2  mrg       dump_cst (pp, m_lower, show_types);
    431  1.1.1.2  mrg       pp_string (pp, ", ");
    432  1.1.1.2  mrg       dump_cst (pp, m_upper, show_types);
    433  1.1.1.2  mrg       pp_character (pp, ']');
    434  1.1.1.2  mrg     }
    435  1.1.1.2  mrg }
    436  1.1.1.2  mrg 
    437  1.1.1.2  mrg /* Dump this object to stderr.  */
    438  1.1.1.2  mrg 
    439  1.1.1.2  mrg void
    440  1.1.1.2  mrg bounded_range::dump (bool show_types) const
    441  1.1.1.2  mrg {
    442  1.1.1.2  mrg   pretty_printer pp;
    443  1.1.1.2  mrg   pp_format_decoder (&pp) = default_tree_printer;
    444  1.1.1.2  mrg   pp_show_color (&pp) = pp_show_color (global_dc->printer);
    445  1.1.1.2  mrg   pp.buffer->stream = stderr;
    446  1.1.1.2  mrg   dump_to_pp (&pp, show_types);
    447  1.1.1.2  mrg   pp_newline (&pp);
    448  1.1.1.2  mrg   pp_flush (&pp);
    449  1.1.1.2  mrg }
    450  1.1.1.2  mrg 
    451  1.1.1.2  mrg json::object *
    452  1.1.1.2  mrg bounded_range::to_json () const
    453  1.1.1.2  mrg {
    454  1.1.1.2  mrg   json::object *range_obj = new json::object ();
    455  1.1.1.2  mrg   set_json_attr (range_obj, "lower", m_lower);
    456  1.1.1.2  mrg   set_json_attr (range_obj, "upper", m_upper);
    457  1.1.1.2  mrg   return range_obj;
    458  1.1.1.2  mrg }
    459  1.1.1.2  mrg 
    460  1.1.1.2  mrg /* Subroutine of bounded_range::to_json.  */
    461  1.1.1.2  mrg 
    462  1.1.1.2  mrg void
    463  1.1.1.2  mrg bounded_range::set_json_attr (json::object *obj, const char *name, tree value)
    464  1.1.1.2  mrg {
    465  1.1.1.2  mrg   pretty_printer pp;
    466  1.1.1.2  mrg   pp_format_decoder (&pp) = default_tree_printer;
    467  1.1.1.2  mrg   pp_printf (&pp, "%E", value);
    468  1.1.1.2  mrg   obj->set (name, new json::string (pp_formatted_text (&pp)));
    469  1.1.1.2  mrg }
    470  1.1.1.2  mrg 
    471  1.1.1.2  mrg 
    472  1.1.1.2  mrg /* Return true iff CST is within this range.  */
    473  1.1.1.2  mrg 
    474  1.1.1.2  mrg bool
    475  1.1.1.2  mrg bounded_range::contains_p (tree cst) const
    476  1.1.1.2  mrg {
    477  1.1.1.2  mrg   /* Reject if below lower bound.  */
    478  1.1.1.2  mrg   if (tree_int_cst_lt (cst, m_lower))
    479  1.1.1.2  mrg     return false;
    480  1.1.1.2  mrg   /* Reject if above lower bound.  */
    481  1.1.1.2  mrg   if (tree_int_cst_lt (m_upper, cst))
    482  1.1.1.2  mrg     return false;
    483  1.1.1.2  mrg   return true;
    484  1.1.1.2  mrg }
    485  1.1.1.2  mrg 
    486  1.1.1.2  mrg /* If this range intersects OTHER, return true, writing
    487  1.1.1.2  mrg    the intersection to *OUT if OUT is non-NULL.
    488  1.1.1.2  mrg    Return false if they do not intersect.  */
    489  1.1.1.2  mrg 
    490  1.1.1.2  mrg bool
    491  1.1.1.2  mrg bounded_range::intersects_p (const bounded_range &other,
    492  1.1.1.2  mrg 			     bounded_range *out) const
    493  1.1.1.2  mrg {
    494  1.1.1.2  mrg   const tree max_lower
    495  1.1.1.2  mrg     = (tree_int_cst_le (m_lower, other.m_lower)
    496  1.1.1.2  mrg        ? other.m_lower : m_lower);
    497  1.1.1.2  mrg   gcc_assert (TREE_CODE (max_lower) == INTEGER_CST);
    498  1.1.1.2  mrg   const tree min_upper
    499  1.1.1.2  mrg     = (tree_int_cst_le (m_upper, other.m_upper)
    500  1.1.1.2  mrg        ? m_upper : other.m_upper);
    501  1.1.1.2  mrg   gcc_assert (TREE_CODE (min_upper) == INTEGER_CST);
    502  1.1.1.2  mrg 
    503  1.1.1.2  mrg   if (tree_int_cst_le (max_lower, min_upper))
    504  1.1.1.2  mrg     {
    505  1.1.1.2  mrg       if (out)
    506  1.1.1.2  mrg 	*out = bounded_range (max_lower, min_upper);
    507  1.1.1.2  mrg       return true;
    508  1.1.1.2  mrg     }
    509  1.1.1.2  mrg   else
    510  1.1.1.2  mrg     return false;
    511  1.1.1.2  mrg }
    512  1.1.1.2  mrg 
    513  1.1.1.2  mrg bool
    514  1.1.1.2  mrg bounded_range::operator== (const bounded_range &other) const
    515  1.1.1.2  mrg {
    516  1.1.1.2  mrg   return (TREE_TYPE (m_lower) == TREE_TYPE (other.m_lower)
    517  1.1.1.2  mrg 	  && TREE_TYPE (m_upper) == TREE_TYPE (other.m_upper)
    518  1.1.1.2  mrg 	  && tree_int_cst_equal (m_lower, other.m_lower)
    519  1.1.1.2  mrg 	  && tree_int_cst_equal (m_upper, other.m_upper));
    520  1.1.1.2  mrg }
    521  1.1.1.2  mrg 
    522  1.1.1.2  mrg int
    523  1.1.1.2  mrg bounded_range::cmp (const bounded_range &br1, const bounded_range &br2)
    524  1.1.1.2  mrg {
    525  1.1.1.2  mrg   if (int cmp_lower = tree_int_cst_compare (br1.m_lower,
    526  1.1.1.2  mrg 					    br2.m_lower))
    527  1.1.1.2  mrg     return cmp_lower;
    528  1.1.1.2  mrg   return tree_int_cst_compare (br1.m_upper, br2.m_upper);
    529  1.1.1.2  mrg }
    530  1.1.1.2  mrg 
    531  1.1.1.2  mrg /* struct bounded_ranges.  */
    532  1.1.1.2  mrg 
    533  1.1.1.2  mrg /* Construct a bounded_ranges instance from a single range.  */
    534  1.1.1.2  mrg 
    535  1.1.1.2  mrg bounded_ranges::bounded_ranges (const bounded_range &range)
    536  1.1.1.2  mrg : m_ranges (1)
    537  1.1.1.2  mrg {
    538  1.1.1.2  mrg   m_ranges.quick_push (range);
    539  1.1.1.2  mrg   canonicalize ();
    540  1.1.1.2  mrg   validate ();
    541  1.1.1.2  mrg }
    542  1.1.1.2  mrg 
    543  1.1.1.2  mrg /* Construct a bounded_ranges instance from multiple ranges.  */
    544  1.1.1.2  mrg 
    545  1.1.1.2  mrg bounded_ranges::bounded_ranges (const vec<bounded_range> &ranges)
    546  1.1.1.2  mrg : m_ranges (ranges.length ())
    547  1.1.1.2  mrg {
    548  1.1.1.2  mrg   m_ranges.safe_splice (ranges);
    549  1.1.1.2  mrg   canonicalize ();
    550  1.1.1.2  mrg   validate ();
    551  1.1.1.2  mrg }
    552  1.1.1.2  mrg 
    553  1.1.1.2  mrg /* Construct a bounded_ranges instance for values of LHS for which
    554  1.1.1.2  mrg    (LHS OP RHS_CONST) is true (e.g. "(LHS > 3)".  */
    555  1.1.1.2  mrg 
    556  1.1.1.2  mrg bounded_ranges::bounded_ranges (enum tree_code op, tree rhs_const)
    557  1.1.1.2  mrg : m_ranges ()
    558  1.1.1.2  mrg {
    559  1.1.1.2  mrg   gcc_assert (TREE_CODE (rhs_const) == INTEGER_CST);
    560  1.1.1.2  mrg   tree type = TREE_TYPE (rhs_const);
    561  1.1.1.2  mrg   switch (op)
    562  1.1.1.2  mrg     {
    563  1.1.1.2  mrg     default:
    564  1.1.1.2  mrg       gcc_unreachable ();
    565  1.1.1.2  mrg     case EQ_EXPR:
    566  1.1.1.2  mrg       m_ranges.safe_push (bounded_range (rhs_const, rhs_const));
    567  1.1.1.2  mrg       break;
    568  1.1.1.2  mrg 
    569  1.1.1.2  mrg     case GE_EXPR:
    570  1.1.1.2  mrg       m_ranges.safe_push (bounded_range (rhs_const, TYPE_MAX_VALUE (type)));
    571  1.1.1.2  mrg       break;
    572  1.1.1.2  mrg 
    573  1.1.1.2  mrg     case LE_EXPR:
    574  1.1.1.2  mrg       m_ranges.safe_push (bounded_range (TYPE_MIN_VALUE (type), rhs_const));
    575  1.1.1.2  mrg       break;
    576  1.1.1.2  mrg 
    577  1.1.1.2  mrg     case NE_EXPR:
    578  1.1.1.2  mrg       if (tree_int_cst_lt (TYPE_MIN_VALUE (type), rhs_const))
    579  1.1.1.2  mrg 	m_ranges.safe_push (bounded_range (TYPE_MIN_VALUE (type),
    580  1.1.1.2  mrg 					   minus_one (rhs_const)));
    581  1.1.1.2  mrg       if (tree_int_cst_lt (rhs_const, TYPE_MAX_VALUE (type)))
    582  1.1.1.2  mrg 	m_ranges.safe_push (bounded_range (plus_one (rhs_const),
    583  1.1.1.2  mrg 					   TYPE_MAX_VALUE (type)));
    584  1.1.1.2  mrg       break;
    585  1.1.1.2  mrg     case GT_EXPR:
    586  1.1.1.2  mrg       if (tree_int_cst_lt (rhs_const, TYPE_MAX_VALUE (type)))
    587  1.1.1.2  mrg 	m_ranges.safe_push (bounded_range (plus_one (rhs_const),
    588  1.1.1.2  mrg 					   TYPE_MAX_VALUE (type)));
    589  1.1.1.2  mrg       break;
    590  1.1.1.2  mrg     case LT_EXPR:
    591  1.1.1.2  mrg       if (tree_int_cst_lt (TYPE_MIN_VALUE (type), rhs_const))
    592  1.1.1.2  mrg 	m_ranges.safe_push (bounded_range (TYPE_MIN_VALUE (type),
    593  1.1.1.2  mrg 					   minus_one (rhs_const)));
    594  1.1.1.2  mrg       break;
    595  1.1.1.2  mrg     }
    596  1.1.1.2  mrg   canonicalize ();
    597  1.1.1.2  mrg   validate ();
    598  1.1.1.2  mrg }
    599  1.1.1.2  mrg 
    600  1.1.1.2  mrg /* Subroutine of ctors for fixing up m_ranges.
    601  1.1.1.2  mrg    Also, initialize m_hash.  */
    602  1.1.1.2  mrg 
    603  1.1.1.2  mrg void
    604  1.1.1.2  mrg bounded_ranges::canonicalize ()
    605  1.1.1.2  mrg {
    606  1.1.1.2  mrg   /* Sort the ranges.  */
    607  1.1.1.2  mrg   m_ranges.qsort ([](const void *p1, const void *p2) -> int
    608  1.1.1.2  mrg 		  {
    609  1.1.1.2  mrg 		    const bounded_range &br1 = *(const bounded_range *)p1;
    610  1.1.1.2  mrg 		    const bounded_range &br2 = *(const bounded_range *)p2;
    611  1.1.1.2  mrg 		    return bounded_range::cmp (br1, br2);
    612  1.1.1.2  mrg 		  });
    613  1.1.1.2  mrg 
    614  1.1.1.2  mrg   /* Merge ranges that are touching or overlapping.  */
    615  1.1.1.2  mrg   for (unsigned i = 1; i < m_ranges.length (); )
    616  1.1.1.2  mrg     {
    617  1.1.1.2  mrg       bounded_range *prev = &m_ranges[i - 1];
    618  1.1.1.2  mrg       const bounded_range *next = &m_ranges[i];
    619  1.1.1.2  mrg       if (prev->intersects_p (*next, NULL)
    620  1.1.1.2  mrg 	  || (can_plus_one_p (prev->m_upper)
    621  1.1.1.2  mrg 	      && tree_int_cst_equal (plus_one (prev->m_upper),
    622  1.1.1.2  mrg 				     next->m_lower)))
    623  1.1.1.2  mrg 	{
    624  1.1.1.2  mrg 	  prev->m_upper = next->m_upper;
    625  1.1.1.2  mrg 	  m_ranges.ordered_remove (i);
    626  1.1.1.2  mrg 	}
    627  1.1.1.2  mrg       else
    628  1.1.1.2  mrg 	i++;
    629  1.1.1.2  mrg     }
    630  1.1.1.2  mrg 
    631  1.1.1.2  mrg   /* Initialize m_hash.  */
    632  1.1.1.2  mrg   inchash::hash hstate (0);
    633  1.1.1.2  mrg   for (const auto &iter : m_ranges)
    634  1.1.1.2  mrg     {
    635  1.1.1.2  mrg       inchash::add_expr (iter.m_lower, hstate);
    636  1.1.1.2  mrg       inchash::add_expr (iter.m_upper, hstate);
    637  1.1.1.2  mrg     }
    638  1.1.1.2  mrg   m_hash = hstate.end ();
    639  1.1.1.2  mrg }
    640  1.1.1.2  mrg 
    641  1.1.1.2  mrg /* Assert that this object is valid.  */
    642  1.1.1.2  mrg 
    643  1.1.1.2  mrg void
    644  1.1.1.2  mrg bounded_ranges::validate () const
    645  1.1.1.2  mrg {
    646  1.1.1.2  mrg   /* Skip this in a release build.  */
    647  1.1.1.2  mrg #if !CHECKING_P
    648  1.1.1.2  mrg   return;
    649  1.1.1.2  mrg #endif
    650  1.1.1.2  mrg 
    651  1.1.1.2  mrg   for (unsigned i = 1; i < m_ranges.length (); i++)
    652  1.1.1.2  mrg     {
    653  1.1.1.2  mrg       const bounded_range &prev = m_ranges[i - 1];
    654  1.1.1.2  mrg       const bounded_range &next = m_ranges[i];
    655  1.1.1.2  mrg 
    656  1.1.1.2  mrg       /* Give up if we somehow have incompatible different types.  */
    657  1.1.1.2  mrg       if (!types_compatible_p (TREE_TYPE (prev.m_upper),
    658  1.1.1.2  mrg 			       TREE_TYPE (next.m_lower)))
    659  1.1.1.2  mrg 	continue;
    660  1.1.1.2  mrg 
    661  1.1.1.2  mrg       /* Verify sorted.  */
    662  1.1.1.2  mrg       gcc_assert (tree_int_cst_lt (prev.m_upper, next.m_lower));
    663  1.1.1.2  mrg 
    664  1.1.1.2  mrg       gcc_assert (can_plus_one_p (prev.m_upper));
    665  1.1.1.2  mrg       /* otherwise there's no room for "next".  */
    666  1.1.1.2  mrg 
    667  1.1.1.2  mrg       /* Verify no ranges touch each other.  */
    668  1.1.1.2  mrg       gcc_assert (tree_int_cst_lt (plus_one (prev.m_upper), next.m_lower));
    669  1.1.1.2  mrg     }
    670  1.1.1.2  mrg }
    671  1.1.1.2  mrg 
    672  1.1.1.2  mrg /* bounded_ranges equality operator.  */
    673  1.1.1.2  mrg 
    674  1.1.1.2  mrg bool
    675  1.1.1.2  mrg bounded_ranges::operator== (const bounded_ranges &other) const
    676  1.1.1.2  mrg {
    677  1.1.1.2  mrg   if (m_ranges.length () != other.m_ranges.length ())
    678  1.1.1.2  mrg     return false;
    679  1.1.1.2  mrg   for (unsigned i = 0; i < m_ranges.length (); i++)
    680  1.1.1.2  mrg     {
    681  1.1.1.2  mrg       if (m_ranges[i] != other.m_ranges[i])
    682  1.1.1.2  mrg 	return false;
    683  1.1.1.2  mrg     }
    684  1.1.1.2  mrg   return true;
    685  1.1.1.2  mrg }
    686  1.1.1.2  mrg 
    687  1.1.1.2  mrg /* Dump this object to PP.  */
    688  1.1.1.2  mrg 
    689  1.1.1.2  mrg void
    690  1.1.1.2  mrg bounded_ranges::dump_to_pp (pretty_printer *pp, bool show_types) const
    691  1.1.1.2  mrg {
    692  1.1.1.2  mrg   pp_character (pp, '{');
    693  1.1.1.2  mrg   for (unsigned i = 0; i < m_ranges.length (); ++i)
    694  1.1.1.2  mrg     {
    695  1.1.1.2  mrg       if (i > 0)
    696  1.1.1.2  mrg 	pp_string (pp, ", ");
    697  1.1.1.2  mrg       m_ranges[i].dump_to_pp (pp, show_types);
    698  1.1.1.2  mrg     }
    699  1.1.1.2  mrg   pp_character (pp, '}');
    700  1.1.1.2  mrg }
    701  1.1.1.2  mrg 
    702  1.1.1.2  mrg /* Dump this object to stderr.  */
    703  1.1.1.2  mrg 
    704  1.1.1.2  mrg DEBUG_FUNCTION void
    705  1.1.1.2  mrg bounded_ranges::dump (bool show_types) const
    706  1.1.1.2  mrg {
    707  1.1.1.2  mrg   pretty_printer pp;
    708  1.1.1.2  mrg   pp_format_decoder (&pp) = default_tree_printer;
    709  1.1.1.2  mrg   pp_show_color (&pp) = pp_show_color (global_dc->printer);
    710  1.1.1.2  mrg   pp.buffer->stream = stderr;
    711  1.1.1.2  mrg   dump_to_pp (&pp, show_types);
    712  1.1.1.2  mrg   pp_newline (&pp);
    713  1.1.1.2  mrg   pp_flush (&pp);
    714  1.1.1.2  mrg }
    715  1.1.1.2  mrg 
    716  1.1.1.2  mrg json::value *
    717  1.1.1.2  mrg bounded_ranges::to_json () const
    718  1.1.1.2  mrg {
    719  1.1.1.2  mrg   json::array *arr_obj = new json::array ();
    720  1.1.1.2  mrg 
    721  1.1.1.2  mrg   for (unsigned i = 0; i < m_ranges.length (); ++i)
    722  1.1.1.2  mrg     arr_obj->append (m_ranges[i].to_json ());
    723  1.1.1.2  mrg 
    724  1.1.1.2  mrg   return arr_obj;
    725  1.1.1.2  mrg }
    726  1.1.1.2  mrg 
    727  1.1.1.2  mrg /* Determine whether (X OP RHS_CONST) is known to be true or false
    728  1.1.1.2  mrg    for all X in the ranges expressed by this object.  */
    729  1.1.1.2  mrg 
    730  1.1.1.2  mrg tristate
    731  1.1.1.2  mrg bounded_ranges::eval_condition (enum tree_code op,
    732  1.1.1.2  mrg 				tree rhs_const,
    733  1.1.1.2  mrg 				bounded_ranges_manager *mgr) const
    734  1.1.1.2  mrg {
    735  1.1.1.2  mrg   /* Convert (X OP RHS_CONST) to a bounded_ranges instance and find
    736  1.1.1.2  mrg      the intersection of that with this object.  */
    737  1.1.1.2  mrg   bounded_ranges other (op, rhs_const);
    738  1.1.1.2  mrg   const bounded_ranges *intersection
    739  1.1.1.2  mrg     = mgr->get_or_create_intersection (this, &other);
    740  1.1.1.2  mrg 
    741  1.1.1.2  mrg   if (intersection->m_ranges.length () > 0)
    742  1.1.1.2  mrg     {
    743  1.1.1.2  mrg       /* We can use pointer equality to check for equality,
    744  1.1.1.2  mrg 	 due to instance consolidation.  */
    745  1.1.1.2  mrg       if (intersection == this)
    746  1.1.1.2  mrg 	return tristate (tristate::TS_TRUE);
    747  1.1.1.2  mrg       else
    748  1.1.1.2  mrg 	return tristate (tristate::TS_UNKNOWN);
    749  1.1.1.2  mrg     }
    750  1.1.1.2  mrg   else
    751  1.1.1.2  mrg     /* No intersection.  */
    752  1.1.1.2  mrg     return tristate (tristate::TS_FALSE);
    753  1.1.1.2  mrg }
    754  1.1.1.2  mrg 
    755  1.1.1.2  mrg /* Return true if CST is within any of the ranges.  */
    756  1.1.1.2  mrg 
    757  1.1.1.2  mrg bool
    758  1.1.1.2  mrg bounded_ranges::contain_p (tree cst) const
    759  1.1.1.2  mrg {
    760  1.1.1.2  mrg   gcc_assert (TREE_CODE (cst) == INTEGER_CST);
    761  1.1.1.2  mrg   for (const auto &iter : m_ranges)
    762  1.1.1.2  mrg     {
    763  1.1.1.2  mrg       /* TODO: should we optimize this based on sorting?  */
    764  1.1.1.2  mrg       if (iter.contains_p (cst))
    765  1.1.1.2  mrg 	return true;
    766  1.1.1.2  mrg     }
    767  1.1.1.2  mrg   return false;
    768  1.1.1.2  mrg }
    769  1.1.1.2  mrg 
    770  1.1.1.2  mrg int
    771  1.1.1.2  mrg bounded_ranges::cmp (const bounded_ranges *a, const bounded_ranges *b)
    772  1.1.1.2  mrg {
    773  1.1.1.2  mrg   if (int cmp_length = ((int)a->m_ranges.length ()
    774  1.1.1.2  mrg 			- (int)b->m_ranges.length ()))
    775  1.1.1.2  mrg     return cmp_length;
    776  1.1.1.2  mrg   for (unsigned i = 0; i < a->m_ranges.length (); i++)
    777  1.1.1.2  mrg     {
    778  1.1.1.2  mrg       if (int cmp_range = bounded_range::cmp (a->m_ranges[i], b->m_ranges[i]))
    779  1.1.1.2  mrg 	return cmp_range;
    780  1.1.1.2  mrg     }
    781  1.1.1.2  mrg   /* They are equal.  They ought to have been consolidated, so we should
    782  1.1.1.2  mrg      have two pointers to the same object.  */
    783  1.1.1.2  mrg   gcc_assert (a == b);
    784  1.1.1.2  mrg   return 0;
    785  1.1.1.2  mrg }
    786  1.1.1.2  mrg 
    787  1.1.1.2  mrg /* class bounded_ranges_manager.  */
    788  1.1.1.2  mrg 
    789  1.1.1.2  mrg /* bounded_ranges_manager's dtor.  */
    790  1.1.1.2  mrg 
    791  1.1.1.2  mrg bounded_ranges_manager::~bounded_ranges_manager ()
    792  1.1.1.2  mrg {
    793  1.1.1.2  mrg   /* Delete the managed objects.  */
    794  1.1.1.2  mrg   for (const auto &iter : m_map)
    795  1.1.1.2  mrg     delete iter.second;
    796  1.1.1.2  mrg }
    797  1.1.1.2  mrg 
    798  1.1.1.2  mrg /* Get the bounded_ranges instance for the empty set,  creating it if
    799  1.1.1.2  mrg    necessary.  */
    800  1.1.1.2  mrg 
    801  1.1.1.2  mrg const bounded_ranges *
    802  1.1.1.2  mrg bounded_ranges_manager::get_or_create_empty ()
    803  1.1.1.2  mrg {
    804  1.1.1.2  mrg   auto_vec<bounded_range> empty_vec;
    805  1.1.1.2  mrg 
    806  1.1.1.2  mrg   return consolidate (new bounded_ranges (empty_vec));
    807  1.1.1.2  mrg }
    808  1.1.1.2  mrg 
    809  1.1.1.2  mrg /* Get the bounded_ranges instance for {CST}, creating it if necessary.  */
    810  1.1.1.2  mrg 
    811  1.1.1.2  mrg const bounded_ranges *
    812  1.1.1.2  mrg bounded_ranges_manager::get_or_create_point (const_tree cst)
    813  1.1.1.2  mrg {
    814  1.1.1.2  mrg   gcc_assert (TREE_CODE (cst) == INTEGER_CST);
    815  1.1.1.2  mrg 
    816  1.1.1.2  mrg   return get_or_create_range (cst, cst);
    817  1.1.1.2  mrg }
    818  1.1.1.2  mrg 
    819  1.1.1.2  mrg /* Get the bounded_ranges instance for {[LOWER_BOUND..UPPER_BOUND]},
    820  1.1.1.2  mrg    creating it if necessary.  */
    821  1.1.1.2  mrg 
    822  1.1.1.2  mrg const bounded_ranges *
    823  1.1.1.2  mrg bounded_ranges_manager::get_or_create_range (const_tree lower_bound,
    824  1.1.1.2  mrg 					     const_tree upper_bound)
    825  1.1.1.2  mrg {
    826  1.1.1.2  mrg   gcc_assert (TREE_CODE (lower_bound) == INTEGER_CST);
    827  1.1.1.2  mrg   gcc_assert (TREE_CODE (upper_bound) == INTEGER_CST);
    828  1.1.1.2  mrg 
    829  1.1.1.2  mrg   return consolidate
    830  1.1.1.2  mrg     (new bounded_ranges (bounded_range (lower_bound, upper_bound)));
    831  1.1.1.2  mrg }
    832  1.1.1.2  mrg 
    833  1.1.1.2  mrg /* Get the bounded_ranges instance for the union of OTHERS,
    834  1.1.1.2  mrg    creating it if necessary.  */
    835  1.1.1.2  mrg 
    836  1.1.1.2  mrg const bounded_ranges *
    837  1.1.1.2  mrg bounded_ranges_manager::
    838  1.1.1.2  mrg get_or_create_union (const vec <const bounded_ranges *> &others)
    839  1.1.1.2  mrg {
    840  1.1.1.2  mrg   auto_vec<bounded_range> ranges;
    841  1.1.1.2  mrg   for (const auto &r : others)
    842  1.1.1.2  mrg     ranges.safe_splice (r->m_ranges);
    843  1.1.1.2  mrg   return consolidate (new bounded_ranges (ranges));
    844  1.1.1.2  mrg }
    845  1.1.1.2  mrg 
    846  1.1.1.2  mrg /* Get the bounded_ranges instance for the intersection of A and B,
    847  1.1.1.2  mrg    creating it if necessary.  */
    848  1.1.1.2  mrg 
    849  1.1.1.2  mrg const bounded_ranges *
    850  1.1.1.2  mrg bounded_ranges_manager::get_or_create_intersection (const bounded_ranges *a,
    851  1.1.1.2  mrg 						    const bounded_ranges *b)
    852  1.1.1.2  mrg {
    853  1.1.1.2  mrg   auto_vec<bounded_range> ranges;
    854  1.1.1.2  mrg   unsigned a_idx = 0;
    855  1.1.1.2  mrg   unsigned b_idx = 0;
    856  1.1.1.2  mrg   while (a_idx < a->m_ranges.length ()
    857  1.1.1.2  mrg 	 && b_idx < b->m_ranges.length ())
    858  1.1.1.2  mrg     {
    859  1.1.1.2  mrg       const bounded_range &r_a = a->m_ranges[a_idx];
    860  1.1.1.2  mrg       const bounded_range &r_b = b->m_ranges[b_idx];
    861  1.1.1.2  mrg 
    862  1.1.1.2  mrg       bounded_range intersection (NULL_TREE, NULL_TREE);
    863  1.1.1.2  mrg       if (r_a.intersects_p (r_b, &intersection))
    864  1.1.1.2  mrg 	{
    865  1.1.1.2  mrg 	  ranges.safe_push (intersection);
    866  1.1.1.2  mrg 	}
    867  1.1.1.2  mrg       if (tree_int_cst_lt (r_a.m_lower, r_b.m_lower))
    868  1.1.1.2  mrg 	{
    869  1.1.1.2  mrg 	  a_idx++;
    870  1.1.1.2  mrg 	}
    871  1.1.1.2  mrg       else
    872  1.1.1.2  mrg 	{
    873  1.1.1.2  mrg 	  if (tree_int_cst_lt (r_a.m_upper, r_b.m_upper))
    874  1.1.1.2  mrg 	    a_idx++;
    875  1.1.1.2  mrg 	  else
    876  1.1.1.2  mrg 	    b_idx++;
    877  1.1.1.2  mrg 	}
    878  1.1.1.2  mrg     }
    879  1.1.1.2  mrg 
    880  1.1.1.2  mrg   return consolidate (new bounded_ranges (ranges));
    881  1.1.1.2  mrg }
    882  1.1.1.2  mrg 
    883  1.1.1.2  mrg /* Get the bounded_ranges instance for the inverse of OTHER relative
    884  1.1.1.2  mrg    to TYPE, creating it if necessary.
    885  1.1.1.2  mrg    This is for use when handling "default" in switch statements, where
    886  1.1.1.2  mrg    OTHER represents all the other cases.  */
    887  1.1.1.2  mrg 
    888  1.1.1.2  mrg const bounded_ranges *
    889  1.1.1.2  mrg bounded_ranges_manager::get_or_create_inverse (const bounded_ranges *other,
    890  1.1.1.2  mrg 					       tree type)
    891  1.1.1.2  mrg {
    892  1.1.1.2  mrg   tree min_val = TYPE_MIN_VALUE (type);
    893  1.1.1.2  mrg   tree max_val = TYPE_MAX_VALUE (type);
    894  1.1.1.2  mrg   if (other->m_ranges.length () == 0)
    895  1.1.1.2  mrg     return get_or_create_range (min_val, max_val);
    896  1.1.1.2  mrg   auto_vec<bounded_range> ranges;
    897  1.1.1.2  mrg   tree first_lb = other->m_ranges[0].m_lower;
    898  1.1.1.2  mrg   if (tree_int_cst_lt (min_val, first_lb)
    899  1.1.1.2  mrg       && can_minus_one_p (first_lb))
    900  1.1.1.2  mrg     ranges.safe_push (bounded_range (min_val,
    901  1.1.1.2  mrg 				     minus_one (first_lb)));
    902  1.1.1.2  mrg   for (unsigned i = 1; i < other->m_ranges.length (); i++)
    903  1.1.1.2  mrg     {
    904  1.1.1.2  mrg       tree prev_ub = other->m_ranges[i - 1].m_upper;
    905  1.1.1.2  mrg       tree iter_lb = other->m_ranges[i].m_lower;
    906  1.1.1.2  mrg       gcc_assert (tree_int_cst_lt (prev_ub, iter_lb));
    907  1.1.1.2  mrg       if (can_plus_one_p (prev_ub) && can_minus_one_p (iter_lb))
    908  1.1.1.2  mrg 	ranges.safe_push (bounded_range (plus_one (prev_ub),
    909  1.1.1.2  mrg 					 minus_one (iter_lb)));
    910  1.1.1.2  mrg     }
    911  1.1.1.2  mrg   tree last_ub
    912  1.1.1.2  mrg     = other->m_ranges[other->m_ranges.length () - 1].m_upper;
    913  1.1.1.2  mrg   if (tree_int_cst_lt (last_ub, max_val)
    914  1.1.1.2  mrg       && can_plus_one_p (last_ub))
    915  1.1.1.2  mrg     ranges.safe_push (bounded_range (plus_one (last_ub), max_val));
    916  1.1.1.2  mrg 
    917  1.1.1.2  mrg   return consolidate (new bounded_ranges (ranges));
    918  1.1.1.2  mrg }
    919  1.1.1.2  mrg 
    920  1.1.1.2  mrg /* If an object equal to INST is already present, delete INST and
    921  1.1.1.2  mrg    return the existing object.
    922  1.1.1.2  mrg    Otherwise add INST and return it.  */
    923  1.1.1.2  mrg 
    924  1.1.1.2  mrg const bounded_ranges *
    925  1.1.1.2  mrg bounded_ranges_manager::consolidate (bounded_ranges *inst)
    926  1.1.1.2  mrg {
    927  1.1.1.2  mrg   if (bounded_ranges **slot = m_map.get (inst))
    928  1.1.1.2  mrg     {
    929  1.1.1.2  mrg       delete inst;
    930  1.1.1.2  mrg       return *slot;
    931  1.1.1.2  mrg     }
    932  1.1.1.2  mrg   m_map.put (inst, inst);
    933  1.1.1.2  mrg   return inst;
    934  1.1.1.2  mrg }
    935  1.1.1.2  mrg 
    936  1.1.1.2  mrg /* Get the bounded_ranges instance for EDGE of SWITCH_STMT,
    937  1.1.1.2  mrg    creating it if necessary, and caching it by edge.  */
    938  1.1.1.2  mrg 
    939  1.1.1.2  mrg const bounded_ranges *
    940  1.1.1.2  mrg bounded_ranges_manager::
    941  1.1.1.2  mrg get_or_create_ranges_for_switch (const switch_cfg_superedge *edge,
    942  1.1.1.2  mrg 				 const gswitch *switch_stmt)
    943  1.1.1.2  mrg {
    944  1.1.1.2  mrg   /* Look in per-edge cache.  */
    945  1.1.1.2  mrg   if (const bounded_ranges ** slot = m_edge_cache.get (edge))
    946  1.1.1.2  mrg     return *slot;
    947  1.1.1.2  mrg 
    948  1.1.1.2  mrg   /* Not yet in cache.  */
    949  1.1.1.2  mrg   const bounded_ranges *all_cases_ranges
    950  1.1.1.2  mrg     = create_ranges_for_switch (*edge, switch_stmt);
    951  1.1.1.2  mrg   m_edge_cache.put (edge, all_cases_ranges);
    952  1.1.1.2  mrg   return all_cases_ranges;
    953  1.1.1.2  mrg }
    954  1.1.1.2  mrg 
    955  1.1.1.2  mrg /* Get the bounded_ranges instance for EDGE of SWITCH_STMT,
    956  1.1.1.2  mrg    creating it if necessary, for edges for which the per-edge
    957  1.1.1.2  mrg    cache has not yet been populated.  */
    958  1.1.1.2  mrg 
    959  1.1.1.2  mrg const bounded_ranges *
    960  1.1.1.2  mrg bounded_ranges_manager::
    961  1.1.1.2  mrg create_ranges_for_switch (const switch_cfg_superedge &edge,
    962  1.1.1.2  mrg 			  const gswitch *switch_stmt)
    963  1.1.1.2  mrg {
    964  1.1.1.2  mrg   /* Get the ranges for each case label.  */
    965  1.1.1.2  mrg   auto_vec <const bounded_ranges *> case_ranges_vec
    966  1.1.1.2  mrg     (gimple_switch_num_labels (switch_stmt));
    967  1.1.1.2  mrg 
    968  1.1.1.2  mrg   for (tree case_label : edge.get_case_labels ())
    969  1.1.1.2  mrg     {
    970  1.1.1.2  mrg       /* Get the ranges for this case label.  */
    971  1.1.1.2  mrg       const bounded_ranges *case_ranges
    972  1.1.1.2  mrg 	= make_case_label_ranges (switch_stmt, case_label);
    973  1.1.1.2  mrg       case_ranges_vec.quick_push (case_ranges);
    974  1.1.1.2  mrg     }
    975  1.1.1.2  mrg 
    976  1.1.1.2  mrg   /* Combine all the ranges for each case label into a single collection
    977  1.1.1.2  mrg      of ranges.  */
    978  1.1.1.2  mrg   const bounded_ranges *all_cases_ranges
    979  1.1.1.2  mrg     = get_or_create_union (case_ranges_vec);
    980  1.1.1.2  mrg   return all_cases_ranges;
    981  1.1.1.2  mrg }
    982  1.1.1.2  mrg 
    983  1.1.1.2  mrg /* Get the bounded_ranges instance for CASE_LABEL within
    984  1.1.1.2  mrg    SWITCH_STMT.  */
    985  1.1.1.2  mrg 
    986  1.1.1.2  mrg const bounded_ranges *
    987  1.1.1.2  mrg bounded_ranges_manager::
    988  1.1.1.2  mrg make_case_label_ranges (const gswitch *switch_stmt,
    989  1.1.1.2  mrg 			tree case_label)
    990  1.1.1.2  mrg {
    991  1.1.1.2  mrg   gcc_assert (TREE_CODE (case_label) == CASE_LABEL_EXPR);
    992  1.1.1.2  mrg   tree lower_bound = CASE_LOW (case_label);
    993  1.1.1.2  mrg   tree upper_bound = CASE_HIGH (case_label);
    994  1.1.1.2  mrg   if (lower_bound)
    995  1.1.1.2  mrg     {
    996  1.1.1.2  mrg       if (upper_bound)
    997  1.1.1.2  mrg 	/* Range.  */
    998  1.1.1.2  mrg 	return get_or_create_range (lower_bound, upper_bound);
    999  1.1.1.2  mrg       else
   1000  1.1.1.2  mrg 	/* Single-value.  */
   1001  1.1.1.2  mrg 	return get_or_create_point (lower_bound);
   1002  1.1.1.2  mrg     }
   1003  1.1.1.2  mrg   else
   1004  1.1.1.2  mrg     {
   1005  1.1.1.2  mrg       /* The default case.
   1006  1.1.1.2  mrg 	 Add exclusions based on the other cases.  */
   1007  1.1.1.2  mrg       auto_vec <const bounded_ranges *> other_case_ranges
   1008  1.1.1.2  mrg 	(gimple_switch_num_labels (switch_stmt));
   1009  1.1.1.2  mrg       for (unsigned other_idx = 1;
   1010  1.1.1.2  mrg 	   other_idx < gimple_switch_num_labels (switch_stmt);
   1011  1.1.1.2  mrg 	   other_idx++)
   1012  1.1.1.2  mrg 	{
   1013  1.1.1.2  mrg 	  tree other_label = gimple_switch_label (switch_stmt,
   1014  1.1.1.2  mrg 						  other_idx);
   1015  1.1.1.2  mrg 	  const bounded_ranges *other_ranges
   1016  1.1.1.2  mrg 	    = make_case_label_ranges (switch_stmt, other_label);
   1017  1.1.1.2  mrg 	  other_case_ranges.quick_push (other_ranges);
   1018  1.1.1.2  mrg 	}
   1019  1.1.1.2  mrg       const bounded_ranges *other_cases_ranges
   1020  1.1.1.2  mrg 	= get_or_create_union (other_case_ranges);
   1021  1.1.1.2  mrg       tree type = TREE_TYPE (gimple_switch_index (switch_stmt));
   1022  1.1.1.2  mrg       return get_or_create_inverse (other_cases_ranges, type);
   1023  1.1.1.2  mrg     }
   1024  1.1.1.2  mrg }
   1025  1.1.1.2  mrg 
   1026  1.1.1.2  mrg /* Dump the number of objects of each class that were managed by this
   1027  1.1.1.2  mrg    manager to LOGGER.
   1028  1.1.1.2  mrg    If SHOW_OBJS is true, also dump the objects themselves.  */
   1029  1.1.1.2  mrg 
   1030  1.1.1.2  mrg void
   1031  1.1.1.2  mrg bounded_ranges_manager::log_stats (logger *logger, bool show_objs) const
   1032  1.1.1.2  mrg {
   1033  1.1.1.2  mrg   LOG_SCOPE (logger);
   1034  1.1.1.2  mrg   logger->log ("  # %s: %li", "ranges", (long)m_map.elements ());
   1035  1.1.1.2  mrg   if (!show_objs)
   1036  1.1.1.2  mrg     return;
   1037  1.1.1.2  mrg 
   1038  1.1.1.2  mrg   auto_vec<const bounded_ranges *> vec_objs (m_map.elements ());
   1039  1.1.1.2  mrg   for (const auto &iter : m_map)
   1040  1.1.1.2  mrg     vec_objs.quick_push (iter.second);
   1041  1.1.1.2  mrg   vec_objs.qsort
   1042  1.1.1.2  mrg     ([](const void *p1, const void *p2) -> int
   1043  1.1.1.2  mrg      {
   1044  1.1.1.2  mrg        const bounded_ranges *br1 = *(const bounded_ranges * const *)p1;
   1045  1.1.1.2  mrg        const bounded_ranges *br2 = *(const bounded_ranges * const *)p2;
   1046  1.1.1.2  mrg        return bounded_ranges::cmp (br1, br2);
   1047  1.1.1.2  mrg      });
   1048  1.1.1.2  mrg 
   1049  1.1.1.2  mrg   for (const auto &iter : vec_objs)
   1050      1.1  mrg     {
   1051  1.1.1.2  mrg       logger->start_log_line ();
   1052  1.1.1.2  mrg       pretty_printer *pp = logger->get_printer ();
   1053  1.1.1.2  mrg       pp_string (pp, "    ");
   1054  1.1.1.2  mrg       iter->dump_to_pp (pp, true);
   1055  1.1.1.2  mrg       logger->end_log_line ();
   1056      1.1  mrg     }
   1057      1.1  mrg }
   1058      1.1  mrg 
   1059      1.1  mrg /* class equiv_class.  */
   1060      1.1  mrg 
   1061      1.1  mrg /* equiv_class's default ctor.  */
   1062      1.1  mrg 
   1063      1.1  mrg equiv_class::equiv_class ()
   1064  1.1.1.2  mrg : m_constant (NULL_TREE), m_cst_sval (NULL), m_vars ()
   1065      1.1  mrg {
   1066      1.1  mrg }
   1067      1.1  mrg 
   1068      1.1  mrg /* equiv_class's copy ctor.  */
   1069      1.1  mrg 
   1070      1.1  mrg equiv_class::equiv_class (const equiv_class &other)
   1071  1.1.1.2  mrg : m_constant (other.m_constant), m_cst_sval (other.m_cst_sval),
   1072      1.1  mrg   m_vars (other.m_vars.length ())
   1073      1.1  mrg {
   1074  1.1.1.2  mrg   for (const svalue *sval : other.m_vars)
   1075  1.1.1.2  mrg     m_vars.quick_push (sval);
   1076      1.1  mrg }
   1077      1.1  mrg 
   1078      1.1  mrg /* Print an all-on-one-line representation of this equiv_class to PP,
   1079      1.1  mrg    which must support %E for trees.  */
   1080      1.1  mrg 
   1081      1.1  mrg void
   1082      1.1  mrg equiv_class::print (pretty_printer *pp) const
   1083      1.1  mrg {
   1084      1.1  mrg   pp_character (pp, '{');
   1085      1.1  mrg   int i;
   1086  1.1.1.2  mrg   const svalue *sval;
   1087  1.1.1.2  mrg   FOR_EACH_VEC_ELT (m_vars, i, sval)
   1088      1.1  mrg     {
   1089      1.1  mrg       if (i > 0)
   1090      1.1  mrg 	pp_string (pp, " == ");
   1091  1.1.1.2  mrg       sval->dump_to_pp (pp, true);
   1092      1.1  mrg     }
   1093      1.1  mrg   if (m_constant)
   1094      1.1  mrg     {
   1095      1.1  mrg       if (i > 0)
   1096      1.1  mrg 	pp_string (pp, " == ");
   1097  1.1.1.2  mrg       pp_printf (pp, "[m_constant]%qE", m_constant);
   1098      1.1  mrg     }
   1099      1.1  mrg   pp_character (pp, '}');
   1100      1.1  mrg }
   1101      1.1  mrg 
   1102  1.1.1.2  mrg /* Return a new json::object of the form
   1103  1.1.1.2  mrg    {"svals" : [str],
   1104  1.1.1.2  mrg     "constant" : optional str}.  */
   1105  1.1.1.2  mrg 
   1106  1.1.1.2  mrg json::object *
   1107  1.1.1.2  mrg equiv_class::to_json () const
   1108  1.1.1.2  mrg {
   1109  1.1.1.2  mrg   json::object *ec_obj = new json::object ();
   1110  1.1.1.2  mrg 
   1111  1.1.1.2  mrg   json::array *sval_arr = new json::array ();
   1112  1.1.1.2  mrg   for (const svalue *sval : m_vars)
   1113  1.1.1.2  mrg     sval_arr->append (sval->to_json ());
   1114  1.1.1.2  mrg   ec_obj->set ("svals", sval_arr);
   1115  1.1.1.2  mrg 
   1116  1.1.1.2  mrg   if (m_constant)
   1117  1.1.1.2  mrg     {
   1118  1.1.1.2  mrg       pretty_printer pp;
   1119  1.1.1.2  mrg       pp_format_decoder (&pp) = default_tree_printer;
   1120  1.1.1.2  mrg       pp_printf (&pp, "%qE", m_constant);
   1121  1.1.1.2  mrg       ec_obj->set ("constant", new json::string (pp_formatted_text (&pp)));
   1122  1.1.1.2  mrg     }
   1123  1.1.1.2  mrg 
   1124  1.1.1.2  mrg   return ec_obj;
   1125  1.1.1.2  mrg }
   1126  1.1.1.2  mrg 
   1127  1.1.1.2  mrg /* Generate a hash value for this equiv_class.
   1128  1.1.1.2  mrg    This relies on the ordering of m_vars, and so this object needs to
   1129  1.1.1.2  mrg    have been canonicalized for this to be meaningful.  */
   1130      1.1  mrg 
   1131      1.1  mrg hashval_t
   1132      1.1  mrg equiv_class::hash () const
   1133      1.1  mrg {
   1134      1.1  mrg   inchash::hash hstate;
   1135      1.1  mrg 
   1136      1.1  mrg   inchash::add_expr (m_constant, hstate);
   1137  1.1.1.2  mrg   for (const svalue * sval : m_vars)
   1138  1.1.1.2  mrg     hstate.add_ptr (sval);
   1139      1.1  mrg   return hstate.end ();
   1140      1.1  mrg }
   1141      1.1  mrg 
   1142  1.1.1.2  mrg /* Equality operator for equiv_class.
   1143  1.1.1.2  mrg    This relies on the ordering of m_vars, and so this object
   1144  1.1.1.2  mrg    and OTHER need to have been canonicalized for this to be
   1145  1.1.1.2  mrg    meaningful.  */
   1146      1.1  mrg 
   1147      1.1  mrg bool
   1148      1.1  mrg equiv_class::operator== (const equiv_class &other)
   1149      1.1  mrg {
   1150      1.1  mrg   if (m_constant != other.m_constant)
   1151      1.1  mrg     return false; // TODO: use tree equality here?
   1152      1.1  mrg 
   1153  1.1.1.2  mrg   /* FIXME: should we compare m_cst_sval?  */
   1154      1.1  mrg 
   1155      1.1  mrg   if (m_vars.length () != other.m_vars.length ())
   1156      1.1  mrg     return false;
   1157      1.1  mrg 
   1158      1.1  mrg   int i;
   1159  1.1.1.2  mrg   const svalue *sval;
   1160  1.1.1.2  mrg   FOR_EACH_VEC_ELT (m_vars, i, sval)
   1161  1.1.1.2  mrg     if (sval != other.m_vars[i])
   1162      1.1  mrg       return false;
   1163      1.1  mrg 
   1164      1.1  mrg   return true;
   1165      1.1  mrg }
   1166      1.1  mrg 
   1167      1.1  mrg /* Add SID to this equiv_class, using CM to check if it's a constant.  */
   1168      1.1  mrg 
   1169      1.1  mrg void
   1170  1.1.1.2  mrg equiv_class::add (const svalue *sval)
   1171      1.1  mrg {
   1172  1.1.1.2  mrg   gcc_assert (sval);
   1173  1.1.1.2  mrg   if (tree cst = sval->maybe_get_constant ())
   1174      1.1  mrg     {
   1175      1.1  mrg       gcc_assert (CONSTANT_CLASS_P (cst));
   1176      1.1  mrg       /* FIXME: should we canonicalize which svalue is the constant
   1177      1.1  mrg 	 when there are multiple equal constants?  */
   1178      1.1  mrg       m_constant = cst;
   1179  1.1.1.2  mrg       m_cst_sval = sval;
   1180      1.1  mrg     }
   1181  1.1.1.2  mrg   m_vars.safe_push (sval);
   1182      1.1  mrg }
   1183      1.1  mrg 
   1184      1.1  mrg /* Remove SID from this equivalence class.
   1185      1.1  mrg    Return true if SID was the last var in the equivalence class (suggesting
   1186      1.1  mrg    a possible leak).  */
   1187      1.1  mrg 
   1188      1.1  mrg bool
   1189  1.1.1.2  mrg equiv_class::del (const svalue *sval)
   1190      1.1  mrg {
   1191  1.1.1.2  mrg   gcc_assert (sval);
   1192  1.1.1.2  mrg   gcc_assert (sval != m_cst_sval);
   1193      1.1  mrg 
   1194      1.1  mrg   int i;
   1195  1.1.1.2  mrg   const svalue *iv;
   1196      1.1  mrg   FOR_EACH_VEC_ELT (m_vars, i, iv)
   1197      1.1  mrg     {
   1198  1.1.1.2  mrg       if (iv == sval)
   1199      1.1  mrg 	{
   1200      1.1  mrg 	  m_vars[i] = m_vars[m_vars.length () - 1];
   1201      1.1  mrg 	  m_vars.pop ();
   1202      1.1  mrg 	  return m_vars.length () == 0;
   1203      1.1  mrg 	}
   1204      1.1  mrg     }
   1205      1.1  mrg 
   1206  1.1.1.2  mrg   /* SVAL must be in the class.  */
   1207      1.1  mrg   gcc_unreachable ();
   1208      1.1  mrg   return false;
   1209      1.1  mrg }
   1210      1.1  mrg 
   1211      1.1  mrg /* Get a representative member of this class, for handling cases
   1212      1.1  mrg    where the IDs can change mid-traversal.  */
   1213      1.1  mrg 
   1214  1.1.1.2  mrg const svalue *
   1215      1.1  mrg equiv_class::get_representative () const
   1216      1.1  mrg {
   1217  1.1.1.2  mrg   gcc_assert (m_vars.length () > 0);
   1218  1.1.1.2  mrg   return m_vars[0];
   1219      1.1  mrg }
   1220      1.1  mrg 
   1221  1.1.1.2  mrg /* Sort the svalues within this equiv_class.  */
   1222      1.1  mrg 
   1223      1.1  mrg void
   1224  1.1.1.2  mrg equiv_class::canonicalize ()
   1225      1.1  mrg {
   1226  1.1.1.2  mrg   m_vars.qsort (svalue::cmp_ptr_ptr);
   1227      1.1  mrg }
   1228      1.1  mrg 
   1229  1.1.1.2  mrg /* Return true if this EC contains a variable, false if it merely
   1230  1.1.1.2  mrg    contains constants.
   1231  1.1.1.2  mrg    Subroutine of constraint_manager::canonicalize, for removing
   1232  1.1.1.2  mrg    redundant ECs.  */
   1233      1.1  mrg 
   1234  1.1.1.2  mrg bool
   1235  1.1.1.2  mrg equiv_class::contains_non_constant_p () const
   1236      1.1  mrg {
   1237  1.1.1.2  mrg   if (m_constant)
   1238  1.1.1.2  mrg     {
   1239  1.1.1.2  mrg       for (auto iter : m_vars)
   1240  1.1.1.2  mrg 	if (iter->maybe_get_constant ())
   1241  1.1.1.2  mrg 	  continue;
   1242  1.1.1.2  mrg 	else
   1243  1.1.1.2  mrg 	  /* We have {non-constant == constant}.  */
   1244  1.1.1.2  mrg 	  return true;
   1245  1.1.1.2  mrg       /* We only have constants.  */
   1246  1.1.1.2  mrg       return false;
   1247  1.1.1.2  mrg     }
   1248  1.1.1.2  mrg   else
   1249  1.1.1.2  mrg     /* Return true if we have {non-constant == non-constant}.  */
   1250  1.1.1.2  mrg     return m_vars.length () > 1;
   1251      1.1  mrg }
   1252      1.1  mrg 
   1253      1.1  mrg /* Get a debug string for C_OP.  */
   1254      1.1  mrg 
   1255      1.1  mrg const char *
   1256      1.1  mrg constraint_op_code (enum constraint_op c_op)
   1257      1.1  mrg {
   1258      1.1  mrg   switch (c_op)
   1259      1.1  mrg     {
   1260      1.1  mrg     default:
   1261      1.1  mrg       gcc_unreachable ();
   1262      1.1  mrg     case CONSTRAINT_NE: return "!=";
   1263      1.1  mrg     case CONSTRAINT_LT: return "<";
   1264      1.1  mrg     case CONSTRAINT_LE: return "<=";
   1265      1.1  mrg     }
   1266      1.1  mrg }
   1267      1.1  mrg 
   1268      1.1  mrg /* Convert C_OP to an enum tree_code.  */
   1269      1.1  mrg 
   1270      1.1  mrg enum tree_code
   1271      1.1  mrg constraint_tree_code (enum constraint_op c_op)
   1272      1.1  mrg {
   1273      1.1  mrg   switch (c_op)
   1274      1.1  mrg     {
   1275      1.1  mrg     default:
   1276      1.1  mrg       gcc_unreachable ();
   1277      1.1  mrg     case CONSTRAINT_NE: return NE_EXPR;
   1278      1.1  mrg     case CONSTRAINT_LT: return LT_EXPR;
   1279      1.1  mrg     case CONSTRAINT_LE: return LE_EXPR;
   1280      1.1  mrg     }
   1281      1.1  mrg }
   1282      1.1  mrg 
   1283      1.1  mrg /* Given "lhs C_OP rhs", determine "lhs T_OP rhs".
   1284      1.1  mrg 
   1285      1.1  mrg    For example, given "x < y", then "x > y" is false.  */
   1286      1.1  mrg 
   1287      1.1  mrg static tristate
   1288      1.1  mrg eval_constraint_op_for_op (enum constraint_op c_op, enum tree_code t_op)
   1289      1.1  mrg {
   1290      1.1  mrg   switch (c_op)
   1291      1.1  mrg     {
   1292      1.1  mrg     default:
   1293      1.1  mrg       gcc_unreachable ();
   1294      1.1  mrg     case CONSTRAINT_NE:
   1295      1.1  mrg       if (t_op == EQ_EXPR)
   1296      1.1  mrg 	return tristate (tristate::TS_FALSE);
   1297      1.1  mrg       if (t_op == NE_EXPR)
   1298      1.1  mrg 	return tristate (tristate::TS_TRUE);
   1299      1.1  mrg       break;
   1300      1.1  mrg     case CONSTRAINT_LT:
   1301      1.1  mrg       if (t_op == LT_EXPR || t_op == LE_EXPR || t_op == NE_EXPR)
   1302      1.1  mrg 	return tristate (tristate::TS_TRUE);
   1303      1.1  mrg       if (t_op == EQ_EXPR || t_op == GT_EXPR || t_op == GE_EXPR)
   1304      1.1  mrg 	return tristate (tristate::TS_FALSE);
   1305      1.1  mrg       break;
   1306      1.1  mrg     case CONSTRAINT_LE:
   1307      1.1  mrg       if (t_op == LE_EXPR)
   1308      1.1  mrg 	return tristate (tristate::TS_TRUE);
   1309      1.1  mrg       if (t_op == GT_EXPR)
   1310      1.1  mrg 	return tristate (tristate::TS_FALSE);
   1311      1.1  mrg       break;
   1312      1.1  mrg     }
   1313      1.1  mrg   return tristate (tristate::TS_UNKNOWN);
   1314      1.1  mrg }
   1315      1.1  mrg 
   1316      1.1  mrg /* class constraint.  */
   1317      1.1  mrg 
   1318      1.1  mrg /* Print this constraint to PP (which must support %E for trees),
   1319      1.1  mrg    using CM to look up equiv_class instances from ids.  */
   1320      1.1  mrg 
   1321      1.1  mrg void
   1322      1.1  mrg constraint::print (pretty_printer *pp, const constraint_manager &cm) const
   1323      1.1  mrg {
   1324      1.1  mrg   m_lhs.print (pp);
   1325      1.1  mrg   pp_string (pp, ": ");
   1326      1.1  mrg   m_lhs.get_obj (cm).print (pp);
   1327      1.1  mrg   pp_string (pp, " ");
   1328      1.1  mrg   pp_string (pp, constraint_op_code (m_op));
   1329      1.1  mrg   pp_string (pp, " ");
   1330      1.1  mrg   m_rhs.print (pp);
   1331      1.1  mrg   pp_string (pp, ": ");
   1332      1.1  mrg   m_rhs.get_obj (cm).print (pp);
   1333      1.1  mrg }
   1334      1.1  mrg 
   1335  1.1.1.2  mrg /* Return a new json::object of the form
   1336  1.1.1.2  mrg    {"lhs" : int, the EC index
   1337  1.1.1.2  mrg     "op"  : str,
   1338  1.1.1.2  mrg     "rhs" : int, the EC index}.  */
   1339  1.1.1.2  mrg 
   1340  1.1.1.2  mrg json::object *
   1341  1.1.1.2  mrg constraint::to_json () const
   1342  1.1.1.2  mrg {
   1343  1.1.1.2  mrg   json::object *con_obj = new json::object ();
   1344  1.1.1.2  mrg 
   1345  1.1.1.2  mrg   con_obj->set ("lhs", new json::integer_number (m_lhs.as_int ()));
   1346  1.1.1.2  mrg   con_obj->set ("op", new json::string (constraint_op_code (m_op)));
   1347  1.1.1.2  mrg   con_obj->set ("rhs", new json::integer_number (m_rhs.as_int ()));
   1348  1.1.1.2  mrg 
   1349  1.1.1.2  mrg   return con_obj;
   1350  1.1.1.2  mrg }
   1351  1.1.1.2  mrg 
   1352      1.1  mrg /* Generate a hash value for this constraint.  */
   1353      1.1  mrg 
   1354      1.1  mrg hashval_t
   1355      1.1  mrg constraint::hash () const
   1356      1.1  mrg {
   1357      1.1  mrg   inchash::hash hstate;
   1358      1.1  mrg   hstate.add_int (m_lhs.m_idx);
   1359      1.1  mrg   hstate.add_int (m_op);
   1360      1.1  mrg   hstate.add_int (m_rhs.m_idx);
   1361      1.1  mrg   return hstate.end ();
   1362      1.1  mrg }
   1363      1.1  mrg 
   1364      1.1  mrg /* Equality operator for constraints.  */
   1365      1.1  mrg 
   1366      1.1  mrg bool
   1367      1.1  mrg constraint::operator== (const constraint &other) const
   1368      1.1  mrg {
   1369      1.1  mrg   if (m_lhs != other.m_lhs)
   1370      1.1  mrg     return false;
   1371      1.1  mrg   if (m_op != other.m_op)
   1372      1.1  mrg     return false;
   1373      1.1  mrg   if (m_rhs != other.m_rhs)
   1374      1.1  mrg     return false;
   1375      1.1  mrg   return true;
   1376      1.1  mrg }
   1377      1.1  mrg 
   1378  1.1.1.2  mrg /* Return true if this constraint is implied by OTHER.  */
   1379  1.1.1.2  mrg 
   1380  1.1.1.2  mrg bool
   1381  1.1.1.2  mrg constraint::implied_by (const constraint &other,
   1382  1.1.1.2  mrg 			 const constraint_manager &cm) const
   1383  1.1.1.2  mrg {
   1384  1.1.1.2  mrg   if (m_lhs == other.m_lhs)
   1385  1.1.1.2  mrg     if (tree rhs_const = m_rhs.get_obj (cm).get_any_constant ())
   1386  1.1.1.2  mrg       if (tree other_rhs_const = other.m_rhs.get_obj (cm).get_any_constant ())
   1387  1.1.1.2  mrg 	if (m_lhs.get_obj (cm).get_any_constant () == NULL_TREE)
   1388  1.1.1.2  mrg 	  if (m_op == other.m_op)
   1389  1.1.1.2  mrg 	    switch (m_op)
   1390  1.1.1.2  mrg 	      {
   1391  1.1.1.2  mrg 	      default:
   1392  1.1.1.2  mrg 		break;
   1393  1.1.1.2  mrg 	      case CONSTRAINT_LE:
   1394  1.1.1.2  mrg 	      case CONSTRAINT_LT:
   1395  1.1.1.2  mrg 		if (compare_constants (rhs_const,
   1396  1.1.1.2  mrg 				       GE_EXPR,
   1397  1.1.1.2  mrg 				       other_rhs_const).is_true ())
   1398  1.1.1.2  mrg 		  return true;
   1399  1.1.1.2  mrg 		break;
   1400  1.1.1.2  mrg 	      }
   1401  1.1.1.2  mrg   return false;
   1402  1.1.1.2  mrg }
   1403  1.1.1.2  mrg 
   1404  1.1.1.2  mrg /* class bounded_ranges_constraint.  */
   1405  1.1.1.2  mrg 
   1406  1.1.1.2  mrg void
   1407  1.1.1.2  mrg bounded_ranges_constraint::print (pretty_printer *pp,
   1408  1.1.1.2  mrg 				  const constraint_manager &cm) const
   1409  1.1.1.2  mrg {
   1410  1.1.1.2  mrg   m_ec_id.print (pp);
   1411  1.1.1.2  mrg   pp_string (pp, ": ");
   1412  1.1.1.2  mrg   m_ec_id.get_obj (cm).print (pp);
   1413  1.1.1.2  mrg   pp_string (pp, ": ");
   1414  1.1.1.2  mrg   m_ranges->dump_to_pp (pp, true);
   1415  1.1.1.2  mrg }
   1416  1.1.1.2  mrg 
   1417  1.1.1.2  mrg json::object *
   1418  1.1.1.2  mrg bounded_ranges_constraint::to_json () const
   1419  1.1.1.2  mrg {
   1420  1.1.1.2  mrg   json::object *con_obj = new json::object ();
   1421  1.1.1.2  mrg 
   1422  1.1.1.2  mrg   con_obj->set ("ec", new json::integer_number (m_ec_id.as_int ()));
   1423  1.1.1.2  mrg   con_obj->set ("ranges", m_ranges->to_json ());
   1424  1.1.1.2  mrg 
   1425  1.1.1.2  mrg   return con_obj;
   1426  1.1.1.2  mrg }
   1427  1.1.1.2  mrg 
   1428  1.1.1.2  mrg bool
   1429  1.1.1.2  mrg bounded_ranges_constraint::
   1430  1.1.1.2  mrg operator== (const bounded_ranges_constraint &other) const
   1431  1.1.1.2  mrg {
   1432  1.1.1.2  mrg   if (m_ec_id != other.m_ec_id)
   1433  1.1.1.2  mrg     return false;
   1434  1.1.1.2  mrg 
   1435  1.1.1.2  mrg   /* We can compare by pointer, since the bounded_ranges_manager
   1436  1.1.1.2  mrg      consolidates instances.  */
   1437  1.1.1.2  mrg   return m_ranges == other.m_ranges;
   1438  1.1.1.2  mrg }
   1439  1.1.1.2  mrg 
   1440  1.1.1.2  mrg void
   1441  1.1.1.2  mrg bounded_ranges_constraint::add_to_hash (inchash::hash *hstate) const
   1442  1.1.1.2  mrg {
   1443  1.1.1.2  mrg   hstate->add_int (m_ec_id.m_idx);
   1444  1.1.1.2  mrg   hstate->merge_hash (m_ranges->get_hash ());
   1445  1.1.1.2  mrg }
   1446  1.1.1.2  mrg 
   1447      1.1  mrg /* class equiv_class_id.  */
   1448      1.1  mrg 
   1449      1.1  mrg /* Get the underlying equiv_class for this ID from CM.  */
   1450      1.1  mrg 
   1451      1.1  mrg const equiv_class &
   1452      1.1  mrg equiv_class_id::get_obj (const constraint_manager &cm) const
   1453      1.1  mrg {
   1454      1.1  mrg   return cm.get_equiv_class_by_index (m_idx);
   1455      1.1  mrg }
   1456      1.1  mrg 
   1457      1.1  mrg /* Access the underlying equiv_class for this ID from CM.  */
   1458      1.1  mrg 
   1459      1.1  mrg equiv_class &
   1460      1.1  mrg equiv_class_id::get_obj (constraint_manager &cm) const
   1461      1.1  mrg {
   1462      1.1  mrg   return cm.get_equiv_class_by_index (m_idx);
   1463      1.1  mrg }
   1464      1.1  mrg 
   1465      1.1  mrg /* Print this equiv_class_id to PP.  */
   1466      1.1  mrg 
   1467      1.1  mrg void
   1468      1.1  mrg equiv_class_id::print (pretty_printer *pp) const
   1469      1.1  mrg {
   1470      1.1  mrg   if (null_p ())
   1471      1.1  mrg     pp_printf (pp, "null");
   1472      1.1  mrg   else
   1473      1.1  mrg     pp_printf (pp, "ec%i", m_idx);
   1474      1.1  mrg }
   1475      1.1  mrg 
   1476      1.1  mrg /* class constraint_manager.  */
   1477      1.1  mrg 
   1478      1.1  mrg /* constraint_manager's copy ctor.  */
   1479      1.1  mrg 
   1480      1.1  mrg constraint_manager::constraint_manager (const constraint_manager &other)
   1481      1.1  mrg : m_equiv_classes (other.m_equiv_classes.length ()),
   1482  1.1.1.2  mrg   m_constraints (other.m_constraints.length ()),
   1483  1.1.1.2  mrg   m_bounded_ranges_constraints (other.m_bounded_ranges_constraints.length ()),
   1484  1.1.1.2  mrg   m_mgr (other.m_mgr)
   1485      1.1  mrg {
   1486      1.1  mrg   int i;
   1487      1.1  mrg   equiv_class *ec;
   1488      1.1  mrg   FOR_EACH_VEC_ELT (other.m_equiv_classes, i, ec)
   1489      1.1  mrg     m_equiv_classes.quick_push (new equiv_class (*ec));
   1490      1.1  mrg   constraint *c;
   1491      1.1  mrg   FOR_EACH_VEC_ELT (other.m_constraints, i, c)
   1492      1.1  mrg     m_constraints.quick_push (*c);
   1493  1.1.1.2  mrg   for (const auto &iter : other.m_bounded_ranges_constraints)
   1494  1.1.1.2  mrg     m_bounded_ranges_constraints.quick_push (iter);
   1495      1.1  mrg }
   1496      1.1  mrg 
   1497      1.1  mrg /* constraint_manager's assignment operator.  */
   1498      1.1  mrg 
   1499      1.1  mrg constraint_manager&
   1500      1.1  mrg constraint_manager::operator= (const constraint_manager &other)
   1501      1.1  mrg {
   1502      1.1  mrg   gcc_assert (m_equiv_classes.length () == 0);
   1503      1.1  mrg   gcc_assert (m_constraints.length () == 0);
   1504  1.1.1.2  mrg   gcc_assert (m_bounded_ranges_constraints.length () == 0);
   1505      1.1  mrg 
   1506      1.1  mrg   int i;
   1507      1.1  mrg   equiv_class *ec;
   1508      1.1  mrg   m_equiv_classes.reserve (other.m_equiv_classes.length ());
   1509      1.1  mrg   FOR_EACH_VEC_ELT (other.m_equiv_classes, i, ec)
   1510      1.1  mrg     m_equiv_classes.quick_push (new equiv_class (*ec));
   1511      1.1  mrg   constraint *c;
   1512      1.1  mrg   m_constraints.reserve (other.m_constraints.length ());
   1513      1.1  mrg   FOR_EACH_VEC_ELT (other.m_constraints, i, c)
   1514      1.1  mrg     m_constraints.quick_push (*c);
   1515  1.1.1.2  mrg   for (const auto &iter : other.m_bounded_ranges_constraints)
   1516  1.1.1.2  mrg     m_bounded_ranges_constraints.quick_push (iter);
   1517      1.1  mrg 
   1518      1.1  mrg   return *this;
   1519      1.1  mrg }
   1520      1.1  mrg 
   1521      1.1  mrg /* Generate a hash value for this constraint_manager.  */
   1522      1.1  mrg 
   1523      1.1  mrg hashval_t
   1524      1.1  mrg constraint_manager::hash () const
   1525      1.1  mrg {
   1526      1.1  mrg   inchash::hash hstate;
   1527      1.1  mrg   int i;
   1528      1.1  mrg   equiv_class *ec;
   1529      1.1  mrg   constraint *c;
   1530      1.1  mrg 
   1531      1.1  mrg   FOR_EACH_VEC_ELT (m_equiv_classes, i, ec)
   1532      1.1  mrg     hstate.merge_hash (ec->hash ());
   1533      1.1  mrg   FOR_EACH_VEC_ELT (m_constraints, i, c)
   1534      1.1  mrg     hstate.merge_hash (c->hash ());
   1535  1.1.1.2  mrg   for (const auto &iter : m_bounded_ranges_constraints)
   1536  1.1.1.2  mrg     iter.add_to_hash (&hstate);
   1537      1.1  mrg   return hstate.end ();
   1538      1.1  mrg }
   1539      1.1  mrg 
   1540      1.1  mrg /* Equality operator for constraint_manager.  */
   1541      1.1  mrg 
   1542      1.1  mrg bool
   1543      1.1  mrg constraint_manager::operator== (const constraint_manager &other) const
   1544      1.1  mrg {
   1545      1.1  mrg   if (m_equiv_classes.length () != other.m_equiv_classes.length ())
   1546      1.1  mrg     return false;
   1547      1.1  mrg   if (m_constraints.length () != other.m_constraints.length ())
   1548      1.1  mrg     return false;
   1549  1.1.1.2  mrg   if (m_bounded_ranges_constraints.length ()
   1550  1.1.1.2  mrg       != other.m_bounded_ranges_constraints.length ())
   1551  1.1.1.2  mrg     return false;
   1552      1.1  mrg 
   1553      1.1  mrg   int i;
   1554      1.1  mrg   equiv_class *ec;
   1555      1.1  mrg 
   1556      1.1  mrg   FOR_EACH_VEC_ELT (m_equiv_classes, i, ec)
   1557      1.1  mrg     if (!(*ec == *other.m_equiv_classes[i]))
   1558      1.1  mrg       return false;
   1559      1.1  mrg 
   1560      1.1  mrg   constraint *c;
   1561      1.1  mrg 
   1562      1.1  mrg   FOR_EACH_VEC_ELT (m_constraints, i, c)
   1563      1.1  mrg     if (!(*c == other.m_constraints[i]))
   1564      1.1  mrg       return false;
   1565      1.1  mrg 
   1566  1.1.1.2  mrg   for (unsigned i = 0; i < m_bounded_ranges_constraints.length (); i++)
   1567  1.1.1.2  mrg     {
   1568  1.1.1.2  mrg       if (m_bounded_ranges_constraints[i]
   1569  1.1.1.2  mrg 	  != other.m_bounded_ranges_constraints[i])
   1570  1.1.1.2  mrg 	return false;
   1571  1.1.1.2  mrg     }
   1572  1.1.1.2  mrg 
   1573      1.1  mrg   return true;
   1574      1.1  mrg }
   1575      1.1  mrg 
   1576      1.1  mrg /* Print this constraint_manager to PP (which must support %E for trees).  */
   1577      1.1  mrg 
   1578      1.1  mrg void
   1579      1.1  mrg constraint_manager::print (pretty_printer *pp) const
   1580      1.1  mrg {
   1581      1.1  mrg   pp_string (pp, "{");
   1582      1.1  mrg   int i;
   1583      1.1  mrg   equiv_class *ec;
   1584      1.1  mrg   FOR_EACH_VEC_ELT (m_equiv_classes, i, ec)
   1585      1.1  mrg     {
   1586      1.1  mrg       if (i > 0)
   1587      1.1  mrg 	pp_string (pp, ", ");
   1588      1.1  mrg       equiv_class_id (i).print (pp);
   1589      1.1  mrg       pp_string (pp, ": ");
   1590      1.1  mrg       ec->print (pp);
   1591      1.1  mrg     }
   1592      1.1  mrg   pp_string (pp, "  |  ");
   1593      1.1  mrg   constraint *c;
   1594      1.1  mrg   FOR_EACH_VEC_ELT (m_constraints, i, c)
   1595      1.1  mrg     {
   1596      1.1  mrg       if (i > 0)
   1597      1.1  mrg 	pp_string (pp, " && ");
   1598      1.1  mrg       c->print (pp, *this);
   1599      1.1  mrg     }
   1600  1.1.1.2  mrg   if (m_bounded_ranges_constraints.length ())
   1601  1.1.1.2  mrg     {
   1602  1.1.1.2  mrg       pp_string (pp, "  |  ");
   1603  1.1.1.2  mrg       i = 0;
   1604  1.1.1.2  mrg       for (const auto &iter : m_bounded_ranges_constraints)
   1605  1.1.1.2  mrg 	{
   1606  1.1.1.2  mrg 	  if (i > 0)
   1607  1.1.1.2  mrg 	    pp_string (pp, " && ");
   1608  1.1.1.2  mrg 	  iter.print (pp, *this);
   1609  1.1.1.2  mrg 	  i++;
   1610  1.1.1.2  mrg 	}
   1611  1.1.1.2  mrg     }
   1612      1.1  mrg   pp_printf (pp, "}");
   1613      1.1  mrg }
   1614      1.1  mrg 
   1615  1.1.1.2  mrg /* Dump a representation of this constraint_manager to PP
   1616      1.1  mrg    (which must support %E for trees).  */
   1617      1.1  mrg 
   1618      1.1  mrg void
   1619  1.1.1.2  mrg constraint_manager::dump_to_pp (pretty_printer *pp, bool multiline) const
   1620      1.1  mrg {
   1621  1.1.1.2  mrg   if (multiline)
   1622  1.1.1.2  mrg     pp_string (pp, "  ");
   1623  1.1.1.2  mrg   pp_string (pp, "equiv classes:");
   1624  1.1.1.2  mrg   if (multiline)
   1625  1.1.1.2  mrg     pp_newline (pp);
   1626  1.1.1.2  mrg   else
   1627  1.1.1.2  mrg     pp_string (pp, " {");
   1628      1.1  mrg   int i;
   1629      1.1  mrg   equiv_class *ec;
   1630      1.1  mrg   FOR_EACH_VEC_ELT (m_equiv_classes, i, ec)
   1631      1.1  mrg     {
   1632  1.1.1.2  mrg       if (multiline)
   1633  1.1.1.2  mrg 	pp_string (pp, "    ");
   1634  1.1.1.2  mrg       else if (i > 0)
   1635  1.1.1.2  mrg 	pp_string (pp, ", ");
   1636      1.1  mrg       equiv_class_id (i).print (pp);
   1637      1.1  mrg       pp_string (pp, ": ");
   1638      1.1  mrg       ec->print (pp);
   1639  1.1.1.2  mrg       if (multiline)
   1640  1.1.1.2  mrg 	pp_newline (pp);
   1641      1.1  mrg     }
   1642  1.1.1.2  mrg   if (multiline)
   1643  1.1.1.2  mrg     pp_string (pp, "  ");
   1644  1.1.1.2  mrg   else
   1645  1.1.1.2  mrg     pp_string (pp, "}");
   1646  1.1.1.2  mrg   pp_string (pp, "constraints:");
   1647  1.1.1.2  mrg   if (multiline)
   1648  1.1.1.2  mrg     pp_newline (pp);
   1649  1.1.1.2  mrg   else
   1650  1.1.1.2  mrg     pp_string (pp, "{");
   1651      1.1  mrg   constraint *c;
   1652      1.1  mrg   FOR_EACH_VEC_ELT (m_constraints, i, c)
   1653      1.1  mrg     {
   1654  1.1.1.2  mrg       if (multiline)
   1655  1.1.1.2  mrg 	pp_string (pp, "    ");
   1656  1.1.1.2  mrg       pp_printf (pp, "%i: ", i);
   1657      1.1  mrg       c->print (pp, *this);
   1658  1.1.1.2  mrg       if (multiline)
   1659  1.1.1.2  mrg 	pp_newline (pp);
   1660      1.1  mrg     }
   1661  1.1.1.2  mrg   if (!multiline)
   1662  1.1.1.2  mrg     pp_string (pp, "}");
   1663  1.1.1.2  mrg   if (m_bounded_ranges_constraints.length ())
   1664  1.1.1.2  mrg     {
   1665  1.1.1.2  mrg       if (multiline)
   1666  1.1.1.2  mrg 	pp_string (pp, "  ");
   1667  1.1.1.2  mrg       pp_string (pp, "ranges:");
   1668  1.1.1.2  mrg       if (multiline)
   1669  1.1.1.2  mrg 	pp_newline (pp);
   1670  1.1.1.2  mrg       else
   1671  1.1.1.2  mrg 	pp_string (pp, "{");
   1672  1.1.1.2  mrg       i = 0;
   1673  1.1.1.2  mrg       for (const auto &iter : m_bounded_ranges_constraints)
   1674  1.1.1.2  mrg 	{
   1675  1.1.1.2  mrg 	  if (multiline)
   1676  1.1.1.2  mrg 	    pp_string (pp, "    ");
   1677  1.1.1.2  mrg 	  else if (i > 0)
   1678  1.1.1.2  mrg 	    pp_string (pp, " && ");
   1679  1.1.1.2  mrg 	  iter.print (pp, *this);
   1680  1.1.1.2  mrg 	  if (multiline)
   1681  1.1.1.2  mrg 	    pp_newline (pp);
   1682  1.1.1.2  mrg 	  i++;
   1683  1.1.1.2  mrg 	}
   1684  1.1.1.2  mrg       if (!multiline)
   1685  1.1.1.2  mrg 	pp_string (pp, "}");
   1686  1.1.1.2  mrg       }
   1687      1.1  mrg }
   1688      1.1  mrg 
   1689      1.1  mrg /* Dump a multiline representation of this constraint_manager to FP.  */
   1690      1.1  mrg 
   1691      1.1  mrg void
   1692      1.1  mrg constraint_manager::dump (FILE *fp) const
   1693      1.1  mrg {
   1694      1.1  mrg   pretty_printer pp;
   1695      1.1  mrg   pp_format_decoder (&pp) = default_tree_printer;
   1696      1.1  mrg   pp_show_color (&pp) = pp_show_color (global_dc->printer);
   1697      1.1  mrg   pp.buffer->stream = fp;
   1698  1.1.1.2  mrg   dump_to_pp (&pp, true);
   1699      1.1  mrg   pp_flush (&pp);
   1700      1.1  mrg }
   1701      1.1  mrg 
   1702      1.1  mrg /* Dump a multiline representation of this constraint_manager to stderr.  */
   1703      1.1  mrg 
   1704      1.1  mrg DEBUG_FUNCTION void
   1705      1.1  mrg constraint_manager::dump () const
   1706      1.1  mrg {
   1707      1.1  mrg   dump (stderr);
   1708      1.1  mrg }
   1709      1.1  mrg 
   1710      1.1  mrg /* Dump a multiline representation of CM to stderr.  */
   1711      1.1  mrg 
   1712      1.1  mrg DEBUG_FUNCTION void
   1713      1.1  mrg debug (const constraint_manager &cm)
   1714      1.1  mrg {
   1715      1.1  mrg   cm.dump ();
   1716      1.1  mrg }
   1717      1.1  mrg 
   1718  1.1.1.2  mrg /* Return a new json::object of the form
   1719  1.1.1.2  mrg    {"ecs" : array of objects, one per equiv_class
   1720  1.1.1.2  mrg     "constraints" : array of objects, one per constraint}.  */
   1721  1.1.1.2  mrg 
   1722  1.1.1.2  mrg json::object *
   1723  1.1.1.2  mrg constraint_manager::to_json () const
   1724  1.1.1.2  mrg {
   1725  1.1.1.2  mrg   json::object *cm_obj = new json::object ();
   1726  1.1.1.2  mrg 
   1727  1.1.1.2  mrg   /* Equivalence classes.  */
   1728  1.1.1.2  mrg   {
   1729  1.1.1.2  mrg     json::array *ec_arr = new json::array ();
   1730  1.1.1.2  mrg     for (const equiv_class *ec : m_equiv_classes)
   1731  1.1.1.2  mrg       ec_arr->append (ec->to_json ());
   1732  1.1.1.2  mrg     cm_obj->set ("ecs", ec_arr);
   1733  1.1.1.2  mrg   }
   1734  1.1.1.2  mrg 
   1735  1.1.1.2  mrg   /* Constraints.  */
   1736  1.1.1.2  mrg   {
   1737  1.1.1.2  mrg     json::array *con_arr = new json::array ();
   1738  1.1.1.2  mrg     for (const constraint &c : m_constraints)
   1739  1.1.1.2  mrg       con_arr->append (c.to_json ());
   1740  1.1.1.2  mrg     cm_obj->set ("constraints", con_arr);
   1741  1.1.1.2  mrg   }
   1742  1.1.1.2  mrg 
   1743  1.1.1.2  mrg   /* m_bounded_ranges_constraints.  */
   1744  1.1.1.2  mrg   {
   1745  1.1.1.2  mrg     json::array *con_arr = new json::array ();
   1746  1.1.1.2  mrg     for (const auto &c : m_bounded_ranges_constraints)
   1747  1.1.1.2  mrg       con_arr->append (c.to_json ());
   1748  1.1.1.2  mrg     cm_obj->set ("bounded_ranges_constraints", con_arr);
   1749  1.1.1.2  mrg   }
   1750  1.1.1.2  mrg 
   1751  1.1.1.2  mrg   return cm_obj;
   1752  1.1.1.2  mrg }
   1753  1.1.1.2  mrg 
   1754      1.1  mrg /* Attempt to add the constraint LHS OP RHS to this constraint_manager.
   1755      1.1  mrg    Return true if the constraint could be added (or is already true).
   1756      1.1  mrg    Return false if the constraint contradicts existing knowledge.  */
   1757      1.1  mrg 
   1758      1.1  mrg bool
   1759  1.1.1.2  mrg constraint_manager::add_constraint (const svalue *lhs,
   1760  1.1.1.2  mrg 				     enum tree_code op,
   1761  1.1.1.2  mrg 				     const svalue *rhs)
   1762  1.1.1.2  mrg {
   1763  1.1.1.2  mrg   lhs = lhs->unwrap_any_unmergeable ();
   1764  1.1.1.2  mrg   rhs = rhs->unwrap_any_unmergeable ();
   1765  1.1.1.2  mrg 
   1766  1.1.1.2  mrg   /* Nothing can be known about unknown/poisoned values.  */
   1767  1.1.1.2  mrg   if (!lhs->can_have_associated_state_p ()
   1768  1.1.1.2  mrg       || !rhs->can_have_associated_state_p ())
   1769  1.1.1.2  mrg     /* Not a contradiction.  */
   1770  1.1.1.2  mrg     return true;
   1771  1.1.1.2  mrg 
   1772  1.1.1.2  mrg   /* Check the conditions on svalues.  */
   1773  1.1.1.2  mrg   {
   1774  1.1.1.2  mrg     tristate t_cond = eval_condition (lhs, op, rhs);
   1775  1.1.1.2  mrg 
   1776  1.1.1.2  mrg     /* If we already have the condition, do nothing.  */
   1777  1.1.1.2  mrg     if (t_cond.is_true ())
   1778  1.1.1.2  mrg       return true;
   1779  1.1.1.2  mrg 
   1780  1.1.1.2  mrg     /* Reject a constraint that would contradict existing knowledge, as
   1781  1.1.1.2  mrg        unsatisfiable.  */
   1782  1.1.1.2  mrg     if (t_cond.is_false ())
   1783  1.1.1.2  mrg       return false;
   1784  1.1.1.2  mrg   }
   1785  1.1.1.2  mrg 
   1786      1.1  mrg   equiv_class_id lhs_ec_id = get_or_add_equiv_class (lhs);
   1787      1.1  mrg   equiv_class_id rhs_ec_id = get_or_add_equiv_class (rhs);
   1788  1.1.1.2  mrg 
   1789  1.1.1.2  mrg   /* Check the stronger conditions on ECs.  */
   1790  1.1.1.2  mrg   {
   1791  1.1.1.2  mrg     tristate t = eval_condition (lhs_ec_id, op, rhs_ec_id);
   1792  1.1.1.2  mrg 
   1793  1.1.1.2  mrg     /* Discard constraints that are already known.  */
   1794  1.1.1.2  mrg     if (t.is_true ())
   1795  1.1.1.2  mrg       return true;
   1796  1.1.1.2  mrg 
   1797  1.1.1.2  mrg     /* Reject unsatisfiable constraints.  */
   1798  1.1.1.2  mrg     if (t.is_false ())
   1799  1.1.1.2  mrg       return false;
   1800  1.1.1.2  mrg   }
   1801  1.1.1.2  mrg 
   1802  1.1.1.2  mrg   /* If adding
   1803  1.1.1.2  mrg        (SVAL + OFFSET) > CST,
   1804  1.1.1.2  mrg      then that can imply:
   1805  1.1.1.2  mrg        SVAL > (CST - OFFSET).  */
   1806  1.1.1.2  mrg   if (const binop_svalue *lhs_binop = lhs->dyn_cast_binop_svalue ())
   1807  1.1.1.2  mrg     if (tree rhs_cst = rhs->maybe_get_constant ())
   1808  1.1.1.2  mrg       if (tree offset = lhs_binop->get_arg1 ()->maybe_get_constant ())
   1809  1.1.1.2  mrg 	if ((op == GT_EXPR || op == LT_EXPR
   1810  1.1.1.2  mrg 	     || op == GE_EXPR || op == LE_EXPR)
   1811  1.1.1.2  mrg 	    && lhs_binop->get_op () == PLUS_EXPR)
   1812  1.1.1.2  mrg 	  {
   1813  1.1.1.2  mrg 	    tree offset_of_cst = fold_build2 (MINUS_EXPR, TREE_TYPE (rhs_cst),
   1814  1.1.1.2  mrg 					      rhs_cst, offset);
   1815  1.1.1.2  mrg 	    const svalue *implied_lhs = lhs_binop->get_arg0 ();
   1816  1.1.1.2  mrg 	    enum tree_code implied_op = op;
   1817  1.1.1.2  mrg 	    const svalue *implied_rhs
   1818  1.1.1.2  mrg 	      = m_mgr->get_or_create_constant_svalue (offset_of_cst);
   1819  1.1.1.2  mrg 	    if (!add_constraint (implied_lhs, implied_op, implied_rhs))
   1820  1.1.1.2  mrg 	      return false;
   1821  1.1.1.2  mrg 	    /* The above add_constraint could lead to EC merger, so we need
   1822  1.1.1.2  mrg 	       to refresh the EC IDs.  */
   1823  1.1.1.2  mrg 	    lhs_ec_id = get_or_add_equiv_class (lhs);
   1824  1.1.1.2  mrg 	    rhs_ec_id = get_or_add_equiv_class (rhs);
   1825  1.1.1.2  mrg 	  }
   1826  1.1.1.2  mrg 
   1827  1.1.1.2  mrg   add_unknown_constraint (lhs_ec_id, op, rhs_ec_id);
   1828  1.1.1.2  mrg   return true;
   1829      1.1  mrg }
   1830      1.1  mrg 
   1831      1.1  mrg /* Attempt to add the constraint LHS_EC_ID OP RHS_EC_ID to this
   1832      1.1  mrg    constraint_manager.
   1833      1.1  mrg    Return true if the constraint could be added (or is already true).
   1834      1.1  mrg    Return false if the constraint contradicts existing knowledge.  */
   1835      1.1  mrg 
   1836      1.1  mrg bool
   1837      1.1  mrg constraint_manager::add_constraint (equiv_class_id lhs_ec_id,
   1838  1.1.1.2  mrg 				     enum tree_code op,
   1839  1.1.1.2  mrg 				     equiv_class_id rhs_ec_id)
   1840      1.1  mrg {
   1841      1.1  mrg   tristate t = eval_condition (lhs_ec_id, op, rhs_ec_id);
   1842      1.1  mrg 
   1843      1.1  mrg   /* Discard constraints that are already known.  */
   1844      1.1  mrg   if (t.is_true ())
   1845      1.1  mrg     return true;
   1846      1.1  mrg 
   1847      1.1  mrg   /* Reject unsatisfiable constraints.  */
   1848      1.1  mrg   if (t.is_false ())
   1849      1.1  mrg     return false;
   1850      1.1  mrg 
   1851  1.1.1.2  mrg   add_unknown_constraint (lhs_ec_id, op, rhs_ec_id);
   1852  1.1.1.2  mrg   return true;
   1853  1.1.1.2  mrg }
   1854  1.1.1.2  mrg 
   1855  1.1.1.2  mrg /* Add the constraint LHS_EC_ID OP RHS_EC_ID to this constraint_manager,
   1856  1.1.1.2  mrg    where the constraint has already been checked for being "unknown".  */
   1857  1.1.1.2  mrg 
   1858  1.1.1.2  mrg void
   1859  1.1.1.2  mrg constraint_manager::add_unknown_constraint (equiv_class_id lhs_ec_id,
   1860  1.1.1.2  mrg 					     enum tree_code op,
   1861  1.1.1.2  mrg 					     equiv_class_id rhs_ec_id)
   1862  1.1.1.2  mrg {
   1863      1.1  mrg   gcc_assert (lhs_ec_id != rhs_ec_id);
   1864      1.1  mrg 
   1865      1.1  mrg   /* For now, simply accumulate constraints, without attempting any further
   1866      1.1  mrg      optimization.  */
   1867      1.1  mrg   switch (op)
   1868      1.1  mrg     {
   1869      1.1  mrg     case EQ_EXPR:
   1870      1.1  mrg       {
   1871      1.1  mrg 	/* Merge rhs_ec into lhs_ec.  */
   1872      1.1  mrg 	equiv_class &lhs_ec_obj = lhs_ec_id.get_obj (*this);
   1873      1.1  mrg 	const equiv_class &rhs_ec_obj = rhs_ec_id.get_obj (*this);
   1874      1.1  mrg 
   1875      1.1  mrg 	int i;
   1876  1.1.1.2  mrg 	const svalue *sval;
   1877  1.1.1.2  mrg 	FOR_EACH_VEC_ELT (rhs_ec_obj.m_vars, i, sval)
   1878  1.1.1.2  mrg 	  lhs_ec_obj.add (sval);
   1879      1.1  mrg 
   1880      1.1  mrg 	if (rhs_ec_obj.m_constant)
   1881      1.1  mrg 	  {
   1882      1.1  mrg 	    lhs_ec_obj.m_constant = rhs_ec_obj.m_constant;
   1883  1.1.1.2  mrg 	    lhs_ec_obj.m_cst_sval = rhs_ec_obj.m_cst_sval;
   1884      1.1  mrg 	  }
   1885      1.1  mrg 
   1886      1.1  mrg 	/* Drop rhs equivalence class, overwriting it with the
   1887      1.1  mrg 	   final ec (which might be the same one).  */
   1888      1.1  mrg 	equiv_class_id final_ec_id = m_equiv_classes.length () - 1;
   1889      1.1  mrg 	equiv_class *old_ec = m_equiv_classes[rhs_ec_id.m_idx];
   1890      1.1  mrg 	equiv_class *final_ec = m_equiv_classes.pop ();
   1891      1.1  mrg 	if (final_ec != old_ec)
   1892      1.1  mrg 	  m_equiv_classes[rhs_ec_id.m_idx] = final_ec;
   1893      1.1  mrg 	delete old_ec;
   1894  1.1.1.2  mrg 	if (lhs_ec_id == final_ec_id)
   1895  1.1.1.2  mrg 	  lhs_ec_id = rhs_ec_id;
   1896      1.1  mrg 
   1897      1.1  mrg 	/* Update the constraints.  */
   1898      1.1  mrg 	constraint *c;
   1899      1.1  mrg 	FOR_EACH_VEC_ELT (m_constraints, i, c)
   1900      1.1  mrg 	  {
   1901      1.1  mrg 	    /* Update references to the rhs_ec so that
   1902      1.1  mrg 	       they refer to the lhs_ec.  */
   1903      1.1  mrg 	    if (c->m_lhs == rhs_ec_id)
   1904      1.1  mrg 	      c->m_lhs = lhs_ec_id;
   1905      1.1  mrg 	    if (c->m_rhs == rhs_ec_id)
   1906      1.1  mrg 	      c->m_rhs = lhs_ec_id;
   1907      1.1  mrg 
   1908      1.1  mrg 	    /* Renumber all constraints that refer to the final rhs_ec
   1909      1.1  mrg 	       to the old rhs_ec, where the old final_ec now lives.  */
   1910      1.1  mrg 	    if (c->m_lhs == final_ec_id)
   1911      1.1  mrg 	      c->m_lhs = rhs_ec_id;
   1912      1.1  mrg 	    if (c->m_rhs == final_ec_id)
   1913      1.1  mrg 	      c->m_rhs = rhs_ec_id;
   1914      1.1  mrg 	  }
   1915  1.1.1.2  mrg 	bounded_ranges_constraint *brc;
   1916  1.1.1.2  mrg 	FOR_EACH_VEC_ELT (m_bounded_ranges_constraints, i, brc)
   1917  1.1.1.2  mrg 	  {
   1918  1.1.1.2  mrg 	    if (brc->m_ec_id == rhs_ec_id)
   1919  1.1.1.2  mrg 	      brc->m_ec_id = lhs_ec_id;
   1920  1.1.1.2  mrg 	    if (brc->m_ec_id == final_ec_id)
   1921  1.1.1.2  mrg 	      brc->m_ec_id = rhs_ec_id;
   1922  1.1.1.2  mrg 	  }
   1923  1.1.1.2  mrg 
   1924  1.1.1.2  mrg 	/* We may now have self-comparisons due to the merger; these
   1925  1.1.1.2  mrg 	   constraints should be removed.  */
   1926  1.1.1.2  mrg 	unsigned read_index, write_index;
   1927  1.1.1.2  mrg 	VEC_ORDERED_REMOVE_IF (m_constraints, read_index, write_index, c,
   1928  1.1.1.2  mrg 			       (c->m_lhs == c->m_rhs));
   1929      1.1  mrg       }
   1930      1.1  mrg       break;
   1931      1.1  mrg     case GE_EXPR:
   1932      1.1  mrg       add_constraint_internal (rhs_ec_id, CONSTRAINT_LE, lhs_ec_id);
   1933      1.1  mrg       break;
   1934      1.1  mrg     case LE_EXPR:
   1935      1.1  mrg       add_constraint_internal (lhs_ec_id, CONSTRAINT_LE, rhs_ec_id);
   1936      1.1  mrg       break;
   1937      1.1  mrg     case NE_EXPR:
   1938      1.1  mrg       add_constraint_internal (lhs_ec_id, CONSTRAINT_NE, rhs_ec_id);
   1939      1.1  mrg       break;
   1940      1.1  mrg     case GT_EXPR:
   1941      1.1  mrg       add_constraint_internal (rhs_ec_id, CONSTRAINT_LT, lhs_ec_id);
   1942      1.1  mrg       break;
   1943      1.1  mrg     case LT_EXPR:
   1944      1.1  mrg       add_constraint_internal (lhs_ec_id, CONSTRAINT_LT, rhs_ec_id);
   1945      1.1  mrg       break;
   1946      1.1  mrg     default:
   1947      1.1  mrg       /* do nothing.  */
   1948      1.1  mrg       break;
   1949      1.1  mrg     }
   1950      1.1  mrg   validate ();
   1951      1.1  mrg }
   1952      1.1  mrg 
   1953      1.1  mrg /* Subroutine of constraint_manager::add_constraint, for handling all
   1954      1.1  mrg    operations other than equality (for which equiv classes are merged).  */
   1955      1.1  mrg 
   1956      1.1  mrg void
   1957      1.1  mrg constraint_manager::add_constraint_internal (equiv_class_id lhs_id,
   1958      1.1  mrg 					     enum constraint_op c_op,
   1959      1.1  mrg 					     equiv_class_id rhs_id)
   1960      1.1  mrg {
   1961  1.1.1.2  mrg   if (m_constraints.length () >= (unsigned)param_analyzer_max_constraints)
   1962  1.1.1.2  mrg     return;
   1963  1.1.1.2  mrg 
   1964  1.1.1.2  mrg   constraint new_c (lhs_id, c_op, rhs_id);
   1965  1.1.1.2  mrg 
   1966  1.1.1.2  mrg   /* Remove existing constraints that would be implied by the
   1967  1.1.1.2  mrg      new constraint.  */
   1968  1.1.1.2  mrg   unsigned read_index, write_index;
   1969  1.1.1.2  mrg   constraint *c;
   1970  1.1.1.2  mrg   VEC_ORDERED_REMOVE_IF (m_constraints, read_index, write_index, c,
   1971  1.1.1.2  mrg 			 (c->implied_by (new_c, *this)));
   1972  1.1.1.2  mrg 
   1973      1.1  mrg   /* Add the constraint.  */
   1974  1.1.1.2  mrg   m_constraints.safe_push (new_c);
   1975  1.1.1.2  mrg 
   1976  1.1.1.2  mrg   /* We don't yet update m_bounded_ranges_constraints here yet.  */
   1977      1.1  mrg 
   1978      1.1  mrg   if (!flag_analyzer_transitivity)
   1979      1.1  mrg     return;
   1980      1.1  mrg 
   1981      1.1  mrg   if (c_op != CONSTRAINT_NE)
   1982      1.1  mrg     {
   1983      1.1  mrg       /* The following can potentially add EQ_EXPR facts, which could lead
   1984      1.1  mrg 	 to ECs being merged, which would change the meaning of the EC IDs.
   1985      1.1  mrg 	 Hence we need to do this via representatives.  */
   1986  1.1.1.2  mrg       const svalue *lhs = lhs_id.get_obj (*this).get_representative ();
   1987  1.1.1.2  mrg       const svalue *rhs = rhs_id.get_obj (*this).get_representative ();
   1988      1.1  mrg 
   1989      1.1  mrg       /* We have LHS </<= RHS */
   1990      1.1  mrg 
   1991      1.1  mrg       /* Handle transitivity of ordering by adding additional constraints
   1992      1.1  mrg 	 based on what we already knew.
   1993      1.1  mrg 
   1994      1.1  mrg 	 So if we have already have:
   1995      1.1  mrg 	   (a < b)
   1996      1.1  mrg 	   (c < d)
   1997      1.1  mrg 	 Then adding:
   1998      1.1  mrg 	   (b < c)
   1999      1.1  mrg 	 will also add:
   2000      1.1  mrg 	   (a < c)
   2001      1.1  mrg 	   (b < d)
   2002      1.1  mrg 	 We need to recurse to ensure we also add:
   2003      1.1  mrg 	   (a < d).
   2004      1.1  mrg 	 We call the checked add_constraint to avoid adding constraints
   2005      1.1  mrg 	 that are already present.  Doing so also ensures termination
   2006      1.1  mrg 	 in the case of cycles.
   2007      1.1  mrg 
   2008      1.1  mrg 	 We also check for single-element ranges, adding EQ_EXPR facts
   2009      1.1  mrg 	 where we discover them.  For example 3 < x < 5 implies
   2010      1.1  mrg 	 that x == 4 (if x is an integer).  */
   2011      1.1  mrg       for (unsigned i = 0; i < m_constraints.length (); i++)
   2012      1.1  mrg 	{
   2013      1.1  mrg 	  const constraint *other = &m_constraints[i];
   2014      1.1  mrg 	  if (other->is_ordering_p ())
   2015      1.1  mrg 	    {
   2016      1.1  mrg 	      /* Refresh the EC IDs, in case any mergers have happened.  */
   2017      1.1  mrg 	      lhs_id = get_or_add_equiv_class (lhs);
   2018      1.1  mrg 	      rhs_id = get_or_add_equiv_class (rhs);
   2019      1.1  mrg 
   2020      1.1  mrg 	      tree lhs_const = lhs_id.get_obj (*this).m_constant;
   2021      1.1  mrg 	      tree rhs_const = rhs_id.get_obj (*this).m_constant;
   2022      1.1  mrg 	      tree other_lhs_const
   2023      1.1  mrg 		= other->m_lhs.get_obj (*this).m_constant;
   2024      1.1  mrg 	      tree other_rhs_const
   2025      1.1  mrg 		= other->m_rhs.get_obj (*this).m_constant;
   2026      1.1  mrg 
   2027      1.1  mrg 	      /* We have "LHS </<= RHS" and "other.lhs </<= other.rhs".  */
   2028      1.1  mrg 
   2029      1.1  mrg 	      /* If we have LHS </<= RHS and RHS </<= LHS, then we have a
   2030      1.1  mrg 		 cycle.  */
   2031      1.1  mrg 	      if (rhs_id == other->m_lhs
   2032      1.1  mrg 		  && other->m_rhs == lhs_id)
   2033      1.1  mrg 		{
   2034      1.1  mrg 		  /* We must have equality for this to be possible.  */
   2035      1.1  mrg 		  gcc_assert (c_op == CONSTRAINT_LE
   2036      1.1  mrg 			      && other->m_op == CONSTRAINT_LE);
   2037      1.1  mrg 		  add_constraint (lhs_id, EQ_EXPR, rhs_id);
   2038      1.1  mrg 		  /* Adding an equality will merge the two ECs and potentially
   2039      1.1  mrg 		     reorganize the constraints.  Stop iterating.  */
   2040      1.1  mrg 		  return;
   2041      1.1  mrg 		}
   2042      1.1  mrg 	      /* Otherwise, check for transitivity.  */
   2043      1.1  mrg 	      if (rhs_id == other->m_lhs)
   2044      1.1  mrg 		{
   2045      1.1  mrg 		  /* With RHS == other.lhs, we have:
   2046      1.1  mrg 		     "LHS </<= (RHS, other.lhs) </<= other.rhs"
   2047      1.1  mrg 		     and thus this implies "LHS </<= other.rhs".  */
   2048      1.1  mrg 
   2049      1.1  mrg 		  /* Do we have a tightly-constrained range?  */
   2050      1.1  mrg 		  if (lhs_const
   2051      1.1  mrg 		      && !rhs_const
   2052      1.1  mrg 		      && other_rhs_const)
   2053      1.1  mrg 		    {
   2054      1.1  mrg 		      range r (bound (lhs_const, c_op == CONSTRAINT_LE),
   2055      1.1  mrg 			       bound (other_rhs_const,
   2056      1.1  mrg 				      other->m_op == CONSTRAINT_LE));
   2057  1.1.1.2  mrg 		      if (tree constant = r.constrained_to_single_element ())
   2058      1.1  mrg 			{
   2059  1.1.1.2  mrg 			  const svalue *cst_sval
   2060  1.1.1.2  mrg 			    = m_mgr->get_or_create_constant_svalue (constant);
   2061      1.1  mrg 			  add_constraint
   2062      1.1  mrg 			    (rhs_id, EQ_EXPR,
   2063  1.1.1.2  mrg 			     get_or_add_equiv_class (cst_sval));
   2064      1.1  mrg 			  return;
   2065      1.1  mrg 			}
   2066      1.1  mrg 		    }
   2067      1.1  mrg 
   2068      1.1  mrg 		  /* Otherwise, add the constraint implied by transitivity.  */
   2069      1.1  mrg 		  enum tree_code new_op
   2070      1.1  mrg 		    = ((c_op == CONSTRAINT_LE && other->m_op == CONSTRAINT_LE)
   2071      1.1  mrg 		       ? LE_EXPR : LT_EXPR);
   2072      1.1  mrg 		  add_constraint (lhs_id, new_op, other->m_rhs);
   2073      1.1  mrg 		}
   2074      1.1  mrg 	      else if (other->m_rhs == lhs_id)
   2075      1.1  mrg 		{
   2076      1.1  mrg 		  /* With other.rhs == LHS, we have:
   2077      1.1  mrg 		     "other.lhs </<= (other.rhs, LHS) </<= RHS"
   2078      1.1  mrg 		     and thus this implies "other.lhs </<= RHS".  */
   2079      1.1  mrg 
   2080      1.1  mrg 		  /* Do we have a tightly-constrained range?  */
   2081      1.1  mrg 		  if (other_lhs_const
   2082      1.1  mrg 		      && !lhs_const
   2083      1.1  mrg 		      && rhs_const)
   2084      1.1  mrg 		    {
   2085      1.1  mrg 		      range r (bound (other_lhs_const,
   2086      1.1  mrg 				      other->m_op == CONSTRAINT_LE),
   2087      1.1  mrg 			       bound (rhs_const,
   2088      1.1  mrg 				      c_op == CONSTRAINT_LE));
   2089  1.1.1.2  mrg 		      if (tree constant = r.constrained_to_single_element ())
   2090      1.1  mrg 			{
   2091  1.1.1.2  mrg 			  const svalue *cst_sval
   2092  1.1.1.2  mrg 			    = m_mgr->get_or_create_constant_svalue (constant);
   2093      1.1  mrg 			  add_constraint
   2094      1.1  mrg 			    (lhs_id, EQ_EXPR,
   2095  1.1.1.2  mrg 			     get_or_add_equiv_class (cst_sval));
   2096      1.1  mrg 			  return;
   2097      1.1  mrg 			}
   2098      1.1  mrg 		    }
   2099      1.1  mrg 
   2100      1.1  mrg 		  /* Otherwise, add the constraint implied by transitivity.  */
   2101      1.1  mrg 		  enum tree_code new_op
   2102      1.1  mrg 		    = ((c_op == CONSTRAINT_LE && other->m_op == CONSTRAINT_LE)
   2103      1.1  mrg 		       ? LE_EXPR : LT_EXPR);
   2104      1.1  mrg 		  add_constraint (other->m_lhs, new_op, rhs_id);
   2105      1.1  mrg 		}
   2106      1.1  mrg 	    }
   2107      1.1  mrg 	}
   2108      1.1  mrg     }
   2109      1.1  mrg }
   2110      1.1  mrg 
   2111  1.1.1.2  mrg /* Attempt to add the constraint that SVAL is within RANGES to this
   2112  1.1.1.2  mrg    constraint_manager.
   2113  1.1.1.2  mrg 
   2114  1.1.1.2  mrg    Return true if the constraint was successfully added (or is already
   2115  1.1.1.2  mrg    known to be true).
   2116  1.1.1.2  mrg    Return false if the constraint contradicts existing knowledge.  */
   2117  1.1.1.2  mrg 
   2118  1.1.1.2  mrg bool
   2119  1.1.1.2  mrg constraint_manager::add_bounded_ranges (const svalue *sval,
   2120  1.1.1.2  mrg 					const bounded_ranges *ranges)
   2121  1.1.1.2  mrg {
   2122  1.1.1.2  mrg   sval = sval->unwrap_any_unmergeable ();
   2123  1.1.1.2  mrg 
   2124  1.1.1.2  mrg   /* Nothing can be known about unknown/poisoned values.  */
   2125  1.1.1.2  mrg   if (!sval->can_have_associated_state_p ())
   2126  1.1.1.2  mrg     /* Not a contradiction.  */
   2127  1.1.1.2  mrg     return true;
   2128  1.1.1.2  mrg 
   2129  1.1.1.2  mrg   /* If SVAL is a constant, then we can look at RANGES directly.  */
   2130  1.1.1.2  mrg   if (tree cst = sval->maybe_get_constant ())
   2131  1.1.1.2  mrg     {
   2132  1.1.1.2  mrg       /* If the ranges contain CST, then it's a successful no-op;
   2133  1.1.1.2  mrg 	 otherwise it's a contradiction.  */
   2134  1.1.1.2  mrg       return ranges->contain_p (cst);
   2135  1.1.1.2  mrg     }
   2136  1.1.1.2  mrg 
   2137  1.1.1.2  mrg   equiv_class_id ec_id = get_or_add_equiv_class (sval);
   2138  1.1.1.2  mrg 
   2139  1.1.1.2  mrg   /* If the EC has a constant, it's either true or false.  */
   2140  1.1.1.2  mrg   const equiv_class &ec = ec_id.get_obj (*this);
   2141  1.1.1.2  mrg   if (tree ec_cst = ec.get_any_constant ())
   2142  1.1.1.2  mrg     {
   2143  1.1.1.2  mrg       if (ranges->contain_p (ec_cst))
   2144  1.1.1.2  mrg 	/* We already have SVAL == EC_CST, within RANGES, so
   2145  1.1.1.2  mrg 	   we can discard RANGES and succeed.  */
   2146  1.1.1.2  mrg 	return true;
   2147  1.1.1.2  mrg       else
   2148  1.1.1.2  mrg 	/* We already have SVAL == EC_CST, not within RANGES, so
   2149  1.1.1.2  mrg 	   we can reject RANGES as a contradiction.  */
   2150  1.1.1.2  mrg 	return false;
   2151  1.1.1.2  mrg     }
   2152  1.1.1.2  mrg 
   2153  1.1.1.2  mrg   /* We have at most one per ec_id.  */
   2154  1.1.1.2  mrg   /* Iterate through each range in RANGES.  */
   2155  1.1.1.2  mrg   for (auto iter : m_bounded_ranges_constraints)
   2156  1.1.1.2  mrg     {
   2157  1.1.1.2  mrg       if (iter.m_ec_id == ec_id)
   2158  1.1.1.2  mrg 	{
   2159  1.1.1.2  mrg 	  /* Update with intersection, or fail if empty.  */
   2160  1.1.1.2  mrg 	  bounded_ranges_manager *mgr = get_range_manager ();
   2161  1.1.1.2  mrg 	  const bounded_ranges *intersection
   2162  1.1.1.2  mrg 	    = mgr->get_or_create_intersection (iter.m_ranges, ranges);
   2163  1.1.1.2  mrg 	  if (intersection->empty_p ())
   2164  1.1.1.2  mrg 	    {
   2165  1.1.1.2  mrg 	      /* No intersection; fail.  */
   2166  1.1.1.2  mrg 	      return false;
   2167  1.1.1.2  mrg 	    }
   2168  1.1.1.2  mrg 	  else
   2169  1.1.1.2  mrg 	    {
   2170  1.1.1.2  mrg 	      /* Update with intersection; succeed.  */
   2171  1.1.1.2  mrg 	      iter.m_ranges = intersection;
   2172  1.1.1.2  mrg 	      validate ();
   2173  1.1.1.2  mrg 	      return true;
   2174  1.1.1.2  mrg 	    }
   2175  1.1.1.2  mrg 	}
   2176  1.1.1.2  mrg     }
   2177  1.1.1.2  mrg   m_bounded_ranges_constraints.safe_push
   2178  1.1.1.2  mrg     (bounded_ranges_constraint (ec_id, ranges));
   2179  1.1.1.2  mrg 
   2180  1.1.1.2  mrg   validate ();
   2181  1.1.1.2  mrg 
   2182  1.1.1.2  mrg   return true;
   2183  1.1.1.2  mrg }
   2184  1.1.1.2  mrg 
   2185  1.1.1.2  mrg /* Look for SVAL within the equivalence classes of this constraint_manager;
   2186  1.1.1.2  mrg    if found, return true, writing the id to *OUT if OUT is non-NULL,
   2187  1.1.1.2  mrg    otherwise return false.  */
   2188      1.1  mrg 
   2189      1.1  mrg bool
   2190  1.1.1.2  mrg constraint_manager::get_equiv_class_by_svalue (const svalue *sval,
   2191  1.1.1.2  mrg 					       equiv_class_id *out) const
   2192      1.1  mrg {
   2193      1.1  mrg   /* TODO: should we have a map, rather than these searches?  */
   2194      1.1  mrg   int i;
   2195      1.1  mrg   equiv_class *ec;
   2196      1.1  mrg   FOR_EACH_VEC_ELT (m_equiv_classes, i, ec)
   2197      1.1  mrg     {
   2198      1.1  mrg       int j;
   2199  1.1.1.2  mrg       const svalue *iv;
   2200      1.1  mrg       FOR_EACH_VEC_ELT (ec->m_vars, j, iv)
   2201  1.1.1.2  mrg 	if (iv == sval)
   2202      1.1  mrg 	  {
   2203  1.1.1.2  mrg 	    if (out)
   2204  1.1.1.2  mrg 	      *out = equiv_class_id (i);
   2205      1.1  mrg 	    return true;
   2206      1.1  mrg 	  }
   2207      1.1  mrg     }
   2208      1.1  mrg   return false;
   2209      1.1  mrg }
   2210      1.1  mrg 
   2211  1.1.1.2  mrg /* Ensure that SVAL has an equivalence class within this constraint_manager;
   2212      1.1  mrg    return the ID of the class.  */
   2213      1.1  mrg 
   2214      1.1  mrg equiv_class_id
   2215  1.1.1.2  mrg constraint_manager::get_or_add_equiv_class (const svalue *sval)
   2216      1.1  mrg {
   2217      1.1  mrg   equiv_class_id result (-1);
   2218      1.1  mrg 
   2219  1.1.1.2  mrg   gcc_assert (sval->can_have_associated_state_p ());
   2220  1.1.1.2  mrg 
   2221  1.1.1.2  mrg   /* Convert all NULL pointers to (void *) to avoid state explosions
   2222  1.1.1.2  mrg      involving all of the various (foo *)NULL vs (bar *)NULL.  */
   2223  1.1.1.2  mrg   if (sval->get_type ())
   2224  1.1.1.2  mrg     if (POINTER_TYPE_P (sval->get_type ()))
   2225  1.1.1.2  mrg       if (tree cst = sval->maybe_get_constant ())
   2226  1.1.1.2  mrg 	if (zerop (cst))
   2227  1.1.1.2  mrg 	  sval = m_mgr->get_or_create_constant_svalue (null_pointer_node);
   2228  1.1.1.2  mrg 
   2229  1.1.1.2  mrg   /* Try svalue match.  */
   2230  1.1.1.2  mrg   if (get_equiv_class_by_svalue (sval, &result))
   2231      1.1  mrg     return result;
   2232      1.1  mrg 
   2233      1.1  mrg   /* Try equality of constants.  */
   2234  1.1.1.2  mrg   if (tree cst = sval->maybe_get_constant ())
   2235      1.1  mrg     {
   2236      1.1  mrg       int i;
   2237      1.1  mrg       equiv_class *ec;
   2238      1.1  mrg       FOR_EACH_VEC_ELT (m_equiv_classes, i, ec)
   2239      1.1  mrg 	if (ec->m_constant
   2240      1.1  mrg 	    && types_compatible_p (TREE_TYPE (cst),
   2241      1.1  mrg 				   TREE_TYPE (ec->m_constant)))
   2242      1.1  mrg 	  {
   2243      1.1  mrg 	    tree eq = fold_binary (EQ_EXPR, boolean_type_node,
   2244      1.1  mrg 				   cst, ec->m_constant);
   2245      1.1  mrg 	    if (eq == boolean_true_node)
   2246      1.1  mrg 	      {
   2247  1.1.1.2  mrg 		ec->add (sval);
   2248      1.1  mrg 		return equiv_class_id (i);
   2249      1.1  mrg 	      }
   2250      1.1  mrg 	  }
   2251      1.1  mrg     }
   2252      1.1  mrg 
   2253      1.1  mrg 
   2254      1.1  mrg   /* Not found.  */
   2255      1.1  mrg   equiv_class *new_ec = new equiv_class ();
   2256  1.1.1.2  mrg   new_ec->add (sval);
   2257      1.1  mrg   m_equiv_classes.safe_push (new_ec);
   2258      1.1  mrg 
   2259      1.1  mrg   equiv_class_id new_id (m_equiv_classes.length () - 1);
   2260      1.1  mrg 
   2261      1.1  mrg   return new_id;
   2262      1.1  mrg }
   2263      1.1  mrg 
   2264      1.1  mrg /* Evaluate the condition LHS_EC OP RHS_EC.  */
   2265      1.1  mrg 
   2266      1.1  mrg tristate
   2267      1.1  mrg constraint_manager::eval_condition (equiv_class_id lhs_ec,
   2268      1.1  mrg 				    enum tree_code op,
   2269  1.1.1.2  mrg 				    equiv_class_id rhs_ec) const
   2270      1.1  mrg {
   2271      1.1  mrg   if (lhs_ec == rhs_ec)
   2272      1.1  mrg     {
   2273      1.1  mrg       switch (op)
   2274      1.1  mrg 	{
   2275      1.1  mrg 	case EQ_EXPR:
   2276      1.1  mrg 	case GE_EXPR:
   2277      1.1  mrg 	case LE_EXPR:
   2278      1.1  mrg 	  return tristate (tristate::TS_TRUE);
   2279      1.1  mrg 
   2280      1.1  mrg 	case NE_EXPR:
   2281      1.1  mrg 	case GT_EXPR:
   2282      1.1  mrg 	case LT_EXPR:
   2283      1.1  mrg 	  return tristate (tristate::TS_FALSE);
   2284      1.1  mrg 	default:
   2285      1.1  mrg 	  break;
   2286      1.1  mrg 	}
   2287      1.1  mrg     }
   2288      1.1  mrg 
   2289      1.1  mrg   tree lhs_const = lhs_ec.get_obj (*this).get_any_constant ();
   2290      1.1  mrg   tree rhs_const = rhs_ec.get_obj (*this).get_any_constant ();
   2291      1.1  mrg   if (lhs_const && rhs_const)
   2292      1.1  mrg     {
   2293  1.1.1.2  mrg       tristate result_for_constants
   2294  1.1.1.2  mrg 	= compare_constants (lhs_const, op, rhs_const);
   2295  1.1.1.2  mrg       if (result_for_constants.is_known ())
   2296  1.1.1.2  mrg 	return result_for_constants;
   2297      1.1  mrg     }
   2298      1.1  mrg 
   2299      1.1  mrg   enum tree_code swapped_op = swap_tree_comparison (op);
   2300      1.1  mrg 
   2301      1.1  mrg   int i;
   2302      1.1  mrg   constraint *c;
   2303      1.1  mrg   FOR_EACH_VEC_ELT (m_constraints, i, c)
   2304      1.1  mrg     {
   2305      1.1  mrg       if (c->m_lhs == lhs_ec
   2306      1.1  mrg 	  && c->m_rhs == rhs_ec)
   2307      1.1  mrg 	{
   2308      1.1  mrg 	  tristate result_for_constraint
   2309      1.1  mrg 	    = eval_constraint_op_for_op (c->m_op, op);
   2310      1.1  mrg 	  if (result_for_constraint.is_known ())
   2311      1.1  mrg 	    return result_for_constraint;
   2312      1.1  mrg 	}
   2313  1.1.1.2  mrg       /* Swapped operands.  */
   2314  1.1.1.2  mrg       if (c->m_lhs == rhs_ec
   2315  1.1.1.2  mrg 	  && c->m_rhs == lhs_ec)
   2316  1.1.1.2  mrg 	{
   2317  1.1.1.2  mrg 	  tristate result_for_constraint
   2318  1.1.1.2  mrg 	    = eval_constraint_op_for_op (c->m_op, swapped_op);
   2319  1.1.1.2  mrg 	  if (result_for_constraint.is_known ())
   2320  1.1.1.2  mrg 	    return result_for_constraint;
   2321  1.1.1.2  mrg 	}
   2322  1.1.1.2  mrg     }
   2323  1.1.1.2  mrg 
   2324  1.1.1.2  mrg   /* We don't use m_bounded_ranges_constraints here yet.  */
   2325  1.1.1.2  mrg 
   2326  1.1.1.2  mrg   return tristate (tristate::TS_UNKNOWN);
   2327  1.1.1.2  mrg }
   2328  1.1.1.2  mrg 
   2329  1.1.1.2  mrg range
   2330  1.1.1.2  mrg constraint_manager::get_ec_bounds (equiv_class_id ec_id) const
   2331  1.1.1.2  mrg {
   2332  1.1.1.2  mrg   range result;
   2333  1.1.1.2  mrg 
   2334  1.1.1.2  mrg   int i;
   2335  1.1.1.2  mrg   constraint *c;
   2336  1.1.1.2  mrg   FOR_EACH_VEC_ELT (m_constraints, i, c)
   2337  1.1.1.2  mrg     {
   2338  1.1.1.2  mrg       if (c->m_lhs == ec_id)
   2339  1.1.1.2  mrg 	{
   2340  1.1.1.2  mrg 	  if (tree other_cst = c->m_rhs.get_obj (*this).get_any_constant ())
   2341  1.1.1.2  mrg 	    switch (c->m_op)
   2342  1.1.1.2  mrg 	      {
   2343  1.1.1.2  mrg 	      default:
   2344  1.1.1.2  mrg 		gcc_unreachable ();
   2345  1.1.1.2  mrg 	      case CONSTRAINT_NE:
   2346  1.1.1.2  mrg 		continue;
   2347  1.1.1.2  mrg 
   2348  1.1.1.2  mrg 	      case CONSTRAINT_LT:
   2349  1.1.1.2  mrg 		/* We have "EC_ID < OTHER_CST".  */
   2350  1.1.1.2  mrg 		result.add_bound (bound (other_cst, false), BK_UPPER);
   2351  1.1.1.2  mrg 		break;
   2352  1.1.1.2  mrg 
   2353  1.1.1.2  mrg 	      case CONSTRAINT_LE:
   2354  1.1.1.2  mrg 		/* We have "EC_ID <= OTHER_CST".  */
   2355  1.1.1.2  mrg 		result.add_bound (bound (other_cst, true), BK_UPPER);
   2356  1.1.1.2  mrg 		break;
   2357  1.1.1.2  mrg 	      }
   2358  1.1.1.2  mrg 	}
   2359  1.1.1.2  mrg       if (c->m_rhs == ec_id)
   2360  1.1.1.2  mrg 	{
   2361  1.1.1.2  mrg 	  if (tree other_cst = c->m_lhs.get_obj (*this).get_any_constant ())
   2362  1.1.1.2  mrg 	    switch (c->m_op)
   2363  1.1.1.2  mrg 	      {
   2364  1.1.1.2  mrg 	      default:
   2365  1.1.1.2  mrg 		gcc_unreachable ();
   2366  1.1.1.2  mrg 	      case CONSTRAINT_NE:
   2367  1.1.1.2  mrg 		continue;
   2368  1.1.1.2  mrg 
   2369  1.1.1.2  mrg 	      case CONSTRAINT_LT:
   2370  1.1.1.2  mrg 		/* We have "OTHER_CST < EC_ID"
   2371  1.1.1.2  mrg 		   i.e. "EC_ID > OTHER_CST".  */
   2372  1.1.1.2  mrg 		result.add_bound (bound (other_cst, false), BK_LOWER);
   2373  1.1.1.2  mrg 		break;
   2374  1.1.1.2  mrg 
   2375  1.1.1.2  mrg 	      case CONSTRAINT_LE:
   2376  1.1.1.2  mrg 		/* We have "OTHER_CST <= EC_ID"
   2377  1.1.1.2  mrg 		   i.e. "EC_ID >= OTHER_CST".  */
   2378  1.1.1.2  mrg 		result.add_bound (bound (other_cst, true), BK_LOWER);
   2379  1.1.1.2  mrg 		break;
   2380  1.1.1.2  mrg 	      }
   2381  1.1.1.2  mrg 	}
   2382  1.1.1.2  mrg     }
   2383  1.1.1.2  mrg 
   2384  1.1.1.2  mrg   return result;
   2385  1.1.1.2  mrg }
   2386  1.1.1.2  mrg 
   2387  1.1.1.2  mrg /* Evaluate the condition LHS_EC OP RHS_CONST, avoiding the creation
   2388  1.1.1.2  mrg    of equiv_class instances.  */
   2389  1.1.1.2  mrg 
   2390  1.1.1.2  mrg tristate
   2391  1.1.1.2  mrg constraint_manager::eval_condition (equiv_class_id lhs_ec,
   2392  1.1.1.2  mrg 				    enum tree_code op,
   2393  1.1.1.2  mrg 				    tree rhs_const) const
   2394  1.1.1.2  mrg {
   2395  1.1.1.2  mrg   gcc_assert (!lhs_ec.null_p ());
   2396  1.1.1.2  mrg   gcc_assert (CONSTANT_CLASS_P (rhs_const));
   2397  1.1.1.2  mrg 
   2398  1.1.1.2  mrg   if (tree lhs_const = lhs_ec.get_obj (*this).get_any_constant ())
   2399  1.1.1.2  mrg     return compare_constants (lhs_const, op, rhs_const);
   2400  1.1.1.2  mrg 
   2401  1.1.1.2  mrg   /* Check for known inequalities of the form
   2402  1.1.1.2  mrg        (LHS_EC != OTHER_CST) or (OTHER_CST != LHS_EC).
   2403  1.1.1.2  mrg      If RHS_CONST == OTHER_CST, then we also know that LHS_EC != OTHER_CST.
   2404  1.1.1.2  mrg      For example, we might have the constraint
   2405  1.1.1.2  mrg        ptr != (void *)0
   2406  1.1.1.2  mrg      so we want the condition
   2407  1.1.1.2  mrg        ptr == (foo *)0
   2408  1.1.1.2  mrg      to be false.  */
   2409  1.1.1.2  mrg   int i;
   2410  1.1.1.2  mrg   constraint *c;
   2411  1.1.1.2  mrg   FOR_EACH_VEC_ELT (m_constraints, i, c)
   2412  1.1.1.2  mrg     {
   2413  1.1.1.2  mrg       if (c->m_op == CONSTRAINT_NE)
   2414  1.1.1.2  mrg 	{
   2415  1.1.1.2  mrg 	  if (c->m_lhs == lhs_ec)
   2416  1.1.1.2  mrg 	    {
   2417  1.1.1.2  mrg 	      if (tree other_cst = c->m_rhs.get_obj (*this).get_any_constant ())
   2418  1.1.1.2  mrg 		if (compare_constants
   2419  1.1.1.2  mrg 		      (rhs_const, EQ_EXPR, other_cst).is_true ())
   2420  1.1.1.2  mrg 		  {
   2421  1.1.1.2  mrg 		    switch (op)
   2422  1.1.1.2  mrg 		      {
   2423  1.1.1.2  mrg 		      case EQ_EXPR:
   2424  1.1.1.2  mrg 			return tristate (tristate::TS_FALSE);
   2425  1.1.1.2  mrg 		      case NE_EXPR:
   2426  1.1.1.2  mrg 			return tristate (tristate::TS_TRUE);
   2427  1.1.1.2  mrg 		      default:
   2428  1.1.1.2  mrg 			break;
   2429  1.1.1.2  mrg 		      }
   2430  1.1.1.2  mrg 		  }
   2431  1.1.1.2  mrg 	    }
   2432  1.1.1.2  mrg 	  if (c->m_rhs == lhs_ec)
   2433  1.1.1.2  mrg 	    {
   2434  1.1.1.2  mrg 	      if (tree other_cst = c->m_lhs.get_obj (*this).get_any_constant ())
   2435  1.1.1.2  mrg 		if (compare_constants
   2436  1.1.1.2  mrg 		      (rhs_const, EQ_EXPR, other_cst).is_true ())
   2437  1.1.1.2  mrg 		  {
   2438  1.1.1.2  mrg 		    switch (op)
   2439  1.1.1.2  mrg 		      {
   2440  1.1.1.2  mrg 		      case EQ_EXPR:
   2441  1.1.1.2  mrg 			return tristate (tristate::TS_FALSE);
   2442  1.1.1.2  mrg 		      case NE_EXPR:
   2443  1.1.1.2  mrg 			return tristate (tristate::TS_TRUE);
   2444  1.1.1.2  mrg 		      default:
   2445  1.1.1.2  mrg 			break;
   2446  1.1.1.2  mrg 		      }
   2447  1.1.1.2  mrg 		  }
   2448  1.1.1.2  mrg 	    }
   2449  1.1.1.2  mrg 	}
   2450  1.1.1.2  mrg     }
   2451  1.1.1.2  mrg 
   2452  1.1.1.2  mrg   bounded_ranges_manager *mgr = get_range_manager ();
   2453  1.1.1.2  mrg   for (const auto &iter : m_bounded_ranges_constraints)
   2454  1.1.1.2  mrg     if (iter.m_ec_id == lhs_ec)
   2455  1.1.1.2  mrg       return iter.m_ranges->eval_condition (op, rhs_const, mgr);
   2456  1.1.1.2  mrg 
   2457  1.1.1.2  mrg   /* Look at existing bounds on LHS_EC.  */
   2458  1.1.1.2  mrg   range lhs_bounds = get_ec_bounds (lhs_ec);
   2459  1.1.1.2  mrg   tristate result = lhs_bounds.eval_condition (op, rhs_const);
   2460  1.1.1.2  mrg   if (result.is_known ())
   2461  1.1.1.2  mrg     return result;
   2462  1.1.1.2  mrg 
   2463  1.1.1.2  mrg   /* Also reject if range::add_bound fails.  */
   2464  1.1.1.2  mrg   if (!lhs_bounds.add_bound (op, rhs_const))
   2465  1.1.1.2  mrg     return tristate (false);
   2466  1.1.1.2  mrg 
   2467  1.1.1.2  mrg   return tristate::unknown ();
   2468  1.1.1.2  mrg }
   2469  1.1.1.2  mrg 
   2470  1.1.1.2  mrg /* Evaluate the condition LHS OP RHS, without modifying this
   2471  1.1.1.2  mrg    constraint_manager (avoiding the creation of equiv_class instances).  */
   2472  1.1.1.2  mrg 
   2473  1.1.1.2  mrg tristate
   2474  1.1.1.2  mrg constraint_manager::eval_condition (const svalue *lhs,
   2475  1.1.1.2  mrg 				    enum tree_code op,
   2476  1.1.1.2  mrg 				    const svalue *rhs) const
   2477  1.1.1.2  mrg {
   2478  1.1.1.2  mrg   lhs = lhs->unwrap_any_unmergeable ();
   2479  1.1.1.2  mrg   rhs = rhs->unwrap_any_unmergeable ();
   2480  1.1.1.2  mrg 
   2481  1.1.1.2  mrg   /* Nothing can be known about unknown or poisoned values.  */
   2482  1.1.1.2  mrg   if (lhs->get_kind () == SK_UNKNOWN
   2483  1.1.1.2  mrg       || lhs->get_kind () == SK_POISONED
   2484  1.1.1.2  mrg       || rhs->get_kind () == SK_UNKNOWN
   2485  1.1.1.2  mrg       || rhs->get_kind () == SK_POISONED)
   2486  1.1.1.2  mrg     return tristate (tristate::TS_UNKNOWN);
   2487  1.1.1.2  mrg 
   2488  1.1.1.2  mrg   if (lhs == rhs
   2489  1.1.1.2  mrg       && !(FLOAT_TYPE_P (lhs->get_type ())
   2490  1.1.1.2  mrg 	   || FLOAT_TYPE_P (rhs->get_type ())))
   2491  1.1.1.2  mrg     {
   2492  1.1.1.2  mrg       switch (op)
   2493  1.1.1.2  mrg 	{
   2494  1.1.1.2  mrg 	case EQ_EXPR:
   2495  1.1.1.2  mrg 	case GE_EXPR:
   2496  1.1.1.2  mrg 	case LE_EXPR:
   2497  1.1.1.2  mrg 	  return tristate (tristate::TS_TRUE);
   2498  1.1.1.2  mrg 
   2499  1.1.1.2  mrg 	case NE_EXPR:
   2500  1.1.1.2  mrg 	case GT_EXPR:
   2501  1.1.1.2  mrg 	case LT_EXPR:
   2502  1.1.1.2  mrg 	  return tristate (tristate::TS_FALSE);
   2503  1.1.1.2  mrg 	default:
   2504  1.1.1.2  mrg 	  break;
   2505  1.1.1.2  mrg 	}
   2506  1.1.1.2  mrg     }
   2507  1.1.1.2  mrg 
   2508  1.1.1.2  mrg   equiv_class_id lhs_ec (-1);
   2509  1.1.1.2  mrg   equiv_class_id rhs_ec (-1);
   2510  1.1.1.2  mrg   get_equiv_class_by_svalue (lhs, &lhs_ec);
   2511  1.1.1.2  mrg   get_equiv_class_by_svalue (rhs, &rhs_ec);
   2512  1.1.1.2  mrg   if (!lhs_ec.null_p () && !rhs_ec.null_p ())
   2513  1.1.1.2  mrg     {
   2514  1.1.1.2  mrg       tristate result_for_ecs
   2515  1.1.1.2  mrg 	= eval_condition (lhs_ec, op, rhs_ec);
   2516  1.1.1.2  mrg       if (result_for_ecs.is_known ())
   2517  1.1.1.2  mrg 	return result_for_ecs;
   2518  1.1.1.2  mrg     }
   2519  1.1.1.2  mrg 
   2520  1.1.1.2  mrg   /* If at least one is not in an EC, we have no constraints
   2521  1.1.1.2  mrg      comparing LHS and RHS yet.
   2522  1.1.1.2  mrg      They might still be comparable if one (or both) is a constant.
   2523  1.1.1.2  mrg 
   2524  1.1.1.2  mrg      Alternatively, we can also get here if we had ECs but they weren't
   2525  1.1.1.2  mrg      comparable.  Again, constant comparisons might give an answer.  */
   2526  1.1.1.2  mrg   tree lhs_const = lhs->maybe_get_constant ();
   2527  1.1.1.2  mrg   tree rhs_const = rhs->maybe_get_constant ();
   2528  1.1.1.2  mrg   if (lhs_const && rhs_const)
   2529  1.1.1.2  mrg     {
   2530  1.1.1.2  mrg       tristate result_for_constants
   2531  1.1.1.2  mrg 	= compare_constants (lhs_const, op, rhs_const);
   2532  1.1.1.2  mrg       if (result_for_constants.is_known ())
   2533  1.1.1.2  mrg 	return result_for_constants;
   2534  1.1.1.2  mrg     }
   2535  1.1.1.2  mrg 
   2536  1.1.1.2  mrg   if (!lhs_ec.null_p ())
   2537  1.1.1.2  mrg     {
   2538  1.1.1.2  mrg       if (rhs_const)
   2539  1.1.1.2  mrg 	return eval_condition (lhs_ec, op, rhs_const);
   2540  1.1.1.2  mrg     }
   2541  1.1.1.2  mrg   if (!rhs_ec.null_p ())
   2542  1.1.1.2  mrg     {
   2543  1.1.1.2  mrg       if (lhs_const)
   2544      1.1  mrg 	{
   2545  1.1.1.2  mrg 	  enum tree_code swapped_op = swap_tree_comparison (op);
   2546  1.1.1.2  mrg 	  return eval_condition (rhs_ec, swapped_op, lhs_const);
   2547      1.1  mrg 	}
   2548      1.1  mrg     }
   2549      1.1  mrg 
   2550      1.1  mrg   return tristate (tristate::TS_UNKNOWN);
   2551      1.1  mrg }
   2552      1.1  mrg 
   2553  1.1.1.2  mrg /* Delete any information about svalues identified by P.
   2554      1.1  mrg    Such instances are removed from equivalence classes, and any
   2555      1.1  mrg    redundant ECs and constraints are also removed.
   2556      1.1  mrg    Accumulate stats into STATS.  */
   2557      1.1  mrg 
   2558  1.1.1.2  mrg template <typename PurgeCriteria>
   2559      1.1  mrg void
   2560  1.1.1.2  mrg constraint_manager::purge (const PurgeCriteria &p, purge_stats *stats)
   2561      1.1  mrg {
   2562  1.1.1.2  mrg   /* Delete any svalues identified by P within the various equivalence
   2563      1.1  mrg      classes.  */
   2564      1.1  mrg   for (unsigned ec_idx = 0; ec_idx < m_equiv_classes.length (); )
   2565      1.1  mrg     {
   2566      1.1  mrg       equiv_class *ec = m_equiv_classes[ec_idx];
   2567      1.1  mrg 
   2568      1.1  mrg       int i;
   2569  1.1.1.2  mrg       const svalue *sval;
   2570      1.1  mrg       bool delete_ec = false;
   2571  1.1.1.2  mrg       FOR_EACH_VEC_ELT (ec->m_vars, i, sval)
   2572      1.1  mrg 	{
   2573  1.1.1.2  mrg 	  if (sval == ec->m_cst_sval)
   2574      1.1  mrg 	    continue;
   2575  1.1.1.2  mrg 	  if (p.should_purge_p (sval))
   2576      1.1  mrg 	    {
   2577  1.1.1.2  mrg 	      if (ec->del (sval))
   2578      1.1  mrg 		if (!ec->m_constant)
   2579      1.1  mrg 		  delete_ec = true;
   2580      1.1  mrg 	    }
   2581      1.1  mrg 	}
   2582      1.1  mrg 
   2583      1.1  mrg       if (delete_ec)
   2584      1.1  mrg 	{
   2585      1.1  mrg 	  delete ec;
   2586      1.1  mrg 	  m_equiv_classes.ordered_remove (ec_idx);
   2587      1.1  mrg 	  if (stats)
   2588      1.1  mrg 	    stats->m_num_equiv_classes++;
   2589      1.1  mrg 
   2590      1.1  mrg 	  /* Update the constraints, potentially removing some.  */
   2591      1.1  mrg 	  for (unsigned con_idx = 0; con_idx < m_constraints.length (); )
   2592      1.1  mrg 	    {
   2593      1.1  mrg 	      constraint *c = &m_constraints[con_idx];
   2594      1.1  mrg 
   2595      1.1  mrg 	      /* Remove constraints that refer to the deleted EC.  */
   2596      1.1  mrg 	      if (c->m_lhs == ec_idx
   2597      1.1  mrg 		  || c->m_rhs == ec_idx)
   2598      1.1  mrg 		{
   2599      1.1  mrg 		  m_constraints.ordered_remove (con_idx);
   2600      1.1  mrg 		  if (stats)
   2601      1.1  mrg 		    stats->m_num_constraints++;
   2602      1.1  mrg 		}
   2603      1.1  mrg 	      else
   2604      1.1  mrg 		{
   2605      1.1  mrg 		  /* Renumber constraints that refer to ECs that have
   2606      1.1  mrg 		     had their idx changed.  */
   2607      1.1  mrg 		  c->m_lhs.update_for_removal (ec_idx);
   2608      1.1  mrg 		  c->m_rhs.update_for_removal (ec_idx);
   2609      1.1  mrg 
   2610      1.1  mrg 		  con_idx++;
   2611      1.1  mrg 		}
   2612      1.1  mrg 	    }
   2613  1.1.1.2  mrg 
   2614  1.1.1.2  mrg 	  /* Update bounded_ranges_constraint instances.  */
   2615  1.1.1.2  mrg 	  for (unsigned r_idx = 0;
   2616  1.1.1.2  mrg 	       r_idx < m_bounded_ranges_constraints.length (); )
   2617  1.1.1.2  mrg 	    {
   2618  1.1.1.2  mrg 	      bounded_ranges_constraint *brc
   2619  1.1.1.2  mrg 		= &m_bounded_ranges_constraints[r_idx];
   2620  1.1.1.2  mrg 
   2621  1.1.1.2  mrg 	      /* Remove if it refers to the deleted EC.  */
   2622  1.1.1.2  mrg 	      if (brc->m_ec_id == ec_idx)
   2623  1.1.1.2  mrg 		{
   2624  1.1.1.2  mrg 		  m_bounded_ranges_constraints.ordered_remove (r_idx);
   2625  1.1.1.2  mrg 		  if (stats)
   2626  1.1.1.2  mrg 		    stats->m_num_bounded_ranges_constraints++;
   2627  1.1.1.2  mrg 		}
   2628  1.1.1.2  mrg 	      else
   2629  1.1.1.2  mrg 		{
   2630  1.1.1.2  mrg 		  /* Renumber any EC ids that refer to ECs that have
   2631  1.1.1.2  mrg 		     had their idx changed.  */
   2632  1.1.1.2  mrg 		  brc->m_ec_id.update_for_removal (ec_idx);
   2633  1.1.1.2  mrg 		  r_idx++;
   2634  1.1.1.2  mrg 		}
   2635  1.1.1.2  mrg 	    }
   2636      1.1  mrg 	}
   2637      1.1  mrg       else
   2638      1.1  mrg 	ec_idx++;
   2639      1.1  mrg     }
   2640      1.1  mrg 
   2641      1.1  mrg   /* Now delete any constraints that are purely between constants.  */
   2642      1.1  mrg   for (unsigned con_idx = 0; con_idx < m_constraints.length (); )
   2643      1.1  mrg     {
   2644      1.1  mrg       constraint *c = &m_constraints[con_idx];
   2645      1.1  mrg       if (m_equiv_classes[c->m_lhs.m_idx]->m_vars.length () == 0
   2646      1.1  mrg 	  && m_equiv_classes[c->m_rhs.m_idx]->m_vars.length () == 0)
   2647      1.1  mrg 	{
   2648      1.1  mrg 	  m_constraints.ordered_remove (con_idx);
   2649      1.1  mrg 	  if (stats)
   2650      1.1  mrg 	    stats->m_num_constraints++;
   2651      1.1  mrg 	}
   2652      1.1  mrg       else
   2653      1.1  mrg 	{
   2654      1.1  mrg 	  con_idx++;
   2655      1.1  mrg 	}
   2656      1.1  mrg     }
   2657      1.1  mrg 
   2658      1.1  mrg   /* Finally, delete any ECs that purely contain constants and aren't
   2659      1.1  mrg      referenced by any constraints.  */
   2660      1.1  mrg   for (unsigned ec_idx = 0; ec_idx < m_equiv_classes.length (); )
   2661      1.1  mrg     {
   2662      1.1  mrg       equiv_class *ec = m_equiv_classes[ec_idx];
   2663      1.1  mrg       if (ec->m_vars.length () == 0)
   2664      1.1  mrg 	{
   2665      1.1  mrg 	  equiv_class_id ec_id (ec_idx);
   2666      1.1  mrg 	  bool has_constraint = false;
   2667      1.1  mrg 	  for (unsigned con_idx = 0; con_idx < m_constraints.length ();
   2668      1.1  mrg 	       con_idx++)
   2669      1.1  mrg 	    {
   2670      1.1  mrg 	      constraint *c = &m_constraints[con_idx];
   2671      1.1  mrg 	      if (c->m_lhs == ec_id
   2672      1.1  mrg 		  || c->m_rhs == ec_id)
   2673      1.1  mrg 		{
   2674      1.1  mrg 		  has_constraint = true;
   2675      1.1  mrg 		  break;
   2676      1.1  mrg 		}
   2677      1.1  mrg 	    }
   2678      1.1  mrg 	  if (!has_constraint)
   2679      1.1  mrg 	    {
   2680      1.1  mrg 	      delete ec;
   2681      1.1  mrg 	      m_equiv_classes.ordered_remove (ec_idx);
   2682      1.1  mrg 	      if (stats)
   2683      1.1  mrg 		stats->m_num_equiv_classes++;
   2684      1.1  mrg 
   2685      1.1  mrg 	      /* Renumber constraints that refer to ECs that have
   2686      1.1  mrg 		 had their idx changed.  */
   2687      1.1  mrg 	      for (unsigned con_idx = 0; con_idx < m_constraints.length ();
   2688      1.1  mrg 		   con_idx++)
   2689      1.1  mrg 		{
   2690      1.1  mrg 		  constraint *c = &m_constraints[con_idx];
   2691      1.1  mrg 		  c->m_lhs.update_for_removal (ec_idx);
   2692      1.1  mrg 		  c->m_rhs.update_for_removal (ec_idx);
   2693      1.1  mrg 		}
   2694  1.1.1.2  mrg 
   2695  1.1.1.2  mrg 	      /* Likewise for m_bounded_ranges_constraints.  */
   2696  1.1.1.2  mrg 	      for (unsigned r_idx = 0;
   2697  1.1.1.2  mrg 		   r_idx < m_bounded_ranges_constraints.length ();
   2698  1.1.1.2  mrg 		   r_idx++)
   2699  1.1.1.2  mrg 		{
   2700  1.1.1.2  mrg 		  bounded_ranges_constraint *brc
   2701  1.1.1.2  mrg 		    = &m_bounded_ranges_constraints[r_idx];
   2702  1.1.1.2  mrg 		  brc->m_ec_id.update_for_removal (ec_idx);
   2703  1.1.1.2  mrg 		}
   2704  1.1.1.2  mrg 
   2705      1.1  mrg 	      continue;
   2706      1.1  mrg 	    }
   2707      1.1  mrg 	}
   2708      1.1  mrg       ec_idx++;
   2709      1.1  mrg     }
   2710      1.1  mrg 
   2711      1.1  mrg   validate ();
   2712      1.1  mrg }
   2713      1.1  mrg 
   2714  1.1.1.2  mrg /* Implementation of PurgeCriteria: purge svalues that are not live
   2715  1.1.1.2  mrg    with respect to LIVE_SVALUES and MODEL.  */
   2716  1.1.1.2  mrg 
   2717  1.1.1.2  mrg class dead_svalue_purger
   2718  1.1.1.2  mrg {
   2719  1.1.1.2  mrg public:
   2720  1.1.1.2  mrg   dead_svalue_purger (const svalue_set &live_svalues,
   2721  1.1.1.2  mrg 		      const region_model *model)
   2722  1.1.1.2  mrg   : m_live_svalues (live_svalues), m_model (model)
   2723  1.1.1.2  mrg   {
   2724  1.1.1.2  mrg   }
   2725  1.1.1.2  mrg 
   2726  1.1.1.2  mrg   bool should_purge_p (const svalue *sval) const
   2727  1.1.1.2  mrg   {
   2728  1.1.1.2  mrg     return !sval->live_p (&m_live_svalues, m_model);
   2729  1.1.1.2  mrg   }
   2730  1.1.1.2  mrg 
   2731  1.1.1.2  mrg private:
   2732  1.1.1.2  mrg   const svalue_set &m_live_svalues;
   2733  1.1.1.2  mrg   const region_model *m_model;
   2734  1.1.1.2  mrg };
   2735  1.1.1.2  mrg 
   2736  1.1.1.2  mrg /* Purge dead svalues from equivalence classes and update constraints
   2737  1.1.1.2  mrg    accordingly.  */
   2738      1.1  mrg 
   2739      1.1  mrg void
   2740  1.1.1.2  mrg constraint_manager::
   2741  1.1.1.2  mrg on_liveness_change (const svalue_set &live_svalues,
   2742  1.1.1.2  mrg 		    const region_model *model)
   2743      1.1  mrg {
   2744  1.1.1.2  mrg   dead_svalue_purger p (live_svalues, model);
   2745  1.1.1.2  mrg   purge (p, NULL);
   2746  1.1.1.2  mrg }
   2747  1.1.1.2  mrg 
   2748  1.1.1.2  mrg class svalue_purger
   2749  1.1.1.2  mrg {
   2750  1.1.1.2  mrg public:
   2751  1.1.1.2  mrg   svalue_purger (const svalue *sval) : m_sval (sval) {}
   2752  1.1.1.2  mrg 
   2753  1.1.1.2  mrg   bool should_purge_p (const svalue *sval) const
   2754  1.1.1.2  mrg   {
   2755  1.1.1.2  mrg     return sval->involves_p (m_sval);
   2756  1.1.1.2  mrg   }
   2757  1.1.1.2  mrg 
   2758  1.1.1.2  mrg private:
   2759  1.1.1.2  mrg   const svalue *m_sval;
   2760  1.1.1.2  mrg };
   2761  1.1.1.2  mrg 
   2762  1.1.1.2  mrg /* Purge any state involving SVAL.  */
   2763  1.1.1.2  mrg 
   2764  1.1.1.2  mrg void
   2765  1.1.1.2  mrg constraint_manager::purge_state_involving (const svalue *sval)
   2766  1.1.1.2  mrg {
   2767  1.1.1.2  mrg   svalue_purger p (sval);
   2768  1.1.1.2  mrg   purge (p, NULL);
   2769      1.1  mrg }
   2770      1.1  mrg 
   2771      1.1  mrg /* Comparator for use by constraint_manager::canonicalize.
   2772      1.1  mrg    Sort a pair of equiv_class instances, using the representative
   2773  1.1.1.2  mrg    svalue as a sort key.  */
   2774      1.1  mrg 
   2775      1.1  mrg static int
   2776      1.1  mrg equiv_class_cmp (const void *p1, const void *p2)
   2777      1.1  mrg {
   2778      1.1  mrg   const equiv_class *ec1 = *(const equiv_class * const *)p1;
   2779      1.1  mrg   const equiv_class *ec2 = *(const equiv_class * const *)p2;
   2780      1.1  mrg 
   2781  1.1.1.2  mrg   const svalue *rep1 = ec1->get_representative ();
   2782  1.1.1.2  mrg   const svalue *rep2 = ec2->get_representative ();
   2783      1.1  mrg 
   2784  1.1.1.2  mrg   gcc_assert (rep1);
   2785  1.1.1.2  mrg   gcc_assert (rep2);
   2786  1.1.1.2  mrg 
   2787  1.1.1.2  mrg   return svalue::cmp_ptr (rep1, rep2);
   2788      1.1  mrg }
   2789      1.1  mrg 
   2790      1.1  mrg /* Comparator for use by constraint_manager::canonicalize.
   2791      1.1  mrg    Sort a pair of constraint instances.  */
   2792      1.1  mrg 
   2793      1.1  mrg static int
   2794      1.1  mrg constraint_cmp (const void *p1, const void *p2)
   2795      1.1  mrg {
   2796      1.1  mrg   const constraint *c1 = (const constraint *)p1;
   2797      1.1  mrg   const constraint *c2 = (const constraint *)p2;
   2798      1.1  mrg   int lhs_cmp = c1->m_lhs.as_int () - c2->m_lhs.as_int ();
   2799      1.1  mrg   if (lhs_cmp)
   2800      1.1  mrg     return lhs_cmp;
   2801      1.1  mrg   int rhs_cmp = c1->m_rhs.as_int () - c2->m_rhs.as_int ();
   2802      1.1  mrg   if (rhs_cmp)
   2803      1.1  mrg     return rhs_cmp;
   2804      1.1  mrg   return c1->m_op - c2->m_op;
   2805      1.1  mrg }
   2806      1.1  mrg 
   2807  1.1.1.2  mrg /* Purge redundant equivalence classes and constraints, and reorder them
   2808  1.1.1.2  mrg    within this constraint_manager into a canonical order, to increase the
   2809      1.1  mrg    chances of finding equality with another instance.  */
   2810      1.1  mrg 
   2811      1.1  mrg void
   2812  1.1.1.2  mrg constraint_manager::canonicalize ()
   2813      1.1  mrg {
   2814  1.1.1.2  mrg   /* First, sort svalues within the ECs.  */
   2815      1.1  mrg   unsigned i;
   2816      1.1  mrg   equiv_class *ec;
   2817      1.1  mrg   FOR_EACH_VEC_ELT (m_equiv_classes, i, ec)
   2818      1.1  mrg     ec->canonicalize ();
   2819      1.1  mrg 
   2820  1.1.1.2  mrg   /* TODO: remove constraints where both sides have a constant, and are
   2821  1.1.1.2  mrg      thus implicit.  But does this break transitivity?  */
   2822      1.1  mrg 
   2823  1.1.1.2  mrg   /* We will be purging and reordering ECs.
   2824  1.1.1.2  mrg      We will need to remap the equiv_class_ids in the constraints,
   2825      1.1  mrg      so we need to store the original index of each EC.
   2826  1.1.1.2  mrg      Build a lookup table, mapping from the representative svalue
   2827  1.1.1.2  mrg      to the original equiv_class_id of that svalue.  */
   2828  1.1.1.2  mrg   hash_map<const svalue *, equiv_class_id> original_ec_id;
   2829  1.1.1.2  mrg   const unsigned orig_num_equiv_classes = m_equiv_classes.length ();
   2830      1.1  mrg   FOR_EACH_VEC_ELT (m_equiv_classes, i, ec)
   2831      1.1  mrg     {
   2832  1.1.1.2  mrg       const svalue *rep = ec->get_representative ();
   2833  1.1.1.2  mrg       gcc_assert (rep);
   2834  1.1.1.2  mrg       original_ec_id.put (rep, i);
   2835  1.1.1.2  mrg     }
   2836  1.1.1.2  mrg 
   2837  1.1.1.2  mrg   /* Find ECs used by constraints.  */
   2838  1.1.1.2  mrg   hash_set<const equiv_class *> used_ecs;
   2839  1.1.1.2  mrg   constraint *c;
   2840  1.1.1.2  mrg   FOR_EACH_VEC_ELT (m_constraints, i, c)
   2841  1.1.1.2  mrg     {
   2842  1.1.1.2  mrg       used_ecs.add (m_equiv_classes[c->m_lhs.as_int ()]);
   2843  1.1.1.2  mrg       used_ecs.add (m_equiv_classes[c->m_rhs.as_int ()]);
   2844      1.1  mrg     }
   2845      1.1  mrg 
   2846  1.1.1.2  mrg   for (const auto &iter : m_bounded_ranges_constraints)
   2847  1.1.1.2  mrg     used_ecs.add (m_equiv_classes[iter.m_ec_id.as_int ()]);
   2848  1.1.1.2  mrg 
   2849  1.1.1.2  mrg   /* Purge unused ECs: those that aren't used by constraints and
   2850  1.1.1.2  mrg      that effectively have only one svalue (either in m_constant
   2851  1.1.1.2  mrg      or in m_vars).  */
   2852  1.1.1.2  mrg   {
   2853  1.1.1.2  mrg     /* "unordered remove if" from a vec.  */
   2854  1.1.1.2  mrg     unsigned i = 0;
   2855  1.1.1.2  mrg     while (i < m_equiv_classes.length ())
   2856  1.1.1.2  mrg       {
   2857  1.1.1.2  mrg 	equiv_class *ec = m_equiv_classes[i];
   2858  1.1.1.2  mrg 	if (!used_ecs.contains (ec)
   2859  1.1.1.2  mrg 	    && !ec->contains_non_constant_p ())
   2860  1.1.1.2  mrg 	  {
   2861  1.1.1.2  mrg 	    m_equiv_classes.unordered_remove (i);
   2862  1.1.1.2  mrg 	    delete ec;
   2863  1.1.1.2  mrg 	  }
   2864  1.1.1.2  mrg 	else
   2865  1.1.1.2  mrg 	  i++;
   2866  1.1.1.2  mrg       }
   2867  1.1.1.2  mrg   }
   2868  1.1.1.2  mrg 
   2869  1.1.1.2  mrg   /* Next, sort the surviving ECs into a canonical order.  */
   2870      1.1  mrg   m_equiv_classes.qsort (equiv_class_cmp);
   2871      1.1  mrg 
   2872      1.1  mrg   /* Populate ec_id_map based on the old vs new EC ids.  */
   2873  1.1.1.2  mrg   one_way_id_map<equiv_class_id> ec_id_map (orig_num_equiv_classes);
   2874      1.1  mrg   FOR_EACH_VEC_ELT (m_equiv_classes, i, ec)
   2875      1.1  mrg     {
   2876  1.1.1.2  mrg       const svalue *rep = ec->get_representative ();
   2877  1.1.1.2  mrg       gcc_assert (rep);
   2878  1.1.1.2  mrg       ec_id_map.put (*original_ec_id.get (rep), i);
   2879      1.1  mrg     }
   2880      1.1  mrg 
   2881  1.1.1.2  mrg   /* Use ec_id_map to update the EC ids within the constraints.  */
   2882      1.1  mrg   FOR_EACH_VEC_ELT (m_constraints, i, c)
   2883      1.1  mrg     {
   2884      1.1  mrg       ec_id_map.update (&c->m_lhs);
   2885      1.1  mrg       ec_id_map.update (&c->m_rhs);
   2886      1.1  mrg     }
   2887      1.1  mrg 
   2888  1.1.1.2  mrg   for (auto &iter : m_bounded_ranges_constraints)
   2889  1.1.1.2  mrg     ec_id_map.update (&iter.m_ec_id);
   2890  1.1.1.2  mrg 
   2891      1.1  mrg   /* Finally, sort the constraints. */
   2892      1.1  mrg   m_constraints.qsort (constraint_cmp);
   2893      1.1  mrg }
   2894      1.1  mrg 
   2895      1.1  mrg /* Concrete subclass of fact_visitor for use by constraint_manager::merge.
   2896      1.1  mrg    For every fact in CM_A, see if it is also true in *CM_B.  Add such
   2897      1.1  mrg    facts to *OUT.  */
   2898      1.1  mrg 
   2899      1.1  mrg class merger_fact_visitor : public fact_visitor
   2900      1.1  mrg {
   2901      1.1  mrg public:
   2902  1.1.1.2  mrg   merger_fact_visitor (const constraint_manager *cm_b,
   2903      1.1  mrg 		       constraint_manager *out)
   2904      1.1  mrg   : m_cm_b (cm_b), m_out (out)
   2905      1.1  mrg   {}
   2906      1.1  mrg 
   2907  1.1.1.2  mrg   void on_fact (const svalue *lhs, enum tree_code code, const svalue *rhs)
   2908      1.1  mrg     FINAL OVERRIDE
   2909      1.1  mrg   {
   2910  1.1.1.2  mrg     /* Special-case for widening.  */
   2911  1.1.1.2  mrg     if (lhs->get_kind () == SK_WIDENING)
   2912  1.1.1.2  mrg       if (!m_cm_b->get_equiv_class_by_svalue (lhs, NULL))
   2913  1.1.1.2  mrg 	{
   2914  1.1.1.2  mrg 	  /* LHS isn't constrained within m_cm_b.  */
   2915  1.1.1.2  mrg 	  bool sat = m_out->add_constraint (lhs, code, rhs);
   2916  1.1.1.2  mrg 	  gcc_assert (sat);
   2917  1.1.1.2  mrg 	  return;
   2918  1.1.1.2  mrg 	}
   2919  1.1.1.2  mrg 
   2920      1.1  mrg     if (m_cm_b->eval_condition (lhs, code, rhs).is_true ())
   2921      1.1  mrg       {
   2922      1.1  mrg 	bool sat = m_out->add_constraint (lhs, code, rhs);
   2923  1.1.1.2  mrg 	if (!sat)
   2924  1.1.1.2  mrg 	  {
   2925  1.1.1.2  mrg 	    /* If -fanalyzer-transitivity is off, we can encounter cases
   2926  1.1.1.2  mrg 	       where at least one of the two constraint_managers being merged
   2927  1.1.1.2  mrg 	       is infeasible, but we only discover that infeasibility
   2928  1.1.1.2  mrg 	       during merging (PR analyzer/96650).
   2929  1.1.1.2  mrg 	       Silently drop such constraints.  */
   2930  1.1.1.2  mrg 	    gcc_assert (!flag_analyzer_transitivity);
   2931  1.1.1.2  mrg 	  }
   2932  1.1.1.2  mrg       }
   2933  1.1.1.2  mrg   }
   2934  1.1.1.2  mrg 
   2935  1.1.1.2  mrg   void on_ranges (const svalue *lhs_sval,
   2936  1.1.1.2  mrg 		  const bounded_ranges *ranges) FINAL OVERRIDE
   2937  1.1.1.2  mrg   {
   2938  1.1.1.2  mrg     for (const auto &iter : m_cm_b->m_bounded_ranges_constraints)
   2939  1.1.1.2  mrg       {
   2940  1.1.1.2  mrg 	const equiv_class &ec_rhs = iter.m_ec_id.get_obj (*m_cm_b);
   2941  1.1.1.2  mrg 	for (unsigned i = 0; i < ec_rhs.m_vars.length (); i++)
   2942  1.1.1.2  mrg 	  {
   2943  1.1.1.2  mrg 	    const svalue *rhs_sval = ec_rhs.m_vars[i];
   2944  1.1.1.2  mrg 	    if (lhs_sval == rhs_sval)
   2945  1.1.1.2  mrg 	      {
   2946  1.1.1.2  mrg 		/* Union of the two ranges.  */
   2947  1.1.1.2  mrg 		auto_vec <const bounded_ranges *> pair (2);
   2948  1.1.1.2  mrg 		pair.quick_push (ranges);
   2949  1.1.1.2  mrg 		pair.quick_push (iter.m_ranges);
   2950  1.1.1.2  mrg 		bounded_ranges_manager *ranges_mgr
   2951  1.1.1.2  mrg 		  = m_cm_b->get_range_manager ();
   2952  1.1.1.2  mrg 		const bounded_ranges *union_
   2953  1.1.1.2  mrg 		  = ranges_mgr->get_or_create_union (pair);
   2954  1.1.1.2  mrg 		bool sat = m_out->add_bounded_ranges (lhs_sval, union_);
   2955  1.1.1.2  mrg 		gcc_assert (sat);
   2956  1.1.1.2  mrg 	      }
   2957  1.1.1.2  mrg 	  }
   2958      1.1  mrg       }
   2959      1.1  mrg   }
   2960      1.1  mrg 
   2961      1.1  mrg private:
   2962  1.1.1.2  mrg   const constraint_manager *m_cm_b;
   2963      1.1  mrg   constraint_manager *m_out;
   2964      1.1  mrg };
   2965      1.1  mrg 
   2966      1.1  mrg /* Use MERGER to merge CM_A and CM_B into *OUT.
   2967      1.1  mrg    If one thinks of a constraint_manager as a subset of N-dimensional
   2968      1.1  mrg    space, this takes the union of the points of CM_A and CM_B, and
   2969      1.1  mrg    expresses that into *OUT.  Alternatively, it can be thought of
   2970      1.1  mrg    as the intersection of the constraints.  */
   2971      1.1  mrg 
   2972      1.1  mrg void
   2973      1.1  mrg constraint_manager::merge (const constraint_manager &cm_a,
   2974      1.1  mrg 			   const constraint_manager &cm_b,
   2975  1.1.1.2  mrg 			   constraint_manager *out)
   2976      1.1  mrg {
   2977      1.1  mrg   /* Merge the equivalence classes and constraints.
   2978      1.1  mrg      The easiest way to do this seems to be to enumerate all of the facts
   2979  1.1.1.2  mrg      in cm_a, see which are also true in cm_b,
   2980      1.1  mrg      and add those to *OUT.  */
   2981  1.1.1.2  mrg   merger_fact_visitor v (&cm_b, out);
   2982  1.1.1.2  mrg   cm_a.for_each_fact (&v);
   2983      1.1  mrg }
   2984      1.1  mrg 
   2985      1.1  mrg /* Call VISITOR's on_fact vfunc repeatedly to express the various
   2986      1.1  mrg    equivalence classes and constraints.
   2987      1.1  mrg    This is used by constraint_manager::merge to find the common
   2988      1.1  mrg    facts between two input constraint_managers.  */
   2989      1.1  mrg 
   2990      1.1  mrg void
   2991      1.1  mrg constraint_manager::for_each_fact (fact_visitor *visitor) const
   2992      1.1  mrg {
   2993      1.1  mrg   /* First, call EQ_EXPR within the various equivalence classes.  */
   2994      1.1  mrg   unsigned ec_idx;
   2995      1.1  mrg   equiv_class *ec;
   2996      1.1  mrg   FOR_EACH_VEC_ELT (m_equiv_classes, ec_idx, ec)
   2997      1.1  mrg     {
   2998  1.1.1.2  mrg       if (ec->m_cst_sval)
   2999      1.1  mrg 	{
   3000      1.1  mrg 	  unsigned i;
   3001  1.1.1.2  mrg 	  const svalue *sval;
   3002  1.1.1.2  mrg 	  FOR_EACH_VEC_ELT (ec->m_vars, i, sval)
   3003  1.1.1.2  mrg 	    visitor->on_fact (ec->m_cst_sval, EQ_EXPR, sval);
   3004      1.1  mrg 	}
   3005      1.1  mrg       for (unsigned i = 0; i < ec->m_vars.length (); i++)
   3006      1.1  mrg 	for (unsigned j = i + 1; j < ec->m_vars.length (); j++)
   3007      1.1  mrg 	  visitor->on_fact (ec->m_vars[i], EQ_EXPR, ec->m_vars[j]);
   3008      1.1  mrg     }
   3009      1.1  mrg 
   3010      1.1  mrg   /* Now, express the various constraints.  */
   3011      1.1  mrg   unsigned con_idx;
   3012      1.1  mrg   constraint *c;
   3013      1.1  mrg   FOR_EACH_VEC_ELT (m_constraints, con_idx, c)
   3014      1.1  mrg     {
   3015      1.1  mrg       const equiv_class &ec_lhs = c->m_lhs.get_obj (*this);
   3016      1.1  mrg       const equiv_class &ec_rhs = c->m_rhs.get_obj (*this);
   3017      1.1  mrg       enum tree_code code = constraint_tree_code (c->m_op);
   3018      1.1  mrg 
   3019  1.1.1.2  mrg       if (ec_lhs.m_cst_sval)
   3020      1.1  mrg 	{
   3021      1.1  mrg 	  for (unsigned j = 0; j < ec_rhs.m_vars.length (); j++)
   3022      1.1  mrg 	    {
   3023  1.1.1.2  mrg 	      visitor->on_fact (ec_lhs.m_cst_sval, code, ec_rhs.m_vars[j]);
   3024      1.1  mrg 	    }
   3025      1.1  mrg 	}
   3026      1.1  mrg       for (unsigned i = 0; i < ec_lhs.m_vars.length (); i++)
   3027      1.1  mrg 	{
   3028  1.1.1.2  mrg 	  if (ec_rhs.m_cst_sval)
   3029  1.1.1.2  mrg 	    visitor->on_fact (ec_lhs.m_vars[i], code, ec_rhs.m_cst_sval);
   3030      1.1  mrg 	  for (unsigned j = 0; j < ec_rhs.m_vars.length (); j++)
   3031      1.1  mrg 	    visitor->on_fact (ec_lhs.m_vars[i], code, ec_rhs.m_vars[j]);
   3032      1.1  mrg 	}
   3033      1.1  mrg     }
   3034  1.1.1.2  mrg 
   3035  1.1.1.2  mrg   for (const auto &iter : m_bounded_ranges_constraints)
   3036  1.1.1.2  mrg     {
   3037  1.1.1.2  mrg       const equiv_class &ec_lhs = iter.m_ec_id.get_obj (*this);
   3038  1.1.1.2  mrg       for (unsigned i = 0; i < ec_lhs.m_vars.length (); i++)
   3039  1.1.1.2  mrg 	{
   3040  1.1.1.2  mrg 	  const svalue *lhs_sval = ec_lhs.m_vars[i];
   3041  1.1.1.2  mrg 	  visitor->on_ranges (lhs_sval, iter.m_ranges);
   3042  1.1.1.2  mrg 	}
   3043  1.1.1.2  mrg     }
   3044      1.1  mrg }
   3045      1.1  mrg 
   3046      1.1  mrg /* Assert that this object is valid.  */
   3047      1.1  mrg 
   3048      1.1  mrg void
   3049      1.1  mrg constraint_manager::validate () const
   3050      1.1  mrg {
   3051      1.1  mrg   /* Skip this in a release build.  */
   3052      1.1  mrg #if !CHECKING_P
   3053      1.1  mrg   return;
   3054      1.1  mrg #endif
   3055      1.1  mrg 
   3056      1.1  mrg   int i;
   3057      1.1  mrg   equiv_class *ec;
   3058      1.1  mrg   FOR_EACH_VEC_ELT (m_equiv_classes, i, ec)
   3059      1.1  mrg     {
   3060      1.1  mrg       gcc_assert (ec);
   3061      1.1  mrg 
   3062      1.1  mrg       int j;
   3063  1.1.1.2  mrg       const svalue *sval;
   3064  1.1.1.2  mrg       FOR_EACH_VEC_ELT (ec->m_vars, j, sval)
   3065  1.1.1.2  mrg 	gcc_assert (sval);
   3066      1.1  mrg       if (ec->m_constant)
   3067      1.1  mrg 	{
   3068      1.1  mrg 	  gcc_assert (CONSTANT_CLASS_P (ec->m_constant));
   3069  1.1.1.2  mrg 	  gcc_assert (ec->m_cst_sval);
   3070      1.1  mrg 	}
   3071      1.1  mrg #if 0
   3072      1.1  mrg       else
   3073      1.1  mrg 	gcc_assert (ec->m_vars.length () > 0);
   3074      1.1  mrg #endif
   3075      1.1  mrg     }
   3076      1.1  mrg 
   3077      1.1  mrg   constraint *c;
   3078      1.1  mrg   FOR_EACH_VEC_ELT (m_constraints, i, c)
   3079      1.1  mrg     {
   3080      1.1  mrg       gcc_assert (!c->m_lhs.null_p ());
   3081  1.1.1.2  mrg       gcc_assert (c->m_lhs.as_int () < (int)m_equiv_classes.length ());
   3082      1.1  mrg       gcc_assert (!c->m_rhs.null_p ());
   3083  1.1.1.2  mrg       gcc_assert (c->m_rhs.as_int () < (int)m_equiv_classes.length ());
   3084      1.1  mrg     }
   3085  1.1.1.2  mrg 
   3086  1.1.1.2  mrg   for (const auto &iter : m_bounded_ranges_constraints)
   3087  1.1.1.2  mrg     {
   3088  1.1.1.2  mrg       gcc_assert (!iter.m_ec_id.null_p ());
   3089  1.1.1.2  mrg       gcc_assert (iter.m_ec_id.as_int () < (int)m_equiv_classes.length ());
   3090  1.1.1.2  mrg     }
   3091  1.1.1.2  mrg }
   3092  1.1.1.2  mrg 
   3093  1.1.1.2  mrg bounded_ranges_manager *
   3094  1.1.1.2  mrg constraint_manager::get_range_manager () const
   3095  1.1.1.2  mrg {
   3096  1.1.1.2  mrg   return m_mgr->get_range_manager ();
   3097      1.1  mrg }
   3098      1.1  mrg 
   3099      1.1  mrg #if CHECKING_P
   3100      1.1  mrg 
   3101      1.1  mrg namespace selftest {
   3102      1.1  mrg 
   3103      1.1  mrg /* Various constraint_manager selftests.
   3104      1.1  mrg    These have to be written in terms of a region_model, since
   3105  1.1.1.2  mrg    the latter is responsible for managing svalue instances.  */
   3106  1.1.1.2  mrg 
   3107  1.1.1.2  mrg /* Verify that range::add_bound works as expected.  */
   3108  1.1.1.2  mrg 
   3109  1.1.1.2  mrg static void
   3110  1.1.1.2  mrg test_range ()
   3111  1.1.1.2  mrg {
   3112  1.1.1.2  mrg   tree int_0 = build_int_cst (integer_type_node, 0);
   3113  1.1.1.2  mrg   tree int_1 = build_int_cst (integer_type_node, 1);
   3114  1.1.1.2  mrg   tree int_2 = build_int_cst (integer_type_node, 2);
   3115  1.1.1.2  mrg   tree int_5 = build_int_cst (integer_type_node, 5);
   3116  1.1.1.2  mrg 
   3117  1.1.1.2  mrg   {
   3118  1.1.1.2  mrg     range r;
   3119  1.1.1.2  mrg     ASSERT_FALSE (r.constrained_to_single_element ());
   3120  1.1.1.2  mrg 
   3121  1.1.1.2  mrg     /* (r >= 1).  */
   3122  1.1.1.2  mrg     ASSERT_TRUE (r.add_bound (GE_EXPR, int_1));
   3123  1.1.1.2  mrg 
   3124  1.1.1.2  mrg     /* Redundant.  */
   3125  1.1.1.2  mrg     ASSERT_TRUE (r.add_bound (GE_EXPR, int_0));
   3126  1.1.1.2  mrg     ASSERT_TRUE (r.add_bound (GT_EXPR, int_0));
   3127  1.1.1.2  mrg 
   3128  1.1.1.2  mrg     ASSERT_FALSE (r.constrained_to_single_element ());
   3129  1.1.1.2  mrg 
   3130  1.1.1.2  mrg     /* Contradiction.  */
   3131  1.1.1.2  mrg     ASSERT_FALSE (r.add_bound (LT_EXPR, int_1));
   3132  1.1.1.2  mrg 
   3133  1.1.1.2  mrg     /* (r < 5).  */
   3134  1.1.1.2  mrg     ASSERT_TRUE (r.add_bound (LT_EXPR, int_5));
   3135  1.1.1.2  mrg     ASSERT_FALSE (r.constrained_to_single_element ());
   3136  1.1.1.2  mrg 
   3137  1.1.1.2  mrg     /* Contradiction.  */
   3138  1.1.1.2  mrg     ASSERT_FALSE (r.add_bound (GE_EXPR, int_5));
   3139  1.1.1.2  mrg 
   3140  1.1.1.2  mrg     /* (r < 2).  */
   3141  1.1.1.2  mrg     ASSERT_TRUE (r.add_bound (LT_EXPR, int_2));
   3142  1.1.1.2  mrg     ASSERT_TRUE (r.constrained_to_single_element ());
   3143  1.1.1.2  mrg 
   3144  1.1.1.2  mrg     /* Redundant.  */
   3145  1.1.1.2  mrg     ASSERT_TRUE (r.add_bound (LE_EXPR, int_1));
   3146  1.1.1.2  mrg     ASSERT_TRUE (r.constrained_to_single_element ());
   3147  1.1.1.2  mrg   }
   3148  1.1.1.2  mrg }
   3149      1.1  mrg 
   3150      1.1  mrg /* Verify that setting and getting simple conditions within a region_model
   3151      1.1  mrg    work (thus exercising the underlying constraint_manager).  */
   3152      1.1  mrg 
   3153      1.1  mrg static void
   3154      1.1  mrg test_constraint_conditions ()
   3155      1.1  mrg {
   3156      1.1  mrg   tree int_42 = build_int_cst (integer_type_node, 42);
   3157      1.1  mrg   tree int_0 = build_int_cst (integer_type_node, 0);
   3158      1.1  mrg 
   3159      1.1  mrg   tree x = build_global_decl ("x", integer_type_node);
   3160      1.1  mrg   tree y = build_global_decl ("y", integer_type_node);
   3161      1.1  mrg   tree z = build_global_decl ("z", integer_type_node);
   3162      1.1  mrg 
   3163      1.1  mrg   /* Self-comparisons.  */
   3164      1.1  mrg   {
   3165  1.1.1.2  mrg     region_model_manager mgr;
   3166  1.1.1.2  mrg     region_model model (&mgr);
   3167      1.1  mrg     ASSERT_CONDITION_TRUE (model, x, EQ_EXPR, x);
   3168      1.1  mrg     ASSERT_CONDITION_TRUE (model, x, LE_EXPR, x);
   3169      1.1  mrg     ASSERT_CONDITION_TRUE (model, x, GE_EXPR, x);
   3170      1.1  mrg     ASSERT_CONDITION_FALSE (model, x, NE_EXPR, x);
   3171      1.1  mrg     ASSERT_CONDITION_FALSE (model, x, LT_EXPR, x);
   3172      1.1  mrg     ASSERT_CONDITION_FALSE (model, x, GT_EXPR, x);
   3173      1.1  mrg   }
   3174      1.1  mrg 
   3175  1.1.1.2  mrg   /* Adding self-equality shouldn't add equiv classes.  */
   3176  1.1.1.2  mrg   {
   3177  1.1.1.2  mrg     region_model_manager mgr;
   3178  1.1.1.2  mrg     region_model model (&mgr);
   3179  1.1.1.2  mrg     ADD_SAT_CONSTRAINT (model, x, EQ_EXPR, x);
   3180  1.1.1.2  mrg     ADD_SAT_CONSTRAINT (model, int_42, EQ_EXPR, int_42);
   3181  1.1.1.2  mrg     /* ...even when done directly via svalues: */
   3182  1.1.1.2  mrg     const svalue *sval_int_42 = model.get_rvalue (int_42, NULL);
   3183  1.1.1.2  mrg     bool sat = model.get_constraints ()->add_constraint (sval_int_42,
   3184  1.1.1.2  mrg 							  EQ_EXPR,
   3185  1.1.1.2  mrg 							  sval_int_42);
   3186  1.1.1.2  mrg     ASSERT_TRUE (sat);
   3187  1.1.1.2  mrg     ASSERT_EQ (model.get_constraints ()->m_equiv_classes.length (), 0);
   3188  1.1.1.2  mrg   }
   3189  1.1.1.2  mrg 
   3190      1.1  mrg   /* x == y.  */
   3191      1.1  mrg   {
   3192  1.1.1.2  mrg     region_model_manager mgr;
   3193  1.1.1.2  mrg     region_model model (&mgr);
   3194      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, x, EQ_EXPR, y);
   3195      1.1  mrg 
   3196      1.1  mrg     ADD_SAT_CONSTRAINT (model, x, EQ_EXPR, y);
   3197      1.1  mrg 
   3198      1.1  mrg     ASSERT_CONDITION_TRUE (model, x, EQ_EXPR, y);
   3199      1.1  mrg     ASSERT_CONDITION_TRUE (model, x, LE_EXPR, y);
   3200      1.1  mrg     ASSERT_CONDITION_TRUE (model, x, GE_EXPR, y);
   3201      1.1  mrg     ASSERT_CONDITION_FALSE (model, x, NE_EXPR, y);
   3202      1.1  mrg     ASSERT_CONDITION_FALSE (model, x, LT_EXPR, y);
   3203      1.1  mrg     ASSERT_CONDITION_FALSE (model, x, GT_EXPR, y);
   3204      1.1  mrg 
   3205      1.1  mrg     /* Swapped operands.  */
   3206      1.1  mrg     ASSERT_CONDITION_TRUE (model, y, EQ_EXPR, x);
   3207      1.1  mrg     ASSERT_CONDITION_TRUE (model, y, LE_EXPR, x);
   3208      1.1  mrg     ASSERT_CONDITION_TRUE (model, y, GE_EXPR, x);
   3209      1.1  mrg     ASSERT_CONDITION_FALSE (model, y, NE_EXPR, x);
   3210      1.1  mrg     ASSERT_CONDITION_FALSE (model, y, LT_EXPR, x);
   3211      1.1  mrg     ASSERT_CONDITION_FALSE (model, y, GT_EXPR, x);
   3212      1.1  mrg 
   3213      1.1  mrg     /* Comparison with other var.  */
   3214      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, x, EQ_EXPR, z);
   3215      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, x, LE_EXPR, z);
   3216      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, x, GE_EXPR, z);
   3217      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, x, NE_EXPR, z);
   3218      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, x, LT_EXPR, z);
   3219      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, x, GT_EXPR, z);
   3220      1.1  mrg   }
   3221      1.1  mrg 
   3222      1.1  mrg   /* x == y, then y == z  */
   3223      1.1  mrg   {
   3224  1.1.1.2  mrg     region_model_manager mgr;
   3225  1.1.1.2  mrg     region_model model (&mgr);
   3226      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, x, EQ_EXPR, y);
   3227      1.1  mrg 
   3228      1.1  mrg     ADD_SAT_CONSTRAINT (model, x, EQ_EXPR, y);
   3229      1.1  mrg     ADD_SAT_CONSTRAINT (model, y, EQ_EXPR, z);
   3230      1.1  mrg 
   3231      1.1  mrg     ASSERT_CONDITION_TRUE (model, x, EQ_EXPR, z);
   3232      1.1  mrg     ASSERT_CONDITION_TRUE (model, x, LE_EXPR, z);
   3233      1.1  mrg     ASSERT_CONDITION_TRUE (model, x, GE_EXPR, z);
   3234      1.1  mrg     ASSERT_CONDITION_FALSE (model, x, NE_EXPR, z);
   3235      1.1  mrg     ASSERT_CONDITION_FALSE (model, x, LT_EXPR, z);
   3236      1.1  mrg     ASSERT_CONDITION_FALSE (model, x, GT_EXPR, z);
   3237      1.1  mrg   }
   3238      1.1  mrg 
   3239      1.1  mrg   /* x != y.  */
   3240      1.1  mrg   {
   3241  1.1.1.2  mrg     region_model_manager mgr;
   3242  1.1.1.2  mrg     region_model model (&mgr);
   3243      1.1  mrg 
   3244      1.1  mrg     ADD_SAT_CONSTRAINT (model, x, NE_EXPR, y);
   3245      1.1  mrg 
   3246      1.1  mrg     ASSERT_CONDITION_TRUE (model, x, NE_EXPR, y);
   3247      1.1  mrg     ASSERT_CONDITION_FALSE (model, x, EQ_EXPR, y);
   3248      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, x, LE_EXPR, y);
   3249      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, x, GE_EXPR, y);
   3250      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, x, LT_EXPR, y);
   3251      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, x, GT_EXPR, y);
   3252      1.1  mrg 
   3253      1.1  mrg     /* Swapped operands.  */
   3254      1.1  mrg     ASSERT_CONDITION_TRUE (model, y, NE_EXPR, x);
   3255      1.1  mrg     ASSERT_CONDITION_FALSE (model, y, EQ_EXPR, x);
   3256      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, y, LE_EXPR, x);
   3257      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, y, GE_EXPR, x);
   3258      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, y, LT_EXPR, x);
   3259      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, y, GT_EXPR, x);
   3260      1.1  mrg 
   3261      1.1  mrg     /* Comparison with other var.  */
   3262      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, x, EQ_EXPR, z);
   3263      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, x, LE_EXPR, z);
   3264      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, x, GE_EXPR, z);
   3265      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, x, NE_EXPR, z);
   3266      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, x, LT_EXPR, z);
   3267      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, x, GT_EXPR, z);
   3268      1.1  mrg   }
   3269      1.1  mrg 
   3270      1.1  mrg   /* x < y.  */
   3271      1.1  mrg   {
   3272  1.1.1.2  mrg     region_model_manager mgr;
   3273  1.1.1.2  mrg     region_model model (&mgr);
   3274      1.1  mrg 
   3275      1.1  mrg     ADD_SAT_CONSTRAINT (model, x, LT_EXPR, y);
   3276      1.1  mrg 
   3277      1.1  mrg     ASSERT_CONDITION_TRUE (model, x, LT_EXPR, y);
   3278      1.1  mrg     ASSERT_CONDITION_TRUE (model, x, LE_EXPR, y);
   3279      1.1  mrg     ASSERT_CONDITION_TRUE (model, x, NE_EXPR, y);
   3280      1.1  mrg     ASSERT_CONDITION_FALSE (model, x, EQ_EXPR, y);
   3281      1.1  mrg     ASSERT_CONDITION_FALSE (model, x, GT_EXPR, y);
   3282      1.1  mrg     ASSERT_CONDITION_FALSE (model, x, GE_EXPR, y);
   3283      1.1  mrg 
   3284      1.1  mrg     /* Swapped operands.  */
   3285      1.1  mrg     ASSERT_CONDITION_FALSE (model, y, LT_EXPR, x);
   3286      1.1  mrg     ASSERT_CONDITION_FALSE (model, y, LE_EXPR, x);
   3287      1.1  mrg     ASSERT_CONDITION_TRUE (model, y, NE_EXPR, x);
   3288      1.1  mrg     ASSERT_CONDITION_FALSE (model, y, EQ_EXPR, x);
   3289      1.1  mrg     ASSERT_CONDITION_TRUE (model, y, GT_EXPR, x);
   3290      1.1  mrg     ASSERT_CONDITION_TRUE (model, y, GE_EXPR, x);
   3291      1.1  mrg   }
   3292      1.1  mrg 
   3293      1.1  mrg   /* x <= y.  */
   3294      1.1  mrg   {
   3295  1.1.1.2  mrg     region_model_manager mgr;
   3296  1.1.1.2  mrg     region_model model (&mgr);
   3297      1.1  mrg 
   3298      1.1  mrg     ADD_SAT_CONSTRAINT (model, x, LE_EXPR, y);
   3299      1.1  mrg 
   3300      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, x, LT_EXPR, y);
   3301      1.1  mrg     ASSERT_CONDITION_TRUE (model, x, LE_EXPR, y);
   3302      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, x, NE_EXPR, y);
   3303      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, x, EQ_EXPR, y);
   3304      1.1  mrg     ASSERT_CONDITION_FALSE (model, x, GT_EXPR, y);
   3305      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, x, GE_EXPR, y);
   3306      1.1  mrg 
   3307      1.1  mrg     /* Swapped operands.  */
   3308      1.1  mrg     ASSERT_CONDITION_FALSE (model, y, LT_EXPR, x);
   3309      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, y, LE_EXPR, x);
   3310      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, y, NE_EXPR, x);
   3311      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, y, EQ_EXPR, x);
   3312      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, y, GT_EXPR, x);
   3313      1.1  mrg     ASSERT_CONDITION_TRUE (model, y, GE_EXPR, x);
   3314      1.1  mrg   }
   3315      1.1  mrg 
   3316      1.1  mrg   /* x > y.  */
   3317      1.1  mrg   {
   3318  1.1.1.2  mrg     region_model_manager mgr;
   3319  1.1.1.2  mrg     region_model model (&mgr);
   3320      1.1  mrg 
   3321      1.1  mrg     ADD_SAT_CONSTRAINT (model, x, GT_EXPR, y);
   3322      1.1  mrg 
   3323      1.1  mrg     ASSERT_CONDITION_TRUE (model, x, GT_EXPR, y);
   3324      1.1  mrg     ASSERT_CONDITION_TRUE (model, x, GE_EXPR, y);
   3325      1.1  mrg     ASSERT_CONDITION_TRUE (model, x, NE_EXPR, y);
   3326      1.1  mrg     ASSERT_CONDITION_FALSE (model, x, EQ_EXPR, y);
   3327      1.1  mrg     ASSERT_CONDITION_FALSE (model, x, LT_EXPR, y);
   3328      1.1  mrg     ASSERT_CONDITION_FALSE (model, x, LE_EXPR, y);
   3329      1.1  mrg 
   3330      1.1  mrg     /* Swapped operands.  */
   3331      1.1  mrg     ASSERT_CONDITION_FALSE (model, y, GT_EXPR, x);
   3332      1.1  mrg     ASSERT_CONDITION_FALSE (model, y, GE_EXPR, x);
   3333      1.1  mrg     ASSERT_CONDITION_TRUE (model, y, NE_EXPR, x);
   3334      1.1  mrg     ASSERT_CONDITION_FALSE (model, y, EQ_EXPR, x);
   3335      1.1  mrg     ASSERT_CONDITION_TRUE (model, y, LT_EXPR, x);
   3336      1.1  mrg     ASSERT_CONDITION_TRUE (model, y, LE_EXPR, x);
   3337      1.1  mrg   }
   3338      1.1  mrg 
   3339      1.1  mrg   /* x >= y.  */
   3340      1.1  mrg   {
   3341  1.1.1.2  mrg     region_model_manager mgr;
   3342  1.1.1.2  mrg     region_model model (&mgr);
   3343      1.1  mrg 
   3344      1.1  mrg     ADD_SAT_CONSTRAINT (model, x, GE_EXPR, y);
   3345      1.1  mrg 
   3346      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, x, GT_EXPR, y);
   3347      1.1  mrg     ASSERT_CONDITION_TRUE (model, x, GE_EXPR, y);
   3348      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, x, NE_EXPR, y);
   3349      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, x, EQ_EXPR, y);
   3350      1.1  mrg     ASSERT_CONDITION_FALSE (model, x, LT_EXPR, y);
   3351      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, x, LE_EXPR, y);
   3352      1.1  mrg 
   3353      1.1  mrg     /* Swapped operands.  */
   3354      1.1  mrg     ASSERT_CONDITION_FALSE (model, y, GT_EXPR, x);
   3355      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, y, GE_EXPR, x);
   3356      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, y, NE_EXPR, x);
   3357      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, y, EQ_EXPR, x);
   3358      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, y, LT_EXPR, x);
   3359      1.1  mrg     ASSERT_CONDITION_TRUE (model, y, LE_EXPR, x);
   3360      1.1  mrg   }
   3361      1.1  mrg 
   3362      1.1  mrg   // TODO: implied orderings
   3363      1.1  mrg 
   3364      1.1  mrg   /* Constants.  */
   3365      1.1  mrg   {
   3366  1.1.1.2  mrg     region_model_manager mgr;
   3367  1.1.1.2  mrg     region_model model (&mgr);
   3368      1.1  mrg     ASSERT_CONDITION_FALSE (model, int_0, EQ_EXPR, int_42);
   3369      1.1  mrg     ASSERT_CONDITION_TRUE (model, int_0, NE_EXPR, int_42);
   3370      1.1  mrg     ASSERT_CONDITION_TRUE (model, int_0, LT_EXPR, int_42);
   3371      1.1  mrg     ASSERT_CONDITION_TRUE (model, int_0, LE_EXPR, int_42);
   3372      1.1  mrg     ASSERT_CONDITION_FALSE (model, int_0, GT_EXPR, int_42);
   3373      1.1  mrg     ASSERT_CONDITION_FALSE (model, int_0, GE_EXPR, int_42);
   3374      1.1  mrg   }
   3375      1.1  mrg 
   3376      1.1  mrg   /* x == 0, y == 42.  */
   3377      1.1  mrg   {
   3378  1.1.1.2  mrg     region_model_manager mgr;
   3379  1.1.1.2  mrg     region_model model (&mgr);
   3380      1.1  mrg     ADD_SAT_CONSTRAINT (model, x, EQ_EXPR, int_0);
   3381      1.1  mrg     ADD_SAT_CONSTRAINT (model, y, EQ_EXPR, int_42);
   3382      1.1  mrg 
   3383      1.1  mrg     ASSERT_CONDITION_TRUE (model, x, NE_EXPR, y);
   3384      1.1  mrg     ASSERT_CONDITION_FALSE (model, x, EQ_EXPR, y);
   3385      1.1  mrg     ASSERT_CONDITION_TRUE (model, x, LE_EXPR, y);
   3386      1.1  mrg     ASSERT_CONDITION_FALSE (model, x, GE_EXPR, y);
   3387      1.1  mrg     ASSERT_CONDITION_TRUE (model, x, LT_EXPR, y);
   3388      1.1  mrg     ASSERT_CONDITION_FALSE (model, x, GT_EXPR, y);
   3389      1.1  mrg   }
   3390      1.1  mrg 
   3391      1.1  mrg   /* Unsatisfiable combinations.  */
   3392      1.1  mrg 
   3393      1.1  mrg   /* x == y && x != y.  */
   3394      1.1  mrg   {
   3395  1.1.1.2  mrg     region_model_manager mgr;
   3396  1.1.1.2  mrg     region_model model (&mgr);
   3397      1.1  mrg     ADD_SAT_CONSTRAINT (model, x, EQ_EXPR, y);
   3398      1.1  mrg     ADD_UNSAT_CONSTRAINT (model, x, NE_EXPR, y);
   3399      1.1  mrg   }
   3400      1.1  mrg 
   3401      1.1  mrg   /* x == 0 then x == 42.  */
   3402      1.1  mrg   {
   3403  1.1.1.2  mrg     region_model_manager mgr;
   3404  1.1.1.2  mrg     region_model model (&mgr);
   3405      1.1  mrg     ADD_SAT_CONSTRAINT (model, x, EQ_EXPR, int_0);
   3406      1.1  mrg     ADD_UNSAT_CONSTRAINT (model, x, EQ_EXPR, int_42);
   3407      1.1  mrg   }
   3408      1.1  mrg 
   3409      1.1  mrg   /* x == 0 then x != 0.  */
   3410      1.1  mrg   {
   3411  1.1.1.2  mrg     region_model_manager mgr;
   3412  1.1.1.2  mrg     region_model model (&mgr);
   3413      1.1  mrg     ADD_SAT_CONSTRAINT (model, x, EQ_EXPR, int_0);
   3414      1.1  mrg     ADD_UNSAT_CONSTRAINT (model, x, NE_EXPR, int_0);
   3415      1.1  mrg   }
   3416      1.1  mrg 
   3417      1.1  mrg   /* x == 0 then x > 0.  */
   3418      1.1  mrg   {
   3419  1.1.1.2  mrg     region_model_manager mgr;
   3420  1.1.1.2  mrg     region_model model (&mgr);
   3421      1.1  mrg     ADD_SAT_CONSTRAINT (model, x, EQ_EXPR, int_0);
   3422      1.1  mrg     ADD_UNSAT_CONSTRAINT (model, x, GT_EXPR, int_0);
   3423      1.1  mrg   }
   3424      1.1  mrg 
   3425      1.1  mrg   /* x != y && x == y.  */
   3426      1.1  mrg   {
   3427  1.1.1.2  mrg     region_model_manager mgr;
   3428  1.1.1.2  mrg     region_model model (&mgr);
   3429      1.1  mrg     ADD_SAT_CONSTRAINT (model, x, NE_EXPR, y);
   3430      1.1  mrg     ADD_UNSAT_CONSTRAINT (model, x, EQ_EXPR, y);
   3431      1.1  mrg   }
   3432      1.1  mrg 
   3433      1.1  mrg   /* x <= y && x > y.  */
   3434      1.1  mrg   {
   3435  1.1.1.2  mrg     region_model_manager mgr;
   3436  1.1.1.2  mrg     region_model model (&mgr);
   3437      1.1  mrg     ADD_SAT_CONSTRAINT (model, x, LE_EXPR, y);
   3438      1.1  mrg     ADD_UNSAT_CONSTRAINT (model, x, GT_EXPR, y);
   3439      1.1  mrg   }
   3440      1.1  mrg 
   3441      1.1  mrg   // etc
   3442      1.1  mrg }
   3443      1.1  mrg 
   3444      1.1  mrg /* Test transitivity of conditions.  */
   3445      1.1  mrg 
   3446      1.1  mrg static void
   3447      1.1  mrg test_transitivity ()
   3448      1.1  mrg {
   3449      1.1  mrg   tree a = build_global_decl ("a", integer_type_node);
   3450      1.1  mrg   tree b = build_global_decl ("b", integer_type_node);
   3451      1.1  mrg   tree c = build_global_decl ("c", integer_type_node);
   3452      1.1  mrg   tree d = build_global_decl ("d", integer_type_node);
   3453      1.1  mrg 
   3454      1.1  mrg   /* a == b, then c == d, then c == b.  */
   3455      1.1  mrg   {
   3456  1.1.1.2  mrg     region_model_manager mgr;
   3457  1.1.1.2  mrg     region_model model (&mgr);
   3458      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, a, EQ_EXPR, b);
   3459      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, b, EQ_EXPR, c);
   3460      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, c, EQ_EXPR, d);
   3461      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, a, EQ_EXPR, d);
   3462      1.1  mrg 
   3463      1.1  mrg     ADD_SAT_CONSTRAINT (model, a, EQ_EXPR, b);
   3464      1.1  mrg     ASSERT_CONDITION_TRUE (model, a, EQ_EXPR, b);
   3465      1.1  mrg 
   3466      1.1  mrg     ADD_SAT_CONSTRAINT (model, c, EQ_EXPR, d);
   3467      1.1  mrg     ASSERT_CONDITION_TRUE (model, c, EQ_EXPR, d);
   3468      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, a, EQ_EXPR, d);
   3469      1.1  mrg 
   3470      1.1  mrg     ADD_SAT_CONSTRAINT (model, c, EQ_EXPR, b);
   3471      1.1  mrg     ASSERT_CONDITION_TRUE (model, c, EQ_EXPR, b);
   3472      1.1  mrg     ASSERT_CONDITION_TRUE (model, a, EQ_EXPR, d);
   3473      1.1  mrg   }
   3474      1.1  mrg 
   3475      1.1  mrg   /* Transitivity: "a < b", "b < c" should imply "a < c".  */
   3476      1.1  mrg   {
   3477  1.1.1.2  mrg     region_model_manager mgr;
   3478  1.1.1.2  mrg     region_model model (&mgr);
   3479      1.1  mrg     ADD_SAT_CONSTRAINT (model, a, LT_EXPR, b);
   3480      1.1  mrg     ADD_SAT_CONSTRAINT (model, b, LT_EXPR, c);
   3481      1.1  mrg 
   3482      1.1  mrg     ASSERT_CONDITION_TRUE (model, a, LT_EXPR, c);
   3483      1.1  mrg     ASSERT_CONDITION_FALSE (model, a, EQ_EXPR, c);
   3484      1.1  mrg   }
   3485      1.1  mrg 
   3486      1.1  mrg   /* Transitivity: "a <= b", "b < c" should imply "a < c".  */
   3487      1.1  mrg   {
   3488  1.1.1.2  mrg     region_model_manager mgr;
   3489  1.1.1.2  mrg     region_model model (&mgr);
   3490      1.1  mrg     ADD_SAT_CONSTRAINT (model, a, LE_EXPR, b);
   3491      1.1  mrg     ADD_SAT_CONSTRAINT (model, b, LT_EXPR, c);
   3492      1.1  mrg 
   3493      1.1  mrg     ASSERT_CONDITION_TRUE (model, a, LT_EXPR, c);
   3494      1.1  mrg     ASSERT_CONDITION_FALSE (model, a, EQ_EXPR, c);
   3495      1.1  mrg   }
   3496      1.1  mrg 
   3497      1.1  mrg   /* Transitivity: "a <= b", "b <= c" should imply "a <= c".  */
   3498      1.1  mrg   {
   3499  1.1.1.2  mrg     region_model_manager mgr;
   3500  1.1.1.2  mrg     region_model model (&mgr);
   3501      1.1  mrg     ADD_SAT_CONSTRAINT (model, a, LE_EXPR, b);
   3502      1.1  mrg     ADD_SAT_CONSTRAINT (model, b, LE_EXPR, c);
   3503      1.1  mrg 
   3504      1.1  mrg     ASSERT_CONDITION_TRUE (model, a, LE_EXPR, c);
   3505      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, a, EQ_EXPR, c);
   3506      1.1  mrg   }
   3507      1.1  mrg 
   3508      1.1  mrg   /* Transitivity: "a > b", "b > c" should imply "a > c".  */
   3509      1.1  mrg   {
   3510  1.1.1.2  mrg     region_model_manager mgr;
   3511  1.1.1.2  mrg     region_model model (&mgr);
   3512      1.1  mrg     ADD_SAT_CONSTRAINT (model, a, GT_EXPR, b);
   3513      1.1  mrg     ADD_SAT_CONSTRAINT (model, b, GT_EXPR, c);
   3514      1.1  mrg 
   3515      1.1  mrg     ASSERT_CONDITION_TRUE (model, a, GT_EXPR, c);
   3516      1.1  mrg     ASSERT_CONDITION_FALSE (model, a, EQ_EXPR, c);
   3517      1.1  mrg   }
   3518      1.1  mrg 
   3519      1.1  mrg   /* Transitivity: "a >= b", "b > c" should imply " a > c".  */
   3520      1.1  mrg   {
   3521  1.1.1.2  mrg     region_model_manager mgr;
   3522  1.1.1.2  mrg     region_model model (&mgr);
   3523      1.1  mrg     ADD_SAT_CONSTRAINT (model, a, GE_EXPR, b);
   3524      1.1  mrg     ADD_SAT_CONSTRAINT (model, b, GT_EXPR, c);
   3525      1.1  mrg 
   3526      1.1  mrg     ASSERT_CONDITION_TRUE (model, a, GT_EXPR, c);
   3527      1.1  mrg     ASSERT_CONDITION_FALSE (model, a, EQ_EXPR, c);
   3528      1.1  mrg   }
   3529      1.1  mrg 
   3530      1.1  mrg   /* Transitivity: "a >= b", "b >= c" should imply "a >= c".  */
   3531      1.1  mrg   {
   3532  1.1.1.2  mrg     region_model_manager mgr;
   3533  1.1.1.2  mrg     region_model model (&mgr);
   3534      1.1  mrg     ADD_SAT_CONSTRAINT (model, a, GE_EXPR, b);
   3535      1.1  mrg     ADD_SAT_CONSTRAINT (model, b, GE_EXPR, c);
   3536      1.1  mrg 
   3537      1.1  mrg     ASSERT_CONDITION_TRUE (model, a, GE_EXPR, c);
   3538      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, a, EQ_EXPR, c);
   3539      1.1  mrg   }
   3540      1.1  mrg 
   3541      1.1  mrg   /* Transitivity: "(a < b)", "(c < d)", "(b < c)" should
   3542      1.1  mrg      imply the easy cases:
   3543      1.1  mrg        (a < c)
   3544      1.1  mrg        (b < d)
   3545      1.1  mrg      but also that:
   3546      1.1  mrg        (a < d).  */
   3547      1.1  mrg   {
   3548  1.1.1.2  mrg     region_model_manager mgr;
   3549  1.1.1.2  mrg     region_model model (&mgr);
   3550      1.1  mrg     ADD_SAT_CONSTRAINT (model, a, LT_EXPR, b);
   3551      1.1  mrg     ADD_SAT_CONSTRAINT (model, c, LT_EXPR, d);
   3552      1.1  mrg     ADD_SAT_CONSTRAINT (model, b, LT_EXPR, c);
   3553      1.1  mrg 
   3554      1.1  mrg     ASSERT_CONDITION_TRUE (model, a, LT_EXPR, c);
   3555      1.1  mrg     ASSERT_CONDITION_TRUE (model, b, LT_EXPR, d);
   3556      1.1  mrg     ASSERT_CONDITION_TRUE (model, a, LT_EXPR, d);
   3557      1.1  mrg   }
   3558      1.1  mrg 
   3559      1.1  mrg   /* Transitivity: "a >= b", "b >= a" should imply that a == b.  */
   3560      1.1  mrg   {
   3561  1.1.1.2  mrg     region_model_manager mgr;
   3562  1.1.1.2  mrg     region_model model (&mgr);
   3563      1.1  mrg     ADD_SAT_CONSTRAINT (model, a, GE_EXPR, b);
   3564      1.1  mrg     ADD_SAT_CONSTRAINT (model, b, GE_EXPR, a);
   3565      1.1  mrg 
   3566      1.1  mrg     // TODO:
   3567      1.1  mrg     ASSERT_CONDITION_TRUE (model, a, EQ_EXPR, b);
   3568  1.1.1.2  mrg 
   3569  1.1.1.2  mrg     /* The ECs for a and b should have merged, and any constraints removed.  */
   3570  1.1.1.2  mrg     ASSERT_EQ (model.get_constraints ()->m_equiv_classes.length (), 1);
   3571  1.1.1.2  mrg     ASSERT_EQ (model.get_constraints ()->m_constraints.length (), 0);
   3572      1.1  mrg   }
   3573      1.1  mrg 
   3574      1.1  mrg   /* Transitivity: "a >= b", "b > a" should be impossible.  */
   3575      1.1  mrg   {
   3576  1.1.1.2  mrg     region_model_manager mgr;
   3577  1.1.1.2  mrg     region_model model (&mgr);
   3578      1.1  mrg     ADD_SAT_CONSTRAINT (model, a, GE_EXPR, b);
   3579      1.1  mrg     ADD_UNSAT_CONSTRAINT (model, b, GT_EXPR, a);
   3580      1.1  mrg   }
   3581      1.1  mrg 
   3582      1.1  mrg   /* Transitivity: "a >= b", "b >= c", "c >= a" should imply
   3583      1.1  mrg      that a == b == c.  */
   3584      1.1  mrg   {
   3585  1.1.1.2  mrg     region_model_manager mgr;
   3586  1.1.1.2  mrg     region_model model (&mgr);
   3587      1.1  mrg     ADD_SAT_CONSTRAINT (model, a, GE_EXPR, b);
   3588      1.1  mrg     ADD_SAT_CONSTRAINT (model, b, GE_EXPR, c);
   3589      1.1  mrg     ADD_SAT_CONSTRAINT (model, c, GE_EXPR, a);
   3590      1.1  mrg 
   3591      1.1  mrg     ASSERT_CONDITION_TRUE (model, a, EQ_EXPR, c);
   3592      1.1  mrg   }
   3593      1.1  mrg 
   3594      1.1  mrg   /* Transitivity: "a > b", "b > c", "c > a"
   3595      1.1  mrg      should be impossible.  */
   3596      1.1  mrg   {
   3597  1.1.1.2  mrg     region_model_manager mgr;
   3598  1.1.1.2  mrg     region_model model (&mgr);
   3599      1.1  mrg     ADD_SAT_CONSTRAINT (model, a, GT_EXPR, b);
   3600      1.1  mrg     ADD_SAT_CONSTRAINT (model, b, GT_EXPR, c);
   3601      1.1  mrg     ADD_UNSAT_CONSTRAINT (model, c, GT_EXPR, a);
   3602      1.1  mrg   }
   3603      1.1  mrg 
   3604      1.1  mrg }
   3605      1.1  mrg 
   3606      1.1  mrg /* Test various conditionals involving constants where the results
   3607      1.1  mrg    ought to be implied based on the values of the constants.  */
   3608      1.1  mrg 
   3609      1.1  mrg static void
   3610      1.1  mrg test_constant_comparisons ()
   3611      1.1  mrg {
   3612  1.1.1.2  mrg   tree int_1 = build_int_cst (integer_type_node, 1);
   3613      1.1  mrg   tree int_3 = build_int_cst (integer_type_node, 3);
   3614      1.1  mrg   tree int_4 = build_int_cst (integer_type_node, 4);
   3615      1.1  mrg   tree int_5 = build_int_cst (integer_type_node, 5);
   3616      1.1  mrg 
   3617      1.1  mrg   tree int_1023 = build_int_cst (integer_type_node, 1023);
   3618      1.1  mrg   tree int_1024 = build_int_cst (integer_type_node, 1024);
   3619      1.1  mrg 
   3620      1.1  mrg   tree a = build_global_decl ("a", integer_type_node);
   3621      1.1  mrg   tree b = build_global_decl ("b", integer_type_node);
   3622      1.1  mrg 
   3623  1.1.1.2  mrg   tree a_plus_one = build2 (PLUS_EXPR, integer_type_node, a, int_1);
   3624  1.1.1.2  mrg 
   3625      1.1  mrg   /* Given a >= 1024, then a <= 1023 should be impossible.  */
   3626      1.1  mrg   {
   3627  1.1.1.2  mrg     region_model_manager mgr;
   3628  1.1.1.2  mrg     region_model model (&mgr);
   3629      1.1  mrg     ADD_SAT_CONSTRAINT (model, a, GE_EXPR, int_1024);
   3630      1.1  mrg     ADD_UNSAT_CONSTRAINT (model, a, LE_EXPR, int_1023);
   3631      1.1  mrg   }
   3632      1.1  mrg 
   3633      1.1  mrg   /* a > 4.  */
   3634      1.1  mrg   {
   3635  1.1.1.2  mrg     region_model_manager mgr;
   3636  1.1.1.2  mrg     region_model model (&mgr);
   3637      1.1  mrg     ADD_SAT_CONSTRAINT (model, a, GT_EXPR, int_4);
   3638      1.1  mrg     ASSERT_CONDITION_TRUE (model, a, GT_EXPR, int_4);
   3639      1.1  mrg     ASSERT_CONDITION_TRUE (model, a, NE_EXPR, int_3);
   3640      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, a, NE_EXPR, int_5);
   3641      1.1  mrg   }
   3642      1.1  mrg 
   3643      1.1  mrg   /* a <= 4.  */
   3644      1.1  mrg   {
   3645  1.1.1.2  mrg     region_model_manager mgr;
   3646  1.1.1.2  mrg     region_model model (&mgr);
   3647      1.1  mrg     ADD_SAT_CONSTRAINT (model, a, LE_EXPR, int_4);
   3648      1.1  mrg     ASSERT_CONDITION_FALSE (model, a, GT_EXPR, int_4);
   3649      1.1  mrg     ASSERT_CONDITION_FALSE (model, a, GT_EXPR, int_5);
   3650      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, a, NE_EXPR, int_3);
   3651      1.1  mrg   }
   3652      1.1  mrg 
   3653      1.1  mrg   /* If "a > b" and "a == 3", then "b == 4" ought to be unsatisfiable.  */
   3654      1.1  mrg   {
   3655  1.1.1.2  mrg     region_model_manager mgr;
   3656  1.1.1.2  mrg     region_model model (&mgr);
   3657      1.1  mrg     ADD_SAT_CONSTRAINT (model, a, GT_EXPR, b);
   3658      1.1  mrg     ADD_SAT_CONSTRAINT (model, a, EQ_EXPR, int_3);
   3659      1.1  mrg     ADD_UNSAT_CONSTRAINT (model, b, EQ_EXPR, int_4);
   3660      1.1  mrg   }
   3661      1.1  mrg 
   3662      1.1  mrg   /* Various tests of int ranges where there is only one possible candidate.  */
   3663      1.1  mrg   {
   3664      1.1  mrg     /* If "a <= 4" && "a > 3", then "a == 4",
   3665      1.1  mrg        assuming a is of integral type.  */
   3666      1.1  mrg     {
   3667  1.1.1.2  mrg       region_model_manager mgr;
   3668  1.1.1.2  mrg       region_model model (&mgr);
   3669      1.1  mrg       ADD_SAT_CONSTRAINT (model, a, LE_EXPR, int_4);
   3670      1.1  mrg       ADD_SAT_CONSTRAINT (model, a, GT_EXPR, int_3);
   3671      1.1  mrg       ASSERT_CONDITION_TRUE (model, a, EQ_EXPR, int_4);
   3672      1.1  mrg     }
   3673      1.1  mrg 
   3674      1.1  mrg     /* If "a > 3" && "a <= 4", then "a == 4",
   3675      1.1  mrg        assuming a is of integral type.  */
   3676      1.1  mrg     {
   3677  1.1.1.2  mrg       region_model_manager mgr;
   3678  1.1.1.2  mrg       region_model model (&mgr);
   3679      1.1  mrg       ADD_SAT_CONSTRAINT (model, a, GT_EXPR, int_3);
   3680      1.1  mrg       ADD_SAT_CONSTRAINT (model, a, LE_EXPR, int_4);
   3681      1.1  mrg       ASSERT_CONDITION_TRUE (model, a, EQ_EXPR, int_4);
   3682      1.1  mrg     }
   3683      1.1  mrg     /* If "a > 3" && "a < 5", then "a == 4",
   3684      1.1  mrg        assuming a is of integral type.  */
   3685      1.1  mrg     {
   3686  1.1.1.2  mrg       region_model_manager mgr;
   3687  1.1.1.2  mrg       region_model model (&mgr);
   3688      1.1  mrg       ADD_SAT_CONSTRAINT (model, a, GT_EXPR, int_3);
   3689      1.1  mrg       ADD_SAT_CONSTRAINT (model, a, LT_EXPR, int_5);
   3690      1.1  mrg       ASSERT_CONDITION_TRUE (model, a, EQ_EXPR, int_4);
   3691      1.1  mrg     }
   3692      1.1  mrg     /* If "a >= 4" && "a < 5", then "a == 4",
   3693      1.1  mrg        assuming a is of integral type.  */
   3694      1.1  mrg     {
   3695  1.1.1.2  mrg       region_model_manager mgr;
   3696  1.1.1.2  mrg       region_model model (&mgr);
   3697      1.1  mrg       ADD_SAT_CONSTRAINT (model, a, GE_EXPR, int_4);
   3698      1.1  mrg       ADD_SAT_CONSTRAINT (model, a, LT_EXPR, int_5);
   3699      1.1  mrg       ASSERT_CONDITION_TRUE (model, a, EQ_EXPR, int_4);
   3700      1.1  mrg     }
   3701      1.1  mrg     /* If "a >= 4" && "a <= 4", then "a == 4".  */
   3702      1.1  mrg     {
   3703  1.1.1.2  mrg       region_model_manager mgr;
   3704  1.1.1.2  mrg       region_model model (&mgr);
   3705      1.1  mrg       ADD_SAT_CONSTRAINT (model, a, GE_EXPR, int_4);
   3706      1.1  mrg       ADD_SAT_CONSTRAINT (model, a, LE_EXPR, int_4);
   3707      1.1  mrg       ASSERT_CONDITION_TRUE (model, a, EQ_EXPR, int_4);
   3708      1.1  mrg     }
   3709      1.1  mrg   }
   3710      1.1  mrg 
   3711      1.1  mrg   /* As above, but for floating-point:
   3712      1.1  mrg      if "f > 3" && "f <= 4" we don't know that f == 4.  */
   3713      1.1  mrg   {
   3714      1.1  mrg     tree f = build_global_decl ("f", double_type_node);
   3715      1.1  mrg     tree float_3 = build_real_from_int_cst (double_type_node, int_3);
   3716      1.1  mrg     tree float_4 = build_real_from_int_cst (double_type_node, int_4);
   3717      1.1  mrg 
   3718  1.1.1.2  mrg     region_model_manager mgr;
   3719  1.1.1.2  mrg     region_model model (&mgr);
   3720      1.1  mrg     ADD_SAT_CONSTRAINT (model, f, GT_EXPR, float_3);
   3721      1.1  mrg     ADD_SAT_CONSTRAINT (model, f, LE_EXPR, float_4);
   3722      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, f, EQ_EXPR, float_4);
   3723      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, f, EQ_EXPR, int_4);
   3724      1.1  mrg   }
   3725  1.1.1.2  mrg 
   3726  1.1.1.2  mrg   /* "a > 3 && a <= 3" should be impossible.  */
   3727  1.1.1.2  mrg   {
   3728  1.1.1.2  mrg     region_model_manager mgr;
   3729  1.1.1.2  mrg     region_model model (&mgr);
   3730  1.1.1.2  mrg     ADD_SAT_CONSTRAINT (model, a, GT_EXPR, int_3);
   3731  1.1.1.2  mrg     ADD_UNSAT_CONSTRAINT (model, a, LE_EXPR, int_3);
   3732  1.1.1.2  mrg   }
   3733  1.1.1.2  mrg 
   3734  1.1.1.2  mrg   /* "(a + 1) > 3 && a < 3" should be impossible.  */
   3735  1.1.1.2  mrg   {
   3736  1.1.1.2  mrg     region_model_manager mgr;
   3737  1.1.1.2  mrg     {
   3738  1.1.1.2  mrg       region_model model (&mgr);
   3739  1.1.1.2  mrg       ADD_SAT_CONSTRAINT (model, a_plus_one, GT_EXPR, int_3);
   3740  1.1.1.2  mrg       ADD_UNSAT_CONSTRAINT (model, a, LT_EXPR, int_3);
   3741  1.1.1.2  mrg     }
   3742  1.1.1.2  mrg     {
   3743  1.1.1.2  mrg       region_model model (&mgr);
   3744  1.1.1.2  mrg       ADD_SAT_CONSTRAINT (model, a, LT_EXPR, int_3);
   3745  1.1.1.2  mrg       ADD_UNSAT_CONSTRAINT (model, a_plus_one, GT_EXPR, int_3);
   3746  1.1.1.2  mrg     }
   3747  1.1.1.2  mrg   }
   3748  1.1.1.2  mrg 
   3749  1.1.1.2  mrg   /* "3 < a < 4" should be impossible for integer a.  */
   3750  1.1.1.2  mrg   {
   3751  1.1.1.2  mrg     region_model_manager mgr;
   3752  1.1.1.2  mrg     {
   3753  1.1.1.2  mrg       region_model model (&mgr);
   3754  1.1.1.2  mrg       ADD_SAT_CONSTRAINT (model, int_3, LT_EXPR, a);
   3755  1.1.1.2  mrg       ADD_UNSAT_CONSTRAINT (model, a, LT_EXPR, int_4);
   3756  1.1.1.2  mrg     }
   3757  1.1.1.2  mrg     {
   3758  1.1.1.2  mrg       region_model model (&mgr);
   3759  1.1.1.2  mrg       ADD_SAT_CONSTRAINT (model, int_1, LT_EXPR, a);
   3760  1.1.1.2  mrg       ADD_SAT_CONSTRAINT (model, int_3, LT_EXPR, a);
   3761  1.1.1.2  mrg       ADD_SAT_CONSTRAINT (model, a, LT_EXPR, int_5);
   3762  1.1.1.2  mrg       ADD_UNSAT_CONSTRAINT (model, a, LT_EXPR, int_4);
   3763  1.1.1.2  mrg     }
   3764  1.1.1.2  mrg     {
   3765  1.1.1.2  mrg       region_model model (&mgr);
   3766  1.1.1.2  mrg       ADD_SAT_CONSTRAINT (model, int_1, LT_EXPR, a);
   3767  1.1.1.2  mrg       ADD_SAT_CONSTRAINT (model, a, LT_EXPR, int_5);
   3768  1.1.1.2  mrg       ADD_SAT_CONSTRAINT (model, int_3, LT_EXPR, a);
   3769  1.1.1.2  mrg       ADD_UNSAT_CONSTRAINT (model, a, LT_EXPR, int_4);
   3770  1.1.1.2  mrg     }
   3771  1.1.1.2  mrg     {
   3772  1.1.1.2  mrg       region_model model (&mgr);
   3773  1.1.1.2  mrg       ADD_SAT_CONSTRAINT (model, a, LT_EXPR, int_4);
   3774  1.1.1.2  mrg       ADD_UNSAT_CONSTRAINT (model, int_3, LT_EXPR, a);
   3775  1.1.1.2  mrg     }
   3776  1.1.1.2  mrg     {
   3777  1.1.1.2  mrg       region_model model (&mgr);
   3778  1.1.1.2  mrg       ADD_SAT_CONSTRAINT (model, a, GT_EXPR, int_3);
   3779  1.1.1.2  mrg       ADD_UNSAT_CONSTRAINT (model, int_4, GT_EXPR, a);
   3780  1.1.1.2  mrg     }
   3781  1.1.1.2  mrg     {
   3782  1.1.1.2  mrg       region_model model (&mgr);
   3783  1.1.1.2  mrg       ADD_SAT_CONSTRAINT (model, int_4, GT_EXPR, a);
   3784  1.1.1.2  mrg       ADD_UNSAT_CONSTRAINT (model, a, GT_EXPR, int_3);
   3785  1.1.1.2  mrg     }
   3786  1.1.1.2  mrg   }
   3787      1.1  mrg }
   3788      1.1  mrg 
   3789      1.1  mrg /* Verify various lower-level implementation details about
   3790      1.1  mrg    constraint_manager.  */
   3791      1.1  mrg 
   3792      1.1  mrg static void
   3793      1.1  mrg test_constraint_impl ()
   3794      1.1  mrg {
   3795      1.1  mrg   tree int_42 = build_int_cst (integer_type_node, 42);
   3796      1.1  mrg   tree int_0 = build_int_cst (integer_type_node, 0);
   3797      1.1  mrg 
   3798      1.1  mrg   tree x = build_global_decl ("x", integer_type_node);
   3799      1.1  mrg   tree y = build_global_decl ("y", integer_type_node);
   3800      1.1  mrg   tree z = build_global_decl ("z", integer_type_node);
   3801      1.1  mrg 
   3802      1.1  mrg   /* x == y.  */
   3803      1.1  mrg   {
   3804  1.1.1.2  mrg     region_model_manager mgr;
   3805  1.1.1.2  mrg     region_model model (&mgr);
   3806      1.1  mrg 
   3807      1.1  mrg     ADD_SAT_CONSTRAINT (model, x, EQ_EXPR, y);
   3808      1.1  mrg 
   3809      1.1  mrg     /* Assert various things about the insides of model.  */
   3810      1.1  mrg     constraint_manager *cm = model.get_constraints ();
   3811      1.1  mrg     ASSERT_EQ (cm->m_constraints.length (), 0);
   3812      1.1  mrg     ASSERT_EQ (cm->m_equiv_classes.length (), 1);
   3813      1.1  mrg   }
   3814      1.1  mrg 
   3815      1.1  mrg   /* y <= z; x == y.  */
   3816      1.1  mrg   {
   3817  1.1.1.2  mrg     region_model_manager mgr;
   3818  1.1.1.2  mrg     region_model model (&mgr);
   3819      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, x, EQ_EXPR, y);
   3820      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, x, GE_EXPR, z);
   3821      1.1  mrg 
   3822      1.1  mrg     ADD_SAT_CONSTRAINT (model, y, GE_EXPR, z);
   3823      1.1  mrg     ASSERT_CONDITION_TRUE (model, y, GE_EXPR, z);
   3824      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, x, GE_EXPR, z);
   3825      1.1  mrg 
   3826      1.1  mrg     ADD_SAT_CONSTRAINT (model, x, EQ_EXPR, y);
   3827      1.1  mrg 
   3828      1.1  mrg     /* Assert various things about the insides of model.  */
   3829      1.1  mrg     constraint_manager *cm = model.get_constraints ();
   3830      1.1  mrg     ASSERT_EQ (cm->m_constraints.length (), 1);
   3831      1.1  mrg     ASSERT_EQ (cm->m_equiv_classes.length (), 2);
   3832      1.1  mrg 
   3833      1.1  mrg     /* Ensure that we merged the constraints.  */
   3834      1.1  mrg     ASSERT_CONDITION_TRUE (model, x, GE_EXPR, z);
   3835      1.1  mrg   }
   3836      1.1  mrg 
   3837      1.1  mrg   /* y <= z; y == x.  */
   3838      1.1  mrg   {
   3839  1.1.1.2  mrg     region_model_manager mgr;
   3840  1.1.1.2  mrg     region_model model (&mgr);
   3841      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, x, EQ_EXPR, y);
   3842      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, x, GE_EXPR, z);
   3843      1.1  mrg 
   3844      1.1  mrg     ADD_SAT_CONSTRAINT (model, y, GE_EXPR, z);
   3845      1.1  mrg     ASSERT_CONDITION_TRUE (model, y, GE_EXPR, z);
   3846      1.1  mrg     ASSERT_CONDITION_UNKNOWN (model, x, GE_EXPR, z);
   3847      1.1  mrg 
   3848      1.1  mrg     ADD_SAT_CONSTRAINT (model, y, EQ_EXPR, x);
   3849      1.1  mrg 
   3850      1.1  mrg     /* Assert various things about the insides of model.  */
   3851      1.1  mrg     constraint_manager *cm = model.get_constraints ();
   3852      1.1  mrg     ASSERT_EQ (cm->m_constraints.length (), 1);
   3853      1.1  mrg     ASSERT_EQ (cm->m_equiv_classes.length (), 2);
   3854      1.1  mrg 
   3855      1.1  mrg     /* Ensure that we merged the constraints.  */
   3856      1.1  mrg     ASSERT_CONDITION_TRUE (model, x, GE_EXPR, z);
   3857      1.1  mrg   }
   3858      1.1  mrg 
   3859      1.1  mrg   /* x == 0, then x != 42.  */
   3860      1.1  mrg   {
   3861  1.1.1.2  mrg     region_model_manager mgr;
   3862  1.1.1.2  mrg     region_model model (&mgr);
   3863      1.1  mrg 
   3864      1.1  mrg     ADD_SAT_CONSTRAINT (model, x, EQ_EXPR, int_0);
   3865      1.1  mrg     ADD_SAT_CONSTRAINT (model, x, NE_EXPR, int_42);
   3866      1.1  mrg 
   3867      1.1  mrg     /* Assert various things about the insides of model.  */
   3868      1.1  mrg     constraint_manager *cm = model.get_constraints ();
   3869  1.1.1.2  mrg     ASSERT_EQ (cm->m_constraints.length (), 0);
   3870  1.1.1.2  mrg     ASSERT_EQ (cm->m_equiv_classes.length (), 1);
   3871      1.1  mrg   }
   3872      1.1  mrg 
   3873      1.1  mrg   // TODO: selftest for merging ecs "in the middle"
   3874      1.1  mrg   // where a non-final one gets overwritten
   3875      1.1  mrg 
   3876      1.1  mrg   // TODO: selftest where there are pre-existing constraints
   3877      1.1  mrg }
   3878      1.1  mrg 
   3879      1.1  mrg /* Check that operator== and hashing works as expected for the
   3880      1.1  mrg    various types.  */
   3881      1.1  mrg 
   3882      1.1  mrg static void
   3883      1.1  mrg test_equality ()
   3884      1.1  mrg {
   3885      1.1  mrg   tree x = build_global_decl ("x", integer_type_node);
   3886      1.1  mrg   tree y = build_global_decl ("y", integer_type_node);
   3887      1.1  mrg 
   3888      1.1  mrg   {
   3889  1.1.1.2  mrg     region_model_manager mgr;
   3890  1.1.1.2  mrg     region_model model0 (&mgr);
   3891  1.1.1.2  mrg     region_model model1 (&mgr);
   3892      1.1  mrg 
   3893      1.1  mrg     constraint_manager *cm0 = model0.get_constraints ();
   3894      1.1  mrg     constraint_manager *cm1 = model1.get_constraints ();
   3895      1.1  mrg 
   3896      1.1  mrg     ASSERT_EQ (cm0->hash (), cm1->hash ());
   3897      1.1  mrg     ASSERT_EQ (*cm0, *cm1);
   3898      1.1  mrg 
   3899      1.1  mrg     ASSERT_EQ (model0.hash (), model1.hash ());
   3900      1.1  mrg     ASSERT_EQ (model0, model1);
   3901      1.1  mrg 
   3902      1.1  mrg     ADD_SAT_CONSTRAINT (model1, x, EQ_EXPR, y);
   3903      1.1  mrg     ASSERT_NE (cm0->hash (), cm1->hash ());
   3904      1.1  mrg     ASSERT_NE (*cm0, *cm1);
   3905      1.1  mrg 
   3906      1.1  mrg     ASSERT_NE (model0.hash (), model1.hash ());
   3907      1.1  mrg     ASSERT_NE (model0, model1);
   3908      1.1  mrg 
   3909  1.1.1.2  mrg     region_model model2 (&mgr);
   3910      1.1  mrg     constraint_manager *cm2 = model2.get_constraints ();
   3911      1.1  mrg     /* Make the same change to cm2.  */
   3912      1.1  mrg     ADD_SAT_CONSTRAINT (model2, x, EQ_EXPR, y);
   3913      1.1  mrg     ASSERT_EQ (cm1->hash (), cm2->hash ());
   3914      1.1  mrg     ASSERT_EQ (*cm1, *cm2);
   3915      1.1  mrg 
   3916      1.1  mrg     ASSERT_EQ (model1.hash (), model2.hash ());
   3917      1.1  mrg     ASSERT_EQ (model1, model2);
   3918      1.1  mrg   }
   3919      1.1  mrg }
   3920      1.1  mrg 
   3921      1.1  mrg /* Verify tracking inequality of a variable against many constants.  */
   3922      1.1  mrg 
   3923      1.1  mrg static void
   3924      1.1  mrg test_many_constants ()
   3925      1.1  mrg {
   3926  1.1.1.2  mrg   program_point point (program_point::origin ());
   3927      1.1  mrg   tree a = build_global_decl ("a", integer_type_node);
   3928      1.1  mrg 
   3929  1.1.1.2  mrg   region_model_manager mgr;
   3930  1.1.1.2  mrg   region_model model (&mgr);
   3931      1.1  mrg   auto_vec<tree> constants;
   3932      1.1  mrg   for (int i = 0; i < 20; i++)
   3933      1.1  mrg     {
   3934      1.1  mrg       tree constant = build_int_cst (integer_type_node, i);
   3935      1.1  mrg       constants.safe_push (constant);
   3936      1.1  mrg       ADD_SAT_CONSTRAINT (model, a, NE_EXPR, constant);
   3937      1.1  mrg 
   3938      1.1  mrg       /* Merge, and check the result.  */
   3939      1.1  mrg       region_model other (model);
   3940      1.1  mrg 
   3941  1.1.1.2  mrg       region_model merged (&mgr);
   3942  1.1.1.2  mrg       ASSERT_TRUE (model.can_merge_with_p (other, point, &merged));
   3943  1.1.1.2  mrg       model.canonicalize ();
   3944  1.1.1.2  mrg       merged.canonicalize ();
   3945      1.1  mrg       ASSERT_EQ (model, merged);
   3946      1.1  mrg 
   3947      1.1  mrg       for (int j = 0; j <= i; j++)
   3948      1.1  mrg 	ASSERT_CONDITION_TRUE (model, a, NE_EXPR, constants[j]);
   3949      1.1  mrg     }
   3950      1.1  mrg }
   3951      1.1  mrg 
   3952  1.1.1.2  mrg /* Verify that purging state relating to a variable doesn't leave stray
   3953  1.1.1.2  mrg    equivalence classes (after canonicalization).  */
   3954  1.1.1.2  mrg 
   3955  1.1.1.2  mrg static void
   3956  1.1.1.2  mrg test_purging (void)
   3957  1.1.1.2  mrg {
   3958  1.1.1.2  mrg   tree int_0 = build_int_cst (integer_type_node, 0);
   3959  1.1.1.2  mrg   tree a = build_global_decl ("a", integer_type_node);
   3960  1.1.1.2  mrg   tree b = build_global_decl ("b", integer_type_node);
   3961  1.1.1.2  mrg 
   3962  1.1.1.2  mrg   /*  "a != 0".  */
   3963  1.1.1.2  mrg   {
   3964  1.1.1.2  mrg     region_model_manager mgr;
   3965  1.1.1.2  mrg     region_model model (&mgr);
   3966  1.1.1.2  mrg     ADD_SAT_CONSTRAINT (model, a, NE_EXPR, int_0);
   3967  1.1.1.2  mrg     ASSERT_EQ (model.get_constraints ()->m_equiv_classes.length (), 2);
   3968  1.1.1.2  mrg     ASSERT_EQ (model.get_constraints ()->m_constraints.length (), 1);
   3969  1.1.1.2  mrg 
   3970  1.1.1.2  mrg     /* Purge state for "a".  */
   3971  1.1.1.2  mrg     const svalue *sval_a = model.get_rvalue (a, NULL);
   3972  1.1.1.2  mrg     model.purge_state_involving (sval_a, NULL);
   3973  1.1.1.2  mrg     model.canonicalize ();
   3974  1.1.1.2  mrg     /* We should have an empty constraint_manager.  */
   3975  1.1.1.2  mrg     ASSERT_EQ (model.get_constraints ()->m_equiv_classes.length (), 0);
   3976  1.1.1.2  mrg     ASSERT_EQ (model.get_constraints ()->m_constraints.length (), 0);
   3977  1.1.1.2  mrg   }
   3978  1.1.1.2  mrg 
   3979  1.1.1.2  mrg   /*  "a != 0" && "b != 0".  */
   3980  1.1.1.2  mrg   {
   3981  1.1.1.2  mrg     region_model_manager mgr;
   3982  1.1.1.2  mrg     region_model model (&mgr);
   3983  1.1.1.2  mrg     ADD_SAT_CONSTRAINT (model, a, NE_EXPR, int_0);
   3984  1.1.1.2  mrg     ADD_SAT_CONSTRAINT (model, b, NE_EXPR, int_0);
   3985  1.1.1.2  mrg     ASSERT_EQ (model.get_constraints ()->m_equiv_classes.length (), 3);
   3986  1.1.1.2  mrg     ASSERT_EQ (model.get_constraints ()->m_constraints.length (), 2);
   3987  1.1.1.2  mrg 
   3988  1.1.1.2  mrg     /* Purge state for "a".  */
   3989  1.1.1.2  mrg     const svalue *sval_a = model.get_rvalue (a, NULL);
   3990  1.1.1.2  mrg     model.purge_state_involving (sval_a, NULL);
   3991  1.1.1.2  mrg     model.canonicalize ();
   3992  1.1.1.2  mrg     /* We should just have the constraint/ECs involving b != 0.  */
   3993  1.1.1.2  mrg     ASSERT_EQ (model.get_constraints ()->m_equiv_classes.length (), 2);
   3994  1.1.1.2  mrg     ASSERT_EQ (model.get_constraints ()->m_constraints.length (), 1);
   3995  1.1.1.2  mrg     ASSERT_CONDITION_TRUE (model, b, NE_EXPR, int_0);
   3996  1.1.1.2  mrg   }
   3997  1.1.1.2  mrg 
   3998  1.1.1.2  mrg   /*  "a != 0" && "b == 0".  */
   3999  1.1.1.2  mrg   {
   4000  1.1.1.2  mrg     region_model_manager mgr;
   4001  1.1.1.2  mrg     region_model model (&mgr);
   4002  1.1.1.2  mrg     ADD_SAT_CONSTRAINT (model, a, NE_EXPR, int_0);
   4003  1.1.1.2  mrg     ADD_SAT_CONSTRAINT (model, b, EQ_EXPR, int_0);
   4004  1.1.1.2  mrg     ASSERT_EQ (model.get_constraints ()->m_equiv_classes.length (), 2);
   4005  1.1.1.2  mrg     ASSERT_EQ (model.get_constraints ()->m_constraints.length (), 1);
   4006  1.1.1.2  mrg 
   4007  1.1.1.2  mrg     /* Purge state for "a".  */
   4008  1.1.1.2  mrg     const svalue *sval_a = model.get_rvalue (a, NULL);
   4009  1.1.1.2  mrg     model.purge_state_involving (sval_a, NULL);
   4010  1.1.1.2  mrg     model.canonicalize ();
   4011  1.1.1.2  mrg     /* We should just have the EC involving b == 0.  */
   4012  1.1.1.2  mrg     ASSERT_EQ (model.get_constraints ()->m_equiv_classes.length (), 1);
   4013  1.1.1.2  mrg     ASSERT_EQ (model.get_constraints ()->m_constraints.length (), 0);
   4014  1.1.1.2  mrg     ASSERT_CONDITION_TRUE (model, b, EQ_EXPR, int_0);
   4015  1.1.1.2  mrg   }
   4016  1.1.1.2  mrg 
   4017  1.1.1.2  mrg   /*  "a == 0".  */
   4018  1.1.1.2  mrg   {
   4019  1.1.1.2  mrg     region_model_manager mgr;
   4020  1.1.1.2  mrg     region_model model (&mgr);
   4021  1.1.1.2  mrg     ADD_SAT_CONSTRAINT (model, a, EQ_EXPR, int_0);
   4022  1.1.1.2  mrg     ASSERT_EQ (model.get_constraints ()->m_equiv_classes.length (), 1);
   4023  1.1.1.2  mrg     ASSERT_EQ (model.get_constraints ()->m_constraints.length (), 0);
   4024  1.1.1.2  mrg 
   4025  1.1.1.2  mrg     /* Purge state for "a".  */
   4026  1.1.1.2  mrg     const svalue *sval_a = model.get_rvalue (a, NULL);
   4027  1.1.1.2  mrg     model.purge_state_involving (sval_a, NULL);
   4028  1.1.1.2  mrg     model.canonicalize ();
   4029  1.1.1.2  mrg     /* We should have an empty constraint_manager.  */
   4030  1.1.1.2  mrg     ASSERT_EQ (model.get_constraints ()->m_equiv_classes.length (), 0);
   4031  1.1.1.2  mrg     ASSERT_EQ (model.get_constraints ()->m_constraints.length (), 0);
   4032  1.1.1.2  mrg   }
   4033  1.1.1.2  mrg 
   4034  1.1.1.2  mrg   /*  "a == 0" && "b != 0".  */
   4035  1.1.1.2  mrg   {
   4036  1.1.1.2  mrg     region_model_manager mgr;
   4037  1.1.1.2  mrg     region_model model (&mgr);
   4038  1.1.1.2  mrg     ADD_SAT_CONSTRAINT (model, a, EQ_EXPR, int_0);
   4039  1.1.1.2  mrg     ADD_SAT_CONSTRAINT (model, b, NE_EXPR, int_0);
   4040  1.1.1.2  mrg     ASSERT_EQ (model.get_constraints ()->m_equiv_classes.length (), 2);
   4041  1.1.1.2  mrg     ASSERT_EQ (model.get_constraints ()->m_constraints.length (), 1);
   4042  1.1.1.2  mrg 
   4043  1.1.1.2  mrg     /* Purge state for "a".  */
   4044  1.1.1.2  mrg     const svalue *sval_a = model.get_rvalue (a, NULL);
   4045  1.1.1.2  mrg     model.purge_state_involving (sval_a, NULL);
   4046  1.1.1.2  mrg     model.canonicalize ();
   4047  1.1.1.2  mrg     /* We should just have the constraint/ECs involving b != 0.  */
   4048  1.1.1.2  mrg     ASSERT_EQ (model.get_constraints ()->m_equiv_classes.length (), 2);
   4049  1.1.1.2  mrg     ASSERT_EQ (model.get_constraints ()->m_constraints.length (), 1);
   4050  1.1.1.2  mrg     ASSERT_CONDITION_TRUE (model, b, NE_EXPR, int_0);
   4051  1.1.1.2  mrg   }
   4052  1.1.1.2  mrg 
   4053  1.1.1.2  mrg   /*  "a == 0" && "b == 0".  */
   4054  1.1.1.2  mrg   {
   4055  1.1.1.2  mrg     region_model_manager mgr;
   4056  1.1.1.2  mrg     region_model model (&mgr);
   4057  1.1.1.2  mrg     ADD_SAT_CONSTRAINT (model, a, EQ_EXPR, int_0);
   4058  1.1.1.2  mrg     ADD_SAT_CONSTRAINT (model, b, EQ_EXPR, int_0);
   4059  1.1.1.2  mrg     ASSERT_EQ (model.get_constraints ()->m_equiv_classes.length (), 1);
   4060  1.1.1.2  mrg     ASSERT_EQ (model.get_constraints ()->m_constraints.length (), 0);
   4061  1.1.1.2  mrg 
   4062  1.1.1.2  mrg     /* Purge state for "a".  */
   4063  1.1.1.2  mrg     const svalue *sval_a = model.get_rvalue (a, NULL);
   4064  1.1.1.2  mrg     model.purge_state_involving (sval_a, NULL);
   4065  1.1.1.2  mrg     model.canonicalize ();
   4066  1.1.1.2  mrg     /* We should just have the EC involving b == 0.  */
   4067  1.1.1.2  mrg     ASSERT_EQ (model.get_constraints ()->m_equiv_classes.length (), 1);
   4068  1.1.1.2  mrg     ASSERT_EQ (model.get_constraints ()->m_constraints.length (), 0);
   4069  1.1.1.2  mrg     ASSERT_CONDITION_TRUE (model, b, EQ_EXPR, int_0);
   4070  1.1.1.2  mrg   }
   4071  1.1.1.2  mrg }
   4072  1.1.1.2  mrg 
   4073  1.1.1.2  mrg /* Implementation detail of ASSERT_DUMP_BOUNDED_RANGES_EQ.  */
   4074  1.1.1.2  mrg 
   4075  1.1.1.2  mrg static void
   4076  1.1.1.2  mrg assert_dump_bounded_range_eq (const location &loc,
   4077  1.1.1.2  mrg 			      const bounded_range &range,
   4078  1.1.1.2  mrg 			      const char *expected)
   4079  1.1.1.2  mrg {
   4080  1.1.1.2  mrg   auto_fix_quotes sentinel;
   4081  1.1.1.2  mrg   pretty_printer pp;
   4082  1.1.1.2  mrg   pp_format_decoder (&pp) = default_tree_printer;
   4083  1.1.1.2  mrg   range.dump_to_pp (&pp, false);
   4084  1.1.1.2  mrg   ASSERT_STREQ_AT (loc, pp_formatted_text (&pp), expected);
   4085  1.1.1.2  mrg }
   4086  1.1.1.2  mrg 
   4087  1.1.1.2  mrg /* Assert that BR.dump (false) is EXPECTED.  */
   4088  1.1.1.2  mrg 
   4089  1.1.1.2  mrg #define ASSERT_DUMP_BOUNDED_RANGE_EQ(BR, EXPECTED) \
   4090  1.1.1.2  mrg   SELFTEST_BEGIN_STMT							\
   4091  1.1.1.2  mrg   assert_dump_bounded_range_eq ((SELFTEST_LOCATION), (BR), (EXPECTED)); \
   4092  1.1.1.2  mrg   SELFTEST_END_STMT
   4093  1.1.1.2  mrg 
   4094  1.1.1.2  mrg /* Verify that bounded_range works as expected.  */
   4095  1.1.1.2  mrg 
   4096  1.1.1.2  mrg static void
   4097  1.1.1.2  mrg test_bounded_range ()
   4098  1.1.1.2  mrg {
   4099  1.1.1.2  mrg   tree u8_0 = build_int_cst (unsigned_char_type_node, 0);
   4100  1.1.1.2  mrg   tree u8_1 = build_int_cst (unsigned_char_type_node, 1);
   4101  1.1.1.2  mrg   tree u8_64 = build_int_cst (unsigned_char_type_node, 64);
   4102  1.1.1.2  mrg   tree u8_128 = build_int_cst (unsigned_char_type_node, 128);
   4103  1.1.1.2  mrg   tree u8_255 = build_int_cst (unsigned_char_type_node, 255);
   4104  1.1.1.2  mrg 
   4105  1.1.1.2  mrg   tree s8_0 = build_int_cst (signed_char_type_node, 0);
   4106  1.1.1.2  mrg   tree s8_1 = build_int_cst (signed_char_type_node, 1);
   4107  1.1.1.2  mrg   tree s8_2 = build_int_cst (signed_char_type_node, 2);
   4108  1.1.1.2  mrg 
   4109  1.1.1.2  mrg   bounded_range br_u8_0 (u8_0, u8_0);
   4110  1.1.1.2  mrg   ASSERT_DUMP_BOUNDED_RANGE_EQ (br_u8_0, "0");
   4111  1.1.1.2  mrg   ASSERT_TRUE (br_u8_0.contains_p (u8_0));
   4112  1.1.1.2  mrg   ASSERT_FALSE (br_u8_0.contains_p (u8_1));
   4113  1.1.1.2  mrg   ASSERT_TRUE (br_u8_0.contains_p (s8_0));
   4114  1.1.1.2  mrg   ASSERT_FALSE (br_u8_0.contains_p (s8_1));
   4115  1.1.1.2  mrg 
   4116  1.1.1.2  mrg   bounded_range br_u8_0_1 (u8_0, u8_1);
   4117  1.1.1.2  mrg   ASSERT_DUMP_BOUNDED_RANGE_EQ (br_u8_0_1, "[0, 1]");
   4118  1.1.1.2  mrg 
   4119  1.1.1.2  mrg   bounded_range tmp (NULL_TREE, NULL_TREE);
   4120  1.1.1.2  mrg   ASSERT_TRUE (br_u8_0.intersects_p (br_u8_0_1, &tmp));
   4121  1.1.1.2  mrg   ASSERT_DUMP_BOUNDED_RANGE_EQ (tmp, "0");
   4122  1.1.1.2  mrg 
   4123  1.1.1.2  mrg   bounded_range br_u8_64_128 (u8_64, u8_128);
   4124  1.1.1.2  mrg   ASSERT_DUMP_BOUNDED_RANGE_EQ (br_u8_64_128, "[64, 128]");
   4125  1.1.1.2  mrg 
   4126  1.1.1.2  mrg   ASSERT_FALSE (br_u8_0.intersects_p (br_u8_64_128, NULL));
   4127  1.1.1.2  mrg   ASSERT_FALSE (br_u8_64_128.intersects_p (br_u8_0, NULL));
   4128  1.1.1.2  mrg 
   4129  1.1.1.2  mrg   bounded_range br_u8_128_255 (u8_128, u8_255);
   4130  1.1.1.2  mrg   ASSERT_DUMP_BOUNDED_RANGE_EQ (br_u8_128_255, "[128, 255]");
   4131  1.1.1.2  mrg   ASSERT_TRUE (br_u8_128_255.intersects_p (br_u8_64_128, &tmp));
   4132  1.1.1.2  mrg   ASSERT_DUMP_BOUNDED_RANGE_EQ (tmp, "128");
   4133  1.1.1.2  mrg 
   4134  1.1.1.2  mrg   bounded_range br_s8_2 (s8_2, s8_2);
   4135  1.1.1.2  mrg   ASSERT_DUMP_BOUNDED_RANGE_EQ (br_s8_2, "2");
   4136  1.1.1.2  mrg   bounded_range br_s8_2_u8_255 (s8_2, u8_255);
   4137  1.1.1.2  mrg   ASSERT_DUMP_BOUNDED_RANGE_EQ (br_s8_2_u8_255, "[2, 255]");
   4138  1.1.1.2  mrg }
   4139  1.1.1.2  mrg 
   4140  1.1.1.2  mrg /* Implementation detail of ASSERT_DUMP_BOUNDED_RANGES_EQ.  */
   4141  1.1.1.2  mrg 
   4142  1.1.1.2  mrg static void
   4143  1.1.1.2  mrg assert_dump_bounded_ranges_eq (const location &loc,
   4144  1.1.1.2  mrg 			       const bounded_ranges *ranges,
   4145  1.1.1.2  mrg 			       const char *expected)
   4146  1.1.1.2  mrg {
   4147  1.1.1.2  mrg   auto_fix_quotes sentinel;
   4148  1.1.1.2  mrg   pretty_printer pp;
   4149  1.1.1.2  mrg   pp_format_decoder (&pp) = default_tree_printer;
   4150  1.1.1.2  mrg   ranges->dump_to_pp (&pp, false);
   4151  1.1.1.2  mrg   ASSERT_STREQ_AT (loc, pp_formatted_text (&pp), expected);
   4152  1.1.1.2  mrg }
   4153  1.1.1.2  mrg 
   4154  1.1.1.2  mrg /* Implementation detail of ASSERT_DUMP_BOUNDED_RANGES_EQ.  */
   4155  1.1.1.2  mrg 
   4156  1.1.1.2  mrg static void
   4157  1.1.1.2  mrg assert_dump_bounded_ranges_eq (const location &loc,
   4158  1.1.1.2  mrg 			       const bounded_ranges &ranges,
   4159  1.1.1.2  mrg 			       const char *expected)
   4160  1.1.1.2  mrg {
   4161  1.1.1.2  mrg   auto_fix_quotes sentinel;
   4162  1.1.1.2  mrg   pretty_printer pp;
   4163  1.1.1.2  mrg   pp_format_decoder (&pp) = default_tree_printer;
   4164  1.1.1.2  mrg   ranges.dump_to_pp (&pp, false);
   4165  1.1.1.2  mrg   ASSERT_STREQ_AT (loc, pp_formatted_text (&pp), expected);
   4166  1.1.1.2  mrg }
   4167  1.1.1.2  mrg 
   4168  1.1.1.2  mrg /* Assert that BRS.dump (false) is EXPECTED.  */
   4169  1.1.1.2  mrg 
   4170  1.1.1.2  mrg #define ASSERT_DUMP_BOUNDED_RANGES_EQ(BRS, EXPECTED) \
   4171  1.1.1.2  mrg   SELFTEST_BEGIN_STMT							\
   4172  1.1.1.2  mrg   assert_dump_bounded_ranges_eq ((SELFTEST_LOCATION), (BRS), (EXPECTED)); \
   4173  1.1.1.2  mrg   SELFTEST_END_STMT
   4174  1.1.1.2  mrg 
   4175  1.1.1.2  mrg /* Verify that the bounded_ranges class works as expected.  */
   4176  1.1.1.2  mrg 
   4177  1.1.1.2  mrg static void
   4178  1.1.1.2  mrg test_bounded_ranges ()
   4179  1.1.1.2  mrg {
   4180  1.1.1.2  mrg   bounded_ranges_manager mgr;
   4181  1.1.1.2  mrg 
   4182  1.1.1.2  mrg   tree ch0 = build_int_cst (unsigned_char_type_node, 0);
   4183  1.1.1.2  mrg   tree ch1 = build_int_cst (unsigned_char_type_node, 1);
   4184  1.1.1.2  mrg   tree ch2 = build_int_cst (unsigned_char_type_node, 2);
   4185  1.1.1.2  mrg   tree ch3 = build_int_cst (unsigned_char_type_node, 3);
   4186  1.1.1.2  mrg   tree ch128 = build_int_cst (unsigned_char_type_node, 128);
   4187  1.1.1.2  mrg   tree ch129 = build_int_cst (unsigned_char_type_node, 129);
   4188  1.1.1.2  mrg   tree ch254 = build_int_cst (unsigned_char_type_node, 254);
   4189  1.1.1.2  mrg   tree ch255 = build_int_cst (unsigned_char_type_node, 255);
   4190  1.1.1.2  mrg 
   4191  1.1.1.2  mrg   const bounded_ranges *empty = mgr.get_or_create_empty ();
   4192  1.1.1.2  mrg   ASSERT_DUMP_BOUNDED_RANGES_EQ (empty, "{}");
   4193  1.1.1.2  mrg 
   4194  1.1.1.2  mrg   const bounded_ranges *point0 = mgr.get_or_create_point (ch0);
   4195  1.1.1.2  mrg   ASSERT_DUMP_BOUNDED_RANGES_EQ (point0, "{0}");
   4196  1.1.1.2  mrg 
   4197  1.1.1.2  mrg   const bounded_ranges *point1 = mgr.get_or_create_point (ch1);
   4198  1.1.1.2  mrg   ASSERT_DUMP_BOUNDED_RANGES_EQ (point1, "{1}");
   4199  1.1.1.2  mrg 
   4200  1.1.1.2  mrg   const bounded_ranges *point2 = mgr.get_or_create_point (ch2);
   4201  1.1.1.2  mrg   ASSERT_DUMP_BOUNDED_RANGES_EQ (point2, "{2}");
   4202  1.1.1.2  mrg 
   4203  1.1.1.2  mrg   const bounded_ranges *range0_128 = mgr.get_or_create_range (ch0, ch128);
   4204  1.1.1.2  mrg   ASSERT_DUMP_BOUNDED_RANGES_EQ (range0_128, "{[0, 128]}");
   4205  1.1.1.2  mrg 
   4206  1.1.1.2  mrg   const bounded_ranges *range0_255 = mgr.get_or_create_range (ch0, ch255);
   4207  1.1.1.2  mrg   ASSERT_DUMP_BOUNDED_RANGES_EQ (range0_255, "{[0, 255]}");
   4208  1.1.1.2  mrg 
   4209  1.1.1.2  mrg   ASSERT_FALSE (empty->contain_p (ch0));
   4210  1.1.1.2  mrg   ASSERT_FALSE (empty->contain_p (ch1));
   4211  1.1.1.2  mrg   ASSERT_FALSE (empty->contain_p (ch255));
   4212  1.1.1.2  mrg 
   4213  1.1.1.2  mrg   ASSERT_TRUE (point0->contain_p (ch0));
   4214  1.1.1.2  mrg   ASSERT_FALSE (point0->contain_p (ch1));
   4215  1.1.1.2  mrg   ASSERT_FALSE (point0->contain_p (ch255));
   4216  1.1.1.2  mrg 
   4217  1.1.1.2  mrg   ASSERT_FALSE (point1->contain_p (ch0));
   4218  1.1.1.2  mrg   ASSERT_TRUE (point1->contain_p (ch1));
   4219  1.1.1.2  mrg   ASSERT_FALSE (point0->contain_p (ch255));
   4220  1.1.1.2  mrg 
   4221  1.1.1.2  mrg   ASSERT_TRUE (range0_128->contain_p (ch0));
   4222  1.1.1.2  mrg   ASSERT_TRUE (range0_128->contain_p (ch1));
   4223  1.1.1.2  mrg   ASSERT_TRUE (range0_128->contain_p (ch128));
   4224  1.1.1.2  mrg   ASSERT_FALSE (range0_128->contain_p (ch129));
   4225  1.1.1.2  mrg   ASSERT_FALSE (range0_128->contain_p (ch254));
   4226  1.1.1.2  mrg   ASSERT_FALSE (range0_128->contain_p (ch255));
   4227  1.1.1.2  mrg 
   4228  1.1.1.2  mrg   const bounded_ranges *inv0_128
   4229  1.1.1.2  mrg     = mgr.get_or_create_inverse (range0_128, unsigned_char_type_node);
   4230  1.1.1.2  mrg   ASSERT_DUMP_BOUNDED_RANGES_EQ (inv0_128, "{[129, 255]}");
   4231  1.1.1.2  mrg 
   4232  1.1.1.2  mrg   const bounded_ranges *range128_129 = mgr.get_or_create_range (ch128, ch129);
   4233  1.1.1.2  mrg   ASSERT_DUMP_BOUNDED_RANGES_EQ (range128_129, "{[128, 129]}");
   4234  1.1.1.2  mrg 
   4235  1.1.1.2  mrg   const bounded_ranges *inv128_129
   4236  1.1.1.2  mrg     = mgr.get_or_create_inverse (range128_129, unsigned_char_type_node);
   4237  1.1.1.2  mrg   ASSERT_DUMP_BOUNDED_RANGES_EQ (inv128_129, "{[0, 127], [130, 255]}");
   4238  1.1.1.2  mrg 
   4239  1.1.1.2  mrg   /* Intersection.  */
   4240  1.1.1.2  mrg   {
   4241  1.1.1.2  mrg     /* Intersection of disjoint ranges should be empty set.  */
   4242  1.1.1.2  mrg     const bounded_ranges *intersect0_1
   4243  1.1.1.2  mrg       = mgr.get_or_create_intersection (point0, point1);
   4244  1.1.1.2  mrg     ASSERT_DUMP_BOUNDED_RANGES_EQ (intersect0_1, "{}");
   4245  1.1.1.2  mrg   }
   4246  1.1.1.2  mrg 
   4247  1.1.1.2  mrg   /* Various tests of "union of ranges".  */
   4248  1.1.1.2  mrg   {
   4249  1.1.1.2  mrg     {
   4250  1.1.1.2  mrg       /* Touching points should be merged into a range.  */
   4251  1.1.1.2  mrg       auto_vec <const bounded_ranges *> v;
   4252  1.1.1.2  mrg       v.safe_push (point0);
   4253  1.1.1.2  mrg       v.safe_push (point1);
   4254  1.1.1.2  mrg       const bounded_ranges *union_0_and_1 = mgr.get_or_create_union (v);
   4255  1.1.1.2  mrg       ASSERT_DUMP_BOUNDED_RANGES_EQ (union_0_and_1, "{[0, 1]}");
   4256  1.1.1.2  mrg     }
   4257  1.1.1.2  mrg 
   4258  1.1.1.2  mrg     {
   4259  1.1.1.2  mrg       /* Overlapping and out-of-order.  */
   4260  1.1.1.2  mrg       auto_vec <const bounded_ranges *> v;
   4261  1.1.1.2  mrg       v.safe_push (inv0_128); // {[129, 255]}
   4262  1.1.1.2  mrg       v.safe_push (range128_129);
   4263  1.1.1.2  mrg       const bounded_ranges *union_129_255_and_128_129
   4264  1.1.1.2  mrg 	= mgr.get_or_create_union (v);
   4265  1.1.1.2  mrg       ASSERT_DUMP_BOUNDED_RANGES_EQ (union_129_255_and_128_129, "{[128, 255]}");
   4266  1.1.1.2  mrg     }
   4267  1.1.1.2  mrg 
   4268  1.1.1.2  mrg     {
   4269  1.1.1.2  mrg       /* Union of R and inverse(R) should be full range of type.  */
   4270  1.1.1.2  mrg       auto_vec <const bounded_ranges *> v;
   4271  1.1.1.2  mrg       v.safe_push (range128_129);
   4272  1.1.1.2  mrg       v.safe_push (inv128_129);
   4273  1.1.1.2  mrg       const bounded_ranges *union_ = mgr.get_or_create_union (v);
   4274  1.1.1.2  mrg       ASSERT_DUMP_BOUNDED_RANGES_EQ (union_, "{[0, 255]}");
   4275  1.1.1.2  mrg     }
   4276  1.1.1.2  mrg 
   4277  1.1.1.2  mrg     /* Union with an endpoint.  */
   4278  1.1.1.2  mrg     {
   4279  1.1.1.2  mrg       const bounded_ranges *range2_to_255
   4280  1.1.1.2  mrg 	= mgr.get_or_create_range (ch2, ch255);
   4281  1.1.1.2  mrg       ASSERT_DUMP_BOUNDED_RANGES_EQ (range2_to_255, "{[2, 255]}");
   4282  1.1.1.2  mrg       auto_vec <const bounded_ranges *> v;
   4283  1.1.1.2  mrg       v.safe_push (point0);
   4284  1.1.1.2  mrg       v.safe_push (point2);
   4285  1.1.1.2  mrg       v.safe_push (range2_to_255);
   4286  1.1.1.2  mrg       const bounded_ranges *union_ = mgr.get_or_create_union (v);
   4287  1.1.1.2  mrg       ASSERT_DUMP_BOUNDED_RANGES_EQ (union_, "{0, [2, 255]}");
   4288  1.1.1.2  mrg     }
   4289  1.1.1.2  mrg 
   4290  1.1.1.2  mrg     /* Construct from vector of bounded_range.  */
   4291  1.1.1.2  mrg     {
   4292  1.1.1.2  mrg       auto_vec<bounded_range> v;
   4293  1.1.1.2  mrg       v.safe_push (bounded_range (ch2, ch2));
   4294  1.1.1.2  mrg       v.safe_push (bounded_range (ch0, ch0));
   4295  1.1.1.2  mrg       v.safe_push (bounded_range (ch2, ch255));
   4296  1.1.1.2  mrg       bounded_ranges br (v);
   4297  1.1.1.2  mrg       ASSERT_DUMP_BOUNDED_RANGES_EQ (&br, "{0, [2, 255]}");
   4298  1.1.1.2  mrg     }
   4299  1.1.1.2  mrg   }
   4300  1.1.1.2  mrg 
   4301  1.1.1.2  mrg   /* Various tests of "inverse".  */
   4302  1.1.1.2  mrg   {
   4303  1.1.1.2  mrg     {
   4304  1.1.1.2  mrg       const bounded_ranges *range_1_to_3 = mgr.get_or_create_range (ch1, ch3);
   4305  1.1.1.2  mrg       ASSERT_DUMP_BOUNDED_RANGES_EQ (range_1_to_3, "{[1, 3]}");
   4306  1.1.1.2  mrg       const bounded_ranges *inv
   4307  1.1.1.2  mrg 	= mgr.get_or_create_inverse (range_1_to_3, unsigned_char_type_node);
   4308  1.1.1.2  mrg       ASSERT_DUMP_BOUNDED_RANGES_EQ (inv, "{0, [4, 255]}");
   4309  1.1.1.2  mrg     }
   4310  1.1.1.2  mrg     {
   4311  1.1.1.2  mrg       const bounded_ranges *range_1_to_255
   4312  1.1.1.2  mrg 	= mgr.get_or_create_range (ch1, ch255);
   4313  1.1.1.2  mrg       ASSERT_DUMP_BOUNDED_RANGES_EQ (range_1_to_255, "{[1, 255]}");
   4314  1.1.1.2  mrg       const bounded_ranges *inv
   4315  1.1.1.2  mrg 	= mgr.get_or_create_inverse (range_1_to_255, unsigned_char_type_node);
   4316  1.1.1.2  mrg       ASSERT_DUMP_BOUNDED_RANGES_EQ (inv, "{0}");
   4317  1.1.1.2  mrg     }
   4318  1.1.1.2  mrg     {
   4319  1.1.1.2  mrg       const bounded_ranges *range_0_to_254
   4320  1.1.1.2  mrg 	= mgr.get_or_create_range (ch0, ch254);
   4321  1.1.1.2  mrg       ASSERT_DUMP_BOUNDED_RANGES_EQ (range_0_to_254, "{[0, 254]}");
   4322  1.1.1.2  mrg       const bounded_ranges *inv
   4323  1.1.1.2  mrg 	= mgr.get_or_create_inverse (range_0_to_254, unsigned_char_type_node);
   4324  1.1.1.2  mrg       ASSERT_DUMP_BOUNDED_RANGES_EQ (inv, "{255}");
   4325  1.1.1.2  mrg     }
   4326  1.1.1.2  mrg   }
   4327  1.1.1.2  mrg 
   4328  1.1.1.2  mrg   /* "case 'a'-'z': case 'A-Z':" vs "default:", for ASCII.  */
   4329  1.1.1.2  mrg   {
   4330  1.1.1.2  mrg     tree ch65 = build_int_cst (unsigned_char_type_node, 65);
   4331  1.1.1.2  mrg     tree ch90 = build_int_cst (unsigned_char_type_node, 90);
   4332  1.1.1.2  mrg 
   4333  1.1.1.2  mrg     tree ch97 = build_int_cst (unsigned_char_type_node, 97);
   4334  1.1.1.2  mrg     tree ch122 = build_int_cst (unsigned_char_type_node, 122);
   4335  1.1.1.2  mrg 
   4336  1.1.1.2  mrg     const bounded_ranges *A_to_Z = mgr.get_or_create_range (ch65, ch90);
   4337  1.1.1.2  mrg     ASSERT_DUMP_BOUNDED_RANGES_EQ (A_to_Z, "{[65, 90]}");
   4338  1.1.1.2  mrg     const bounded_ranges *a_to_z = mgr.get_or_create_range (ch97, ch122);
   4339  1.1.1.2  mrg     ASSERT_DUMP_BOUNDED_RANGES_EQ (a_to_z, "{[97, 122]}");
   4340  1.1.1.2  mrg     auto_vec <const bounded_ranges *> v;
   4341  1.1.1.2  mrg     v.safe_push (A_to_Z);
   4342  1.1.1.2  mrg     v.safe_push (a_to_z);
   4343  1.1.1.2  mrg     const bounded_ranges *label_ranges = mgr.get_or_create_union (v);
   4344  1.1.1.2  mrg     ASSERT_DUMP_BOUNDED_RANGES_EQ (label_ranges, "{[65, 90], [97, 122]}");
   4345  1.1.1.2  mrg     const bounded_ranges *default_ranges
   4346  1.1.1.2  mrg       = mgr.get_or_create_inverse (label_ranges, unsigned_char_type_node);
   4347  1.1.1.2  mrg     ASSERT_DUMP_BOUNDED_RANGES_EQ (default_ranges,
   4348  1.1.1.2  mrg 				   "{[0, 64], [91, 96], [123, 255]}");
   4349  1.1.1.2  mrg   }
   4350  1.1.1.2  mrg 
   4351  1.1.1.2  mrg   /* Verify ranges from ops.  */
   4352  1.1.1.2  mrg   ASSERT_DUMP_BOUNDED_RANGES_EQ (bounded_ranges (EQ_EXPR, ch128),
   4353  1.1.1.2  mrg 				 "{128}");
   4354  1.1.1.2  mrg   ASSERT_DUMP_BOUNDED_RANGES_EQ (bounded_ranges (NE_EXPR, ch128),
   4355  1.1.1.2  mrg 				 "{[0, 127], [129, 255]}");
   4356  1.1.1.2  mrg   ASSERT_DUMP_BOUNDED_RANGES_EQ (bounded_ranges (LT_EXPR, ch128),
   4357  1.1.1.2  mrg 				 "{[0, 127]}");
   4358  1.1.1.2  mrg   ASSERT_DUMP_BOUNDED_RANGES_EQ (bounded_ranges (LE_EXPR, ch128),
   4359  1.1.1.2  mrg 				 "{[0, 128]}");
   4360  1.1.1.2  mrg   ASSERT_DUMP_BOUNDED_RANGES_EQ (bounded_ranges (GE_EXPR, ch128),
   4361  1.1.1.2  mrg 				 "{[128, 255]}");
   4362  1.1.1.2  mrg   ASSERT_DUMP_BOUNDED_RANGES_EQ (bounded_ranges (GT_EXPR, ch128),
   4363  1.1.1.2  mrg 				 "{[129, 255]}");
   4364  1.1.1.2  mrg   /* Ops at endpoints of type ranges.  */
   4365  1.1.1.2  mrg   ASSERT_DUMP_BOUNDED_RANGES_EQ (bounded_ranges (LE_EXPR, ch0),
   4366  1.1.1.2  mrg 				 "{0}");
   4367  1.1.1.2  mrg   ASSERT_DUMP_BOUNDED_RANGES_EQ (bounded_ranges (LT_EXPR, ch0),
   4368  1.1.1.2  mrg 				 "{}");
   4369  1.1.1.2  mrg   ASSERT_DUMP_BOUNDED_RANGES_EQ (bounded_ranges (NE_EXPR, ch0),
   4370  1.1.1.2  mrg 				 "{[1, 255]}");
   4371  1.1.1.2  mrg   ASSERT_DUMP_BOUNDED_RANGES_EQ (bounded_ranges (GE_EXPR, ch255),
   4372  1.1.1.2  mrg 				 "{255}");
   4373  1.1.1.2  mrg   ASSERT_DUMP_BOUNDED_RANGES_EQ (bounded_ranges (GT_EXPR, ch255),
   4374  1.1.1.2  mrg 				 "{}");
   4375  1.1.1.2  mrg   ASSERT_DUMP_BOUNDED_RANGES_EQ (bounded_ranges (NE_EXPR, ch255),
   4376  1.1.1.2  mrg 				 "{[0, 254]}");
   4377  1.1.1.2  mrg 
   4378  1.1.1.2  mrg   /* Verify that instances are consolidated by mgr.  */
   4379  1.1.1.2  mrg   ASSERT_EQ (mgr.get_or_create_point (ch0),
   4380  1.1.1.2  mrg 	     mgr.get_or_create_point (ch0));
   4381  1.1.1.2  mrg   ASSERT_NE (mgr.get_or_create_point (ch0),
   4382  1.1.1.2  mrg 	     mgr.get_or_create_point (ch1));
   4383  1.1.1.2  mrg }
   4384  1.1.1.2  mrg 
   4385      1.1  mrg /* Run the selftests in this file, temporarily overriding
   4386      1.1  mrg    flag_analyzer_transitivity with TRANSITIVITY.  */
   4387      1.1  mrg 
   4388      1.1  mrg static void
   4389      1.1  mrg run_constraint_manager_tests (bool transitivity)
   4390      1.1  mrg {
   4391      1.1  mrg   int saved_flag_analyzer_transitivity = flag_analyzer_transitivity;
   4392      1.1  mrg   flag_analyzer_transitivity = transitivity;
   4393      1.1  mrg 
   4394  1.1.1.2  mrg   test_range ();
   4395      1.1  mrg   test_constraint_conditions ();
   4396      1.1  mrg   if (flag_analyzer_transitivity)
   4397      1.1  mrg     {
   4398      1.1  mrg       /* These selftests assume transitivity.  */
   4399      1.1  mrg       test_transitivity ();
   4400      1.1  mrg     }
   4401  1.1.1.2  mrg   test_constant_comparisons ();
   4402      1.1  mrg   test_constraint_impl ();
   4403      1.1  mrg   test_equality ();
   4404      1.1  mrg   test_many_constants ();
   4405  1.1.1.2  mrg   test_purging ();
   4406  1.1.1.2  mrg   test_bounded_range ();
   4407  1.1.1.2  mrg   test_bounded_ranges ();
   4408      1.1  mrg 
   4409      1.1  mrg   flag_analyzer_transitivity = saved_flag_analyzer_transitivity;
   4410      1.1  mrg }
   4411      1.1  mrg 
   4412      1.1  mrg /* Run all of the selftests within this file.  */
   4413      1.1  mrg 
   4414      1.1  mrg void
   4415      1.1  mrg analyzer_constraint_manager_cc_tests ()
   4416      1.1  mrg {
   4417      1.1  mrg   /* Run the tests twice: with and without transitivity.  */
   4418      1.1  mrg   run_constraint_manager_tests (true);
   4419      1.1  mrg   run_constraint_manager_tests (false);
   4420      1.1  mrg }
   4421      1.1  mrg 
   4422      1.1  mrg } // namespace selftest
   4423      1.1  mrg 
   4424      1.1  mrg #endif /* CHECKING_P */
   4425      1.1  mrg 
   4426      1.1  mrg } // namespace ana
   4427      1.1  mrg 
   4428      1.1  mrg #endif /* #if ENABLE_ANALYZER */
   4429