00001
00002
00003
00004 #ifndef _PROP_CTRL_RANGE_WS_CC
00005 #define _PROP_CTRL_RANGE_WS_CC
00006
00007 #include "../Collection/Iterator.h"
00008 #include "../utilities/equivalence_util.h"
00009
00010 #include "PropCtrlRangeWS.h"
00011 #include "RangeExpr.h"
00012 #include "range_util.h"
00013
00014
00015
00016
00017
00018 void
00019 PropCtrlRangeWS::_add_to_mod_set(const RefSet<Expression> &refs)
00020 {
00021 Iterator<Expression> iter = refs;
00022
00023 for ( ; iter.valid(); ++iter) {
00024 Symbol *symbol = iter.current().base_variable_ref();
00025
00026 if (symbol && symbol->sym_class() == VARIABLE_CLASS)
00027 if (symbol->type().data_type() == INTEGER_TYPE)
00028 mod_set.ins(*symbol);
00029
00030
00031
00032 RefSet<Symbol> *aliases = equiv_aliases(*symbol);
00033
00034 if (aliases) {
00035 Iterator<Symbol> alias_iter = *aliases;
00036
00037 for ( ; alias_iter.valid(); ++alias_iter) {
00038 Symbol &alias_symbol = alias_iter.current();
00039
00040 if (alias_symbol.type().data_type() == INTEGER_TYPE)
00041 mod_set.ins(alias_symbol);
00042 }
00043
00044 delete aliases;
00045 }
00046 }
00047 }
00048
00049
00050
00051
00052
00053
00054 void
00055 PropCtrlRangeWS::_add_asserts_to_ranges(const Statement &stmt)
00056 {
00057 Iterator<Assertion> assert_iter = stmt.assertions();
00058
00059 for ( ; assert_iter.valid(); ++assert_iter) {
00060 const Assertion &assert = assert_iter.current();
00061
00062 if (assert.type() == AS_RELATION) {
00063 Iterator<Expression> arg_iter = assert.arg_list_guarded();
00064
00065 for ( ; arg_iter.valid(); ++arg_iter) {
00066 Map< Symbol, Set<Expression> > *assert_ranges
00067 = extract_ranges(arg_iter.current());
00068
00069 if (! new_ranges)
00070 new_ranges = assert_ranges;
00071 else {
00072 KeyIterator<Symbol, Set<Expression> > ar_iter = *assert_ranges;
00073
00074 for ( ; ar_iter.valid(); ++ar_iter) {
00075 const Symbol &var = ar_iter.current_key();
00076 Set<Expression> *var_ranges = new_ranges->find_ref(var);
00077
00078 if (! var_ranges)
00079 new_ranges->ins(var, new Set<Expression>(ar_iter.current_data()));
00080 else {
00081 Iterator<Expression> range_iter = ar_iter.current_data();
00082
00083 for ( ; range_iter.valid(); ++range_iter)
00084 var_ranges->ins(range_iter.current().clone());
00085 }
00086 }
00087
00088 delete assert_ranges;
00089 }
00090 }
00091 }
00092 }
00093 }
00094
00095
00096
00097
00098 PropCtrlRangeWS::PropCtrlRangeWS(unsigned long pass_tag, const Statement &stmt)
00099 : WorkSpace(pass_tag)
00100 {
00101 _add_to_mod_set(stmt.out_refs());
00102
00103
00104 new_ranges = 0;
00105 new_else_ranges = 0;
00106
00107 if (stmt.stmt_class() == IF_STMT || stmt.stmt_class() == ELSEIF_STMT) {
00108 new_ranges = extract_ranges(stmt.expr(), false);
00109 new_else_ranges = extract_ranges(stmt.expr(), true);
00110 }
00111 else if (stmt.stmt_class() == DO_STMT
00112 && stmt.index().type().data_type() == INTEGER_TYPE
00113 && is_integer_constant(stmt.step())) {
00114 Expression *bound_cond, *index_range;
00115
00116 if (stmt.step().value() >= 0) {
00117 bound_cond = le(stmt.init().clone(), stmt.limit().clone());
00118 index_range = new RangeExpr(stmt.init().clone(), stmt.limit().clone());
00119 }
00120 else {
00121 bound_cond = ge(stmt.init().clone(), stmt.limit().clone());
00122 index_range = new RangeExpr(stmt.limit().clone(), stmt.init().clone());
00123 }
00124
00125 new_ranges = extract_ranges(*bound_cond);
00126 delete bound_cond;
00127 Set<Expression> *index_set = new Set<Expression>;
00128 index_set->ins(index_range);
00129 new_ranges->ins(stmt.index().symbol(), index_set);
00130 new_else_ranges = new Map< Symbol, Set<Expression> >;
00131 }
00132
00133 _add_asserts_to_ranges(stmt);
00134
00135 _num_visits = 0;
00136 _visited = false;
00137 _toporder = -1;
00138 }
00139
00140 PropCtrlRangeWS::PropCtrlRangeWS(const PropCtrlRangeWS &other) : WorkSpace(other)
00141 {
00142 mod_set = other.mod_set;
00143
00144 if (other.new_ranges)
00145 new_ranges = new Map< Symbol, Set<Expression> >(*other.new_ranges);
00146 else
00147 new_ranges = 0;
00148
00149 if (other.new_else_ranges)
00150 new_else_ranges = new Map< Symbol, Set<Expression> >(*other.new_else_ranges);
00151 else
00152 new_else_ranges = 0;
00153
00154 in_ranges = other.in_ranges;
00155 out_ranges = other.out_ranges;
00156 out_else_ranges = other.out_else_ranges;
00157
00158 _num_visits = other._num_visits;
00159 _visited = other._visited;
00160 _toporder = other._toporder;
00161 }
00162
00163
00164
00165
00166 PropCtrlRangeWS::~PropCtrlRangeWS()
00167 {
00168 if (new_ranges)
00169 delete new_ranges;
00170
00171 if (new_else_ranges)
00172 delete new_else_ranges;
00173 }
00174
00175
00176
00177
00178
00179
00180 static void
00181 _add_range_refs(Map<Symbol, RefSet<Expression> > &ranges,
00182 const Map<Symbol, Set<Expression> > &new_ranges)
00183 {
00184 KeyIterator<Symbol, Set<Expression> > new_iter = new_ranges;
00185
00186 for ( ; new_iter.valid(); ++new_iter) {
00187 const Symbol &var = new_iter.current_key();
00188 RefSet<Expression> *var_ranges = ranges.find_ref(var);
00189
00190 if (! var_ranges) {
00191 var_ranges = new RefSet<Expression>;
00192 ranges.ins(var, var_ranges);
00193 }
00194
00195 Iterator<Expression> range_iter = new_iter.current_data();
00196
00197 for ( ; range_iter.valid(); ++range_iter)
00198 var_ranges->ins(range_iter.current());
00199 }
00200 }
00201
00202
00203
00204
00205
00206
00207 static bool
00208 _are_vars_in_expr(const Expression &e, const RefSet<Symbol> &vars)
00209 {
00210 if (e.op() == ID_OP)
00211 return vars.member(e.symbol());
00212 else {
00213 Iterator<Expression> iter = e.arg_list();
00214
00215 for ( ; iter.valid(); ++iter)
00216 if (_are_vars_in_expr(iter.current(), vars))
00217 return true;
00218 }
00219
00220 return false;
00221 }
00222
00223
00224
00225
00226 bool
00227 PropCtrlRangeWS::update_out_ranges()
00228 {
00229 bool result = false;
00230 out_ranges = in_ranges;
00231
00232 if (mod_set.entries() > 0) {
00233 KeyIterator<Symbol, RefSet<Expression> > out_iter = out_ranges;
00234
00235 for ( ; out_iter.valid(); ++out_iter) {
00236 Mutator<Expression> out_range_iter = out_iter.current_data();
00237
00238 for ( ; out_range_iter.valid(); ++out_range_iter)
00239 if (_are_vars_in_expr(out_range_iter.current(), mod_set))
00240 {
00241 out_range_iter.del();
00242 result = true;
00243 }
00244 }
00245 }
00246
00247 if (new_else_ranges) {
00248 out_else_ranges = out_ranges;
00249 _add_range_refs(out_else_ranges, *new_else_ranges);
00250 result = true;
00251 }
00252
00253 if (new_ranges)
00254 {
00255 _add_range_refs(out_ranges, *new_ranges);
00256 result = true;
00257 }
00258 return result;
00259 }
00260
00261
00262
00263
00264
00265 static void
00266 _print_var_set(ostream &o, const RefSet<Symbol> &var_set)
00267 {
00268 Iterator<Symbol> var_iter = var_set;
00269
00270 o << "{";
00271
00272 if (var_iter.valid()) {
00273 o << var_iter.current().name_ref();
00274 ++var_iter;
00275
00276 for ( ; var_iter.valid(); ++var_iter)
00277 o << ", " << var_iter.current().name_ref();
00278 }
00279
00280 o << "}";
00281 }
00282
00283
00284
00285
00286
00287 static void
00288 _print_range_map(ostream &o, const Map<Symbol, Set<Expression> > &ranges)
00289 {
00290 o << "{";
00291
00292 KeyIterator<Symbol, Set<Expression> > rmap_iter = ranges;
00293
00294 if (rmap_iter.valid()) {
00295 o << rmap_iter.current_key().name_ref()
00296 << ": " << rmap_iter.current_data();
00297 ++rmap_iter;
00298
00299 for ( ; rmap_iter.valid(); ++rmap_iter)
00300 o << ", "<< rmap_iter.current_key().name_ref()
00301 << ": " << rmap_iter.current_data();
00302 }
00303
00304 o << "}";
00305 }
00306
00307 static void
00308 _print_range_map(ostream &o, const Map<Symbol, RefSet<Expression> > &ranges)
00309 {
00310 o << "{";
00311
00312 KeyIterator<Symbol, RefSet<Expression> > rmap_iter = ranges;
00313
00314 if (rmap_iter.valid()) {
00315 o << rmap_iter.current_key().name_ref()
00316 << ": " << rmap_iter.current_data();
00317 ++rmap_iter;
00318
00319 for ( ; rmap_iter.valid(); ++rmap_iter)
00320 o << ", "<< rmap_iter.current_key().name_ref()
00321 << ": " << rmap_iter.current_data();
00322 }
00323
00324 o << "}";
00325 }
00326
00327
00328
00329
00330 void
00331 PropCtrlRangeWS::print(ostream &o) const
00332 {
00333 o << "RangeWS:{";
00334 o << "mod=";
00335 _print_var_set(o, mod_set);
00336 o << ", ";
00337
00338 o << "new_ranges=";
00339
00340 if (new_ranges)
00341 _print_range_map(o, *new_ranges);
00342 else
00343 o << "NULL";
00344
00345 o << ", ";
00346 o << "new_else_ranges=";
00347
00348 if (new_else_ranges)
00349 _print_range_map(o, *new_else_ranges);
00350 else
00351 o << "NULL";
00352
00353 o << ", ";
00354
00355 o << "in_ranges=";
00356 _print_range_map(o, in_ranges);
00357 o << ", ";
00358
00359 o << "out_ranges=";
00360 _print_range_map(o, out_ranges);
00361 o << ", ";
00362
00363 o << "out_else_ranges=";
00364 _print_range_map(o, out_else_ranges);
00365 o << ", ";
00366
00367 o << "num_visits=" << _num_visits << ", ";
00368 o << "toporder=" << _toporder << ", ";
00369
00370 o << "}";
00371 }
00372
00373
00374
00375
00376 int
00377 PropCtrlRangeWS::structures_OK() const
00378 {
00379 if (! mod_set.structures_OK())
00380 return 0;
00381
00382 if (new_ranges && ! new_ranges->structures_OK())
00383 return 0;
00384
00385 if (new_else_ranges && ! new_else_ranges->structures_OK())
00386 return 0;
00387
00388 if (! in_ranges.structures_OK())
00389 return 0;
00390
00391 if (! out_ranges.structures_OK())
00392 return 0;
00393
00394 if (! out_else_ranges.structures_OK())
00395 return 0;
00396
00397 return 1;
00398 }
00399
00400 #endif