BaseStmtRanges.ccGo to the documentation of this file.00001
00002
00003
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
00022
00023 BaseStmtRanges::BaseStmtRanges(const Symtab &symtab)
00024 : RangeComparator(symtab)
00025 {
00026
00027 }
00028
00029 BaseStmtRanges::BaseStmtRanges(const BaseStmtRanges &other)
00030 : RangeComparator(other)
00031 {
00032
00033 }
00034
00035
00036
00037
00038 BaseStmtRanges::~BaseStmtRanges()
00039 {
00040
00041 }
00042
00043
00044
00045
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
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
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
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
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
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
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
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
00231
00232 const Expression *
00233 BaseStmtRanges::get_range_ref(const Symbol &var)
00234 {
00235 return _get_range_ref_c(var);
00236 }
00237
00238
00239
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
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
00279
00280 int
00281 BaseStmtRanges::operator != (const BaseStmtRanges &other) const
00282 {
00283 return ! (*this == other);
00284 }
00285
00286
00287
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
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
00352
00353 int
00354 BaseStmtRanges::structures_OK() const
00355 {
00356 return RangeComparator::structures_OK();
00357 }
|