| Polaris: RangeComparator.h Source File | ||
|
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members
RangeComparator.hGo 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 |
||
|