Polaris: BaseStmtRanges.cc Source File

BaseStmtRanges.cc

Go to the documentation of this file.
00001 ///
00002 ///
00003 /// \file BaseStmtRanges.cc
00004 ///
00005 #include <limits.h>
00006 
00007 #include "../Expression/Expression.h"
00008 #include "../Collection/Iterator.h"
00009 #include "../Collection/KeyIterator.h"
00010 #include "../Collection/RefSet.h"
00011 #include "../Collection/RefList.h"
00012 #include "../utilities/expression_util.h"
00013 #include "../Symtab.h"
00014 
00015 #include "BaseStmtRanges.h"
00016 #include "RangeExpr.h"
00017 #include "range_util.h"
00018 #include "range_dict_util.h"
00019 
00020 
00021 ///  BaseStmtRanges
00022 
00023 BaseStmtRanges::BaseStmtRanges(const Symtab &symtab)
00024 : RangeComparator(symtab)
00025 {
00026     /// ...  nothing to do
00027 }
00028 
00029 BaseStmtRanges::BaseStmtRanges(const BaseStmtRanges &other)
00030 : RangeComparator(other)
00031 {
00032     /// ...  Nothing to do.
00033 }
00034 
00035 
00036 ///  ~BaseStmtRanges
00037 
00038 BaseStmtRanges::~BaseStmtRanges()
00039 {
00040     /// ...  nothing to do
00041 }
00042 
00043 
00044 
00045 ///  union_ranges
00046 
00047 void
00048 BaseStmtRanges::union_ranges(BaseStmtRanges &other)
00049 {
00050     RefSet<Symbol> *vars = range_vars();
00051     Iterator<Symbol> iter = *vars;
00052 
00053     for ( ; iter.valid(); ++iter) {
00054     const Expression *union_expr = other._get_range_ref_c(iter.current());
00055 
00056     if (union_expr)
00057         union_range(iter.current(), *union_expr, &other);
00058     else
00059         del_range(iter.current());
00060     }
00061 
00062     delete vars;
00063 }
00064 
00065 
00066 ///  widen_some_ranges
00067 
00068 void
00069 BaseStmtRanges::widen_some_ranges(BaseStmtRanges &other,
00070                   const RefSet<Symbol> &vars_to_widen)
00071 {
00072     Iterator<Symbol> iter = vars_to_widen;
00073 
00074     for ( ; iter.valid(); ++iter) {
00075     const Expression *widen_expr = other._get_range_ref_c(iter.current());
00076     
00077     if (widen_expr)
00078         widen_range(iter.current(), *widen_expr);
00079     else
00080         del_range(iter.current());
00081     }
00082 }
00083 
00084 
00085 ///  widen_ranges
00086 
00087 void
00088 BaseStmtRanges::widen_ranges(BaseStmtRanges &other)
00089 {
00090     RefSet<Symbol> *vars = range_vars();
00091     widen_some_ranges(other, *vars);
00092     delete vars;
00093 }
00094 
00095 
00096 ///  narrow_ranges
00097 
00098 void
00099 BaseStmtRanges::narrow_ranges(BaseStmtRanges &other)
00100 {
00101     RefSet<Symbol> *vars = range_vars();
00102     Iterator<Symbol> iter = *vars;
00103 
00104     for ( ; iter.valid(); ++iter) {
00105     const Expression *narrow_expr = other._get_range_ref_c(iter.current());
00106 
00107     if (narrow_expr)
00108         narrow_range(iter.current(), *narrow_expr);
00109     }
00110 
00111     delete vars;
00112 }
00113 
00114 
00115 ///  extract_ranges
00116 
00117 void
00118 BaseStmtRanges::extract_ranges(const Expression &expr,
00119                bool complement_expr GIV(false))
00120 {
00121     Map< Symbol, Set<Expression> > *ranges
00122     = ::extract_ranges(expr, complement_expr);
00123 
00124     KeyIterator< Symbol, Set<Expression> > var_iter = *ranges;
00125 
00126     for ( ; var_iter.valid(); ++var_iter) {
00127     const Symbol &var = var_iter.current_key();
00128     Iterator<Expression> range_iter = var_iter.current_data();
00129 
00130     for ( ; range_iter.valid(); ++range_iter)
00131         intersect_range(var, range_iter.current());
00132     }
00133 
00134     delete ranges;
00135 }
00136 
00137 
00138 ///  subst_in_ranges
00139 
00140 void
00141 BaseStmtRanges::subst_in_ranges(const Symbol &var,
00142                 const Expression *subst_expr)
00143 { 
00144     RefSet<Symbol> *vars = range_vars();
00145     Iterator<Symbol> iter = *vars;
00146 
00147     for ( ; iter.valid(); ++iter) {
00148     const Expression *orig_expr = _get_range_ref_c(iter.current());
00149 
00150     if (orig_expr && is_var_in_expr(*orig_expr, var)) {
00151         Expression *new_expr = subst_var_and_simplify(orig_expr->clone(),
00152                               var, subst_expr);
00153 
00154         if (is_var_in_expr(*new_expr, iter.current()))
00155         new_expr = subst_var_and_simplify(new_expr, iter.current(), 0);
00156         
00157         set_range(iter.current(), new_expr);
00158     }
00159     }
00160 
00161     delete vars;
00162 }
00163 
00164 
00165 ///  widen_range
00166 
00167 void
00168 BaseStmtRanges::widen_range(const Symbol &var, const Expression &widen_expr)
00169 {
00170     const Expression *old_range_ref = _get_range_ref_c(var);
00171 
00172     if (! old_range_ref || old_range_ref->op() == OMEGA_OP)
00173     return;
00174 
00175     if (_debug_level >= 1)
00176     cout << "Widening (" << *old_range_ref << ") with ("
00177         << widen_expr << ") for " << var.name_ref() << endl;
00178 
00179     Expression *result = ::widen_range(old_range_ref, &widen_expr, *this);
00180     set_range(var, result);
00181 
00182     if (_debug_level >= 1) {
00183     cout << "  result(widen): ";
00184 
00185     if (result)
00186         cout << *result;
00187     else
00188         cout << "NULL";
00189 
00190     cout << endl;
00191     }
00192 }
00193 
00194 
00195 ///  narrow_range
00196 
00197 void
00198 BaseStmtRanges::narrow_range(const Symbol &var, const Expression &narrow_expr)
00199 {
00200     const Expression *old_range_ref = _get_range_ref_c(var);
00201 
00202     if (_debug_level >= 1) {
00203     cout << "Narrowing (";
00204 
00205     if (old_range_ref)
00206         cout << *old_range_ref;
00207     else
00208         cout << "NULL";
00209         
00210     cout << ") with (" << narrow_expr << ") for "
00211         << var.name_ref() << endl;
00212     }
00213 
00214     Expression *result = ::narrow_range(old_range_ref, &narrow_expr, *this);
00215     set_range(var, result);
00216 
00217     if (_debug_level >= 1) {
00218     cout << "  result(widen): ";
00219     
00220     if (result)
00221         cout << *result;
00222     else
00223         cout << "NULL";
00224     
00225     cout << endl;
00226     }
00227 }
00228 
00229 
00230 /// get_range_ref
00231 
00232 const Expression *
00233 BaseStmtRanges::get_range_ref(const Symbol &var)
00234 {
00235     return _get_range_ref_c(var);
00236 }
00237 
00238 
00239 ///  operator =
00240 
00241 BaseStmtRanges &
00242 BaseStmtRanges::operator = (const BaseStmtRanges &other)
00243 {
00244     if (this != &other)
00245     RangeComparator::operator=(other);
00246 
00247     return *this;
00248 }
00249 
00250 
00251 ///  operator ==
00252 
00253 int
00254 BaseStmtRanges::operator == (const BaseStmtRanges &other) const
00255 {
00256     if (entries() != other.entries())
00257     return 0;
00258     else {
00259     RefSet<Symbol> *vars = range_vars();
00260     Iterator<Symbol> iter = *vars;
00261 
00262     for ( ; iter.valid(); ++iter) {
00263         const Expression *my_range = _get_range_ref_c(iter.current());
00264         p_assert(my_range, "Set returned by range_vars() contains a var without a range.");
00265         const Expression *other_range = other._get_range_ref_c(iter.current());
00266         
00267         if (! other_range || my_range->compare(*other_range) != 0)
00268         return 0;
00269     }
00270 
00271     delete vars;
00272     }
00273 
00274     return 1;
00275 }
00276 
00277 
00278 ///  operator !=
00279 
00280 int
00281 BaseStmtRanges::operator != (const BaseStmtRanges &other) const
00282 {
00283     return ! (*this == other);
00284 }
00285 
00286 
00287 ///  print
00288 
00289 void
00290 BaseStmtRanges::print(ostream &o) const
00291 {
00292     RefSet<Symbol> *vars = range_vars();
00293     Iterator<Symbol> iter = *vars;
00294     bool first = true;
00295 
00296     o << "{";
00297     RangeComparator::print(o);
00298     o << ", ";
00299     o << "{";
00300 
00301     for ( ; iter.valid(); ++iter) {
00302     if (! first)
00303         o << ", ";
00304     else
00305         first = false;
00306 
00307     o << iter.current().name_ref() << ": " << *_get_range_ref_c(iter.current());
00308     }
00309 
00310     delete vars;
00311 
00312     o << "}";
00313     o << "}";
00314 }
00315 
00316 
00317 ///  pretty_print
00318 
00319 void
00320 BaseStmtRanges::pretty_print(ostream &o) const
00321 {
00322     RefSet<Symbol> *vars = range_vars();
00323     RefList<Symbol> sorted_keys;
00324     Iterator<Symbol> c_iter = *vars;
00325 
00326     for ( ; c_iter.valid(); ++c_iter)
00327     sorted_keys.ins_last(c_iter.current());
00328 
00329     delete vars;
00330     sort_sym_list(sorted_keys);
00331     Iterator<Symbol> key_iter = sorted_keys;
00332     bool first = true;
00333 
00334     o << "{";
00335 
00336     for ( ; key_iter.valid(); ++key_iter) {
00337     if (! first)
00338         o << ", ";
00339     else
00340         first = false;
00341 
00342     const Symbol &var = key_iter.current();
00343     const Expression &value = *_get_range_ref_c(var);
00344     pretty_print_range(o, value, var);
00345     }
00346 
00347     o << "}";
00348 }
00349 
00350 
00351 ///  structures_OK
00352 
00353 int
00354 BaseStmtRanges::structures_OK() const
00355 {
00356     return RangeComparator::structures_OK();
00357 }
 © 1995-2005 University of Illinois, Urbana-Champaign. All rights reserved.  Fri Mar 25 23:05:41 2005