00001
00002
00003
00004
00005 #include "../Statement/Statement.h"
00006
00007 #include "RangeAccessor.h"
00008 #include "RangeExpr.h"
00009 #include "range_util.h"
00010
00011
00012
00013
00014 RangeAccessor::RangeAccessor(RangeDict &ranges, const Statement &stmt)
00015 : RangeComparator(ranges.symtab())
00016 {
00017 _range_dict = &ranges;
00018 _stmt1 = &stmt;
00019 _stmt2 = 0;
00020 _union_ranges = true;
00021 }
00022 RangeAccessor::RangeAccessor(RangeDict &ranges, const Statement &stmt1,
00023 const Statement &stmt2, bool union_ranges GIV(true))
00024 : RangeComparator(ranges.symtab())
00025 {
00026 _range_dict = &ranges;
00027 _stmt1 = &stmt1;
00028 _stmt2 = &stmt2;
00029 _union_ranges = union_ranges;
00030
00031 if (&stmt1 == &stmt2) {
00032 _stmt2 = 0;
00033 _union_ranges = true;
00034 }
00035 }
00036
00037 RangeAccessor::RangeAccessor(const RangeAccessor &other)
00038 : RangeComparator(other)
00039 {
00040 *this = other;
00041 }
00042
00043
00044
00045
00046 RangeAccessor::~RangeAccessor()
00047 {
00048
00049 }
00050
00051
00052
00053
00054 void
00055 RangeAccessor::set_range(const Symbol &var, Expression *range)
00056 {
00057 _flush_sign_caches();
00058
00059 if (! range)
00060 range = omega();
00061
00062 _local_ranges.ins(var, range);
00063 }
00064
00065
00066
00067
00068 void
00069 RangeAccessor::del_range(const Symbol &var)
00070 {
00071 set_range(var, 0);
00072 }
00073
00074
00075
00076
00077 const Expression *
00078 RangeAccessor::get_range_ref(const Symbol &var)
00079 {
00080 Expression *result = 0;
00081 Expression *local_range = _local_ranges.find_ref(var);
00082
00083 if (local_range) {
00084 if (local_range->op() != OMEGA_OP)
00085 result = local_range;
00086 }
00087 else {
00088 const Expression *stmt1_range = _range_dict->_get_range_ref(var,
00089 *_stmt1);
00090
00091 if (! _stmt2)
00092 return stmt1_range;
00093 else {
00094 const Expression *stmt2_range = _range_dict->_get_range_ref(var,
00095 *_stmt2);
00096
00097 RangeAccessor stmt1_accessor(*_range_dict, *_stmt1);
00098 RangeAccessor stmt2_accessor(*_range_dict, *_stmt2);
00099
00100 if (_union_ranges)
00101 result = union_ranges(stmt1_range, stmt1_accessor,
00102 stmt2_range, stmt2_accessor);
00103 else
00104 result = intersect_ranges(stmt1_range, stmt1_accessor,
00105 stmt2_range, stmt2_accessor);
00106
00107 set_range(var, result);
00108 }
00109 }
00110
00111 return result;
00112 }
00113
00114
00115
00116
00117 RangeAccessor &
00118 RangeAccessor::operator = (const RangeAccessor &other)
00119 {
00120 if (this != &other) {
00121 RangeComparator::operator=(other);
00122 _range_dict = other._range_dict;
00123 _stmt1 = other._stmt1;
00124 _stmt2 = other._stmt2;
00125 _union_ranges = other._union_ranges;
00126 _local_ranges = other._local_ranges;
00127 }
00128
00129 return *this;
00130 }
00131
00132
00133
00134
00135 void
00136 RangeAccessor::print(ostream &o) const
00137 {
00138 o << "{";
00139 RangeComparator::print(o);
00140 o << ", ";
00141 o << "&_range_dict=" << _range_dict << ", ";
00142
00143 if (_stmt2) {
00144 o << "stmt1=" << _stmt1->tag() << ", ";
00145 o << "stmt2=" << _stmt2->tag() << ", ";
00146 o << "union=" << _union_ranges << ", ";
00147 }
00148 else
00149 o << "stmt=" << _stmt1->tag() << ", ";
00150
00151 o << "local_ranges={";
00152
00153 KeyIterator<Symbol, Expression> iter = _local_ranges;
00154 bool first = true;
00155
00156 for ( ; iter.valid(); ++iter) {
00157 if (! first)
00158 o << ", ";
00159 else
00160 first = false;
00161
00162 o << iter.current_key().name_ref() << ": " << iter.current_data();
00163 }
00164
00165 o << "}";
00166 o << "}";
00167 }
00168
00169
00170
00171
00172 void
00173 RangeAccessor::pretty_print(ostream &o) const
00174 {
00175 if (_stmt2) {
00176 if (_union_ranges)
00177 o << "Union of: ";
00178 else
00179 o << "Intersection of: ";
00180
00181 _range_dict->pretty_print(o, *_stmt1);
00182 o << "\n and: ";
00183 _range_dict->pretty_print(o, *_stmt2);
00184 }
00185 else {
00186 o << "Constraints of: ";
00187 _range_dict->pretty_print(o, *_stmt1);
00188 }
00189
00190 o << "Modified by: ";
00191
00192 RefList<Symbol> sorted_keys;
00193 KeyIterator<Symbol, Expression> r_iter = _local_ranges;
00194
00195 for ( ; r_iter.valid(); ++r_iter) {
00196 const char *sym_name = r_iter.current_key().name_ref();
00197 Symbol *prev = 0;
00198 Iterator<Symbol> key_iter = sorted_keys;
00199
00200 for ( ; key_iter.valid(); ++key_iter) {
00201 int name_cmp = strcmp(sym_name, key_iter.current().name_ref());
00202 if (name_cmp < 0)
00203 break;
00204 else
00205 prev = &key_iter.current();
00206 }
00207
00208 sorted_keys.ins_after(r_iter.current_key(), *prev);
00209 }
00210
00211 Iterator<Symbol> key_iter = sorted_keys;
00212 bool first = true;
00213
00214 o << "{";
00215
00216 for ( ; key_iter.valid(); ++key_iter) {
00217 if (! first)
00218 o << ", ";
00219 else
00220 first = false;
00221
00222 const Symbol &var = key_iter.current();
00223 const Expression &value = _local_ranges[var];
00224 pretty_print_range(o, value, var);
00225 }
00226
00227 o << "}";
00228 }
00229
00230
00231
00232
00233 Listable *
00234 RangeAccessor::listable_clone(void) const
00235 {
00236 return new RangeAccessor(*this);
00237 }
00238
00239
00240
00241
00242 int
00243 RangeAccessor::structures_OK() const
00244 {
00245 return (RangeComparator::structures_OK()
00246 && _local_ranges.structures_OK());
00247 }
00248
00249 Relation
00250 RangeAccessor::compare(const Expression &e1, int value){
00251 return RangeComparator::compare(e1, value);
00252 }
00253
00254 Relation
00255 RangeAccessor::compare(const Expression &e1, const Expression &e2){
00256 return RangeComparator::compare(e1, e2);
00257 }
00258
00259