Polaris: RangeComparator.h Source File

RangeComparator.h

Go to the documentation of this file.
00001 ///
00002 ///
00003 /// file ConstraintDict.h
00004 ///
00005 #ifndef _RANGE_COMPARATOR_H
00006 #define _RANGE_COMPARATOR_H
00007 ///
00008 /// \class RangeComparator 
00009 /// \brief Base class implementing comparison methods.
00010 /// \defgroup Polaris
00011 /// \ingroup Polaris
00012 ///  Range
00013 /// \see RangeComparator.h
00014 /// \see RangeComparator.h
00015 /// \see RangeComparator.cc
00016 ///
00017 /// \endcode
00018 /// \section Overview Overview
00019 /// A RangeComparator object implements most of the basic comparison
00020 /// and modification operators that are useful for using ranges.
00021 ///
00022 /// \endcode
00023 /// \section Description Description
00024 /// RangeComparator is an abstract class that offers a variety of
00025 /// methods for comparing expressions and for high level modifications
00026 /// of ranges.  The two most important methods in this class is
00027 /// compare() and sign(), which compare expressions.  The compare()
00028 /// method returns the inequality relationships that hold between the
00029 /// two given expressions, using the constraints imposed by the ranges
00030 /// "contained" within myself.  The sign() method determines whether
00031 /// an expression is always positive or negative, again using these
00032 /// ranges.
00033 ///
00034 /// This class also offers some methods to modify expressions, using my
00035 /// ranges.  All these methods eliminate undesirable variables or
00036 /// subexpressions by replacing them with ranges.  Method
00037 /// subst_var_and_simplify() replaces a variable in the expression with
00038 /// its range and simplifies it down.  Method eliminate_vars() is
00039 /// similar, except it replaces several variables.  Method
00040 /// remove_truncates_with_var() is used to remove expressions of
00041 /// the form B*(A/B).  
00042 ///
00043 /// Several functions are provided to access or modify ranges contained
00044 /// within myself.  Method get_range_ref() gets the range for a
00045 /// given variable, method set_range() modifies the variable's range,
00046 /// and method del_range() deletes it.  Methods union_range() and
00047 /// intersect_range() modify a given variable's range by unioning or
00048 /// intersecting it with the given range.
00049 ///
00050 /// By default, a NULL or omega expression are considered to be the
00051 /// unconstrained range ([-infinity:+infinity]).  Because of this,
00052 /// methods that may return range expressions may also return NULL or
00053 /// Omega.
00054 ///
00055 /// A variety of functions that manipulate range expressions can be
00056 /// found in range_util.h.
00057 ///
00058 /// The RangeComparator class is abstract because the class does not
00059 /// specify how the ranges it uses are stored within it.  A subclass
00060 /// of RangeComparator must declare such data structures as well
00061 /// as instantiate the pure methods set_range(), get_range_ref(),
00062 /// and del_range() to access these data structures.  The subclass
00063 /// must also instantiate the method listable_clone().
00064 ///
00065 /// The compare() method compares two expressions by taking the
00066 /// difference between the two expressions, then repeated substituting
00067 /// each variable in the difference with the variable's range until
00068 /// the lower bound of the difference is a positive integer or
00069 /// the upper bound is a negative integer.  At this point, the
00070 /// inequality relationships between the two expressions can be
00071 /// determined by examining these integer bounds.  A more complete
00072 /// description of the expression comparison algorithm can be found
00073 /// in Blume and Eigenmann "Symbolic Range Propagation".
00074 ///
00075 /// \endcode
00076 /// \section Known Known bugs or limitations
00077 /// Because this class creates expressions containing intrinsics
00078 /// (e.g., MIN, MAX, MOD), this class needs access to the symbol table
00079 /// to create symbols for these intrinsics.  Because of this, the
00080 /// user must pass the symbol table to the constructors of this class.
00081 ///
00082 #include "../Listable.h"
00083 #include "../Collection/Map.h"
00084 #include "../Collection/RefSet.h"
00085 #include "../Symbol/Symbol.h"
00086 #include "../Expression/Expression.h"
00087 #include "../IntElem.h"
00088 ///
00089 class Symtab;
00090 class RangeExpr;
00091 
00092 #include "Relation.h"
00093 #include "ExprSet.h"
00094 
00095 enum EXPR_SIGN {
00096     POS_EXPR,       ///< Expr. spans over only positive values
00097     NEG_EXPR,       ///< Expr. spans over only negative values
00098     POS_NEG_EXPR,   ///< Expr. spans over positive or negative values
00099     ZERO_EXPR,      ///< Expr. is zero
00100     UNKNOWN_SIGN,   ///< Sign is unknown (Used internally)
00101     PENDING     ///< Sign is being calculated (Used internally)
00102 };
00103 
00104 ///< Internal class used to collect information used by the compare
00105 ///< method.  Each variable has its own CompareData object.
00106 
00107 class CompareData : public Listable {
00108 public:
00109     int num_subst;      ///< Number of substitutions performed by
00110                 ///< unfinished compares for this varianble.
00111     EXPR_SIGN sign_cache;   ///< Cached sign of the variable.
00112 
00113     CompareData();
00114     CompareData(const CompareData &other);
00115     virtual ~CompareData();
00116 
00117     virtual Listable *listable_clone() const;
00118     virtual int     structures_OK() const;
00119     virtual void    print(ostream &o) const;
00120 };
00121 
00122 class RangeComparator : public Listable {
00123 public:
00124     RangeComparator(const Symtab &symtab);
00125     RangeComparator(const RangeComparator &other);
00126     virtual ~RangeComparator();
00127 
00128     
00129     ///< Methods for comparing expressions.
00130 
00131     virtual Relation compare(const Expression &e1, const Expression &e2);
00132     ///< Return the algebraic relationship between the two expressions,
00133     ///< taking my ranges into account.
00134 
00135     virtual Relation compare(const Expression &e1, int value);
00136     ///< Return the algebraic relationship between the given expression
00137     ///< and the integer value, taking Ranges into account.
00138 
00139     EXPR_SIGN sign(const Expression &e);
00140     ///< Return the sign of the expression.  One of three values may be
00141     ///< returned: POS_EXPR, NEG_EXPR, and POS_NEG_EXPR, which means that
00142     ///< the sign is positive, negative, or unknown respectively.
00143 
00144     EXPR_SIGN signz(const Expression &e);
00145     ///< Like sign() but may also return ZERO_EXPR when the expression
00146     ///< equals zero.
00147 
00148     void subst_in_ranges(const Symbol &var,
00149              const Expression *subst_expr);
00150     ///< Replace all uses of variable var in all of the ranges in myself
00151     ///< with the given substitution expression.  If subst_expr is NULL,
00152     ///< the variable references are instead replaced by an unconstrained
00153     ///< range. ([-Inf:Inf])
00154 
00155     
00156     ///< Methods for modifying or accessing ranges inside myself.
00157 
00158     virtual void set_range(const Symbol &var, Expression *range) = 0;
00159     ///< Set the given variable to the given range.
00160   
00161     virtual void del_range(const Symbol &var) = 0;
00162     ///< Delete the range associated with the given variable.
00163 
00164     virtual const Expression *get_range_ref(const Symbol &var) = 0;
00165     ///< Return the range associated with the given variable.  If the
00166     ///< variable doesn't have an associated range, return 0;
00167 
00168     void intersect_range(const Symbol &var, const Expression &inter_expr);
00169     ///< Intersect my range of the given variable with the given range.
00170 
00171     void union_range(const Symbol &var, const Expression &union_expr,
00172                      RangeComparator *union_comparator_ref = 0);
00173     ///< Union my range of the given variable with the given range.
00174 
00175     
00176     ///< Methods for modifying given expressions, using my ranges.
00177 
00178     Expression *subst_var_and_simplify(Expression *e, const Symbol &var,
00179                                        const Expression *subst_expr);
00180     ///< Substitute all occurrences of the given variable in the given
00181     ///< expression with the given substitution expression.  Then, simplify
00182     ///< the resulting expression using the constraint information within
00183     ///< myself.  If subst_expr = NULL, use the unconstrained range
00184     ///< ([-Inf:Inf]) as the substitution expression.
00185 
00186     Expression *eliminate_vars(Expression *e,
00187                    const RefSet<Symbol> *vars_to_eliminate);
00188     ///< Eliminate all variables in the given expression by replacing
00189     ///< these variables with their ranges.  If vars_to_eliminate == NULL,
00190     ///< then all variables are eliminated.
00191 
00192     Expression * remove_truncates_with_var(Expression *e, const Symbol &var);
00193     ///< Remove all subexpressions of the form B*(A/B) and that contain
00194     ///< the given variable from the given expression.  These expressions
00195     ///< are removed by replacing the expressions with a range,
00196     ///< (e.g., B*(A/B) --> [A-B+1:A] if B > 0), then simplifying the
00197     ///< resulting expressions down.
00198 
00199     
00200     ///< Methods that modify/access the way I function.
00201 
00202     void range_join_accuracy(int acc);
00203     ///< Determines the accuracy of unions or intersections of two ranges.
00204     ///< Suppose that B and C are not comparable for the two ranges [A:B]
00205     ///< and [A:C].
00206     ///<        range_join_accuracy      union       intersection
00207     ///<                0              [A:+Infty]       [A:B]
00208     ///<                1              [A:+Infty]    [A:min(B,C)]
00209     ///<                2             [A:max(B,C)]   [A:min(B,C)]
00210     ///< Default is read from switch "range_acc"
00211 
00212     int range_join_accuracy();
00213     ///< Return the range join accuracy.
00214 
00215     void range_compare_accuracy(int acc);
00216     ///< Determines the accuracy of the expression comparison routines.
00217     ///< The higher the number, the more powerful and more expensive range
00218     ///< substitution algorithm used.
00219     ///<   Value     Range substition algorithm
00220     ///<     0     Simple range substitution scheme.
00221     ///<     1     Exact lower/upper bounds determined for monotonic expressions.
00222     ///<     2     Exact lower/upper bounds determined for quadratic expressions.
00223     ///<     3     Exact subst. algs. above may be called recursively.
00224     ///< Default is 1.
00225 
00226     int range_compare_accuracy();
00227     ///< Return the range compare accuracy.
00228 
00229     
00230     ///< Miscellaneous methods.
00231 
00232     RangeComparator &operator = (const RangeComparator &other);
00233     ///< Completely copy the contents of the other range comparator
00234     ///< into myself.
00235 
00236     const Symtab &symtab() const;
00237     ///< Return the symbol table associated with myself
00238 
00239     int debug_level() const;
00240     void debug_level(int level);
00241     ///< Access the debugging level of myself.  Higher debugging levels
00242     ///< generate greater amounts of debugging output.  A debug level of
00243     ///< 0, which is default, indicates no debugging output.
00244 
00245     virtual void    print(ostream &o) const;
00246     virtual int     structures_OK() const;
00247     ///< Support methods for Listable.h.  Note: listable clone is
00248     ///< missing. Subclasses must provide it.
00249 
00250 protected:
00251     int _debug_level;
00252 
00253     void _flush_sign_caches();
00254     ///< Flush out the saved sign for the all variables.  Should be
00255     ///< called whenever a variable's range changes.
00256 
00257 private:
00258     Map<Symbol,CompareData> _compare_info;
00259     const Symtab *_symtab_ref;
00260     bool _use_the_big_guns; ///< Use the more powerful but more expensive
00261                 ///< range substitution techniques.
00262     int _range_join_accuracy;   ///< Accuracy to union and intersect ranges
00263     int _range_compare_accuracy; ///< Accuracy to perform comparisons.
00264     int _cache_expr_signs;   ///< Nonzero if should cache computed expr signs
00265     ExprSet _cached_sign_exprs;  ///< Set of exprs whose signs have been cached
00266     Map<Expression,IntElem> _cached_expr_signs;
00267                 ///< Signs for previously tested exprs.
00268 
00269     CompareData &_compare_data(const Symbol &var);
00270     Expression *_build_delta(const Expression &e1, const Expression &e2);
00271     Relation _compare(Expression * delta);
00272     void _extract_ranges(Expression &expr);
00273     Expression *_solve_monotonic(Expression *expr, const Symbol &var,
00274                  const RangeExpr &subst_range);
00275     Expression *_find_quad_range(const Expression &e, const Symbol &var,
00276                  const RangeExpr &subst_range);
00277     Expression *_eliminate_quads(Expression *expr, const Symbol &var,
00278                  const RangeExpr &subst_range);
00279     Expression *_solve_for_range(Expression *expr, const Symbol &var,
00280                  const RangeExpr &subst_range);
00281     Expression *_remove_truncates(Expression *expr, const Symbol &var);
00282     void _begin_caching_expr_signs();
00283     void _end_caching_expr_signs();
00284 };
00285 
00286 ///< Description:
00287 ///< Return the complement of the given sign. (POS_EXPR <--> NEG_EXPR).
00288 
00289 EXPR_SIGN flip_sign(EXPR_SIGN sign);
00290 
00291 ///< Description:
00292 ///< Tell the RangeComparator class to start collecting statistics.
00293 
00294 void collect_range_stats();
00295 
00296 ///< Description:
00297 ///< Tell the RangeComparator class to stop collecting statistics.
00298 
00299 void stop_range_stats();
00300 
00301 ///< Description:
00302 ///< Print out the statistics collected so far.
00303 
00304 void print_range_stats(ostream &o);
00305 
00306 #endif
 © 1995-2005 University of Illinois, Urbana-Champaign. All rights reserved.  Fri Mar 25 23:06:04 2005