00001
00002
00003
00004
00005 #include "utilities/expression_util.h"
00006
00007 #include "range_util.h"
00008 #include "RangeExpr.h"
00009 #include "SSAFullRangeData.h"
00010 #include "SSAFullRangeDict.h"
00011
00012
00013
00014 template class TypedBaseMap<Symbol,SSARangeOrData>;
00015 template class ProtoMap<Symbol,SSARangeOrData>;
00016 template class Map<Symbol,SSARangeOrData>;
00017 template ostream & operator << (ostream &,
00018 const Map<Symbol,SSARangeOrData> &);
00019 template class KeyIterator<Symbol,SSARangeOrData>;
00020
00021 template class TypedCollection<SSAFullRangeData>;
00022 template class RefList<SSAFullRangeData>;
00023 template ostream & operator << (ostream &, const RefList<SSAFullRangeData> &);
00024 template class RefSet<SSAFullRangeData>;
00025 template ostream & operator << (ostream &, const RefSet<SSAFullRangeData> &);
00026 template class Assign<SSAFullRangeData>;
00027 template class Iterator<SSAFullRangeData>;
00028
00029 template class TypedBaseMap<Symbol,SSAFullRangeData>;
00030 template class ProtoMap<Symbol,SSAFullRangeData>;
00031 template class Map<Symbol,SSAFullRangeData>;
00032 template ostream & operator << (ostream &,
00033 const Map<Symbol,SSAFullRangeData> &);
00034 template class KeyIterator<Symbol,SSAFullRangeData>;
00035
00036
00037
00038
00039
00040
00041 void
00042 SSARangeOrData::print(ostream &o) const
00043 {
00044 o << "[";
00045
00046 if (_is_range) {
00047 o << "range=";
00048
00049 if (_range_ref)
00050 o << *_range_ref;
00051 else
00052 o << NULL;
00053 }
00054 else
00055 o << "data=" << _data_ref->stmt().tag();
00056
00057 o << "]";
00058 }
00059
00060
00061
00062
00063
00064
00065 static int
00066 _is_ssa_function( const Expression & ex )
00067 {
00068 switch (ex.op()) {
00069 case ALPHA_OP:
00070 case ETA_OP:
00071 case GAMMA_OP:
00072 case GMU_OP:
00073 case MU_OP:
00074 case PHI_OP:
00075 return 1;
00076 }
00077
00078 return 0;
00079 }
00080
00081
00082
00083
00084 SSAFullRangeData::SSAFullRangeData(const Statement &stmt, int timestamp,
00085 SSAFullRangeDict &range_dict,
00086 int debug GIV(0))
00087 : _accessor(range_dict, stmt)
00088 {
00089 p_assert(stmt.stmt_class() == ASSIGNMENT_STMT,
00090 "The statement given to the SSAFullRangeData constructor was not an assignment statement.");
00091 _stmt_ref = &stmt;
00092 _timestamp = timestamp;
00093 _control_ranges_ref = &range_dict._control_ranges;
00094 is_phi_stmt = _is_ssa_function(stmt.rhs());
00095
00096 if (is_phi_stmt)
00097 _range = new RangeExpr(constant(1), constant(0));
00098 else
00099 _range = simplify(stmt.rhs().clone());
00100
00101 is_poisoned = false;
00102 needs_iteration = false;
00103 needs_widening = false;
00104 are_all_args_defined = false;
00105 union_arg_ranges = false;
00106 toporder = -1;
00107 num_updates = 0;
00108 computed = false;
00109 df_order = -1;
00110 low_link = -1;
00111 _debug_level = debug;
00112 }
00113
00114 SSAFullRangeData::SSAFullRangeData(const SSAFullRangeData &other)
00115 : _accessor(other._accessor)
00116 {
00117 _stmt_ref = other._stmt_ref;
00118 _timestamp = other._timestamp;
00119 _control_ranges_ref = other._control_ranges_ref;
00120
00121 if (other._range)
00122 _range = other._range->clone();
00123 else
00124 _range = 0;
00125
00126 is_phi_stmt = other.is_phi_stmt;
00127 is_poisoned = other.is_poisoned;
00128 needs_iteration = other.needs_iteration;
00129 needs_widening = other.needs_widening;
00130 arg_ranges_or_data = other.arg_ranges_or_data;
00131 arg_preds = other.arg_preds;
00132 are_all_args_defined = other.are_all_args_defined;
00133 toporder = other.toporder;
00134 num_updates = other.num_updates;
00135 computed = other.computed;
00136 df_order = other.df_order;
00137 low_link = other.low_link;
00138 _debug_level = other._debug_level;
00139 }
00140
00141
00142
00143
00144 SSAFullRangeData::~SSAFullRangeData()
00145 {
00146 if (_range)
00147 delete _range;
00148 }
00149
00150
00151
00152
00153
00154
00155 static inline void
00156 _modify_expr(Expression *& expr, Expression *new_expr)
00157 {
00158 if (expr)
00159 delete expr;
00160
00161 expr = new_expr;
00162 }
00163
00164
00165
00166
00167
00168
00169
00170
00171 Expression *
00172 SSAFullRangeData::_arg_full_range(const Symbol &arg)
00173 {
00174 Expression *arg_full_range = 0;
00175 SSARangeOrData *range_or_data = arg_ranges_or_data.find_ref(arg);
00176
00177 if (range_or_data) {
00178 const Expression *arg_range;
00179
00180 if (range_or_data->is_range())
00181 arg_range = range_or_data->range_ref();
00182 else
00183 arg_range = range_or_data->data().range_ref();
00184
00185 if (arg_range)
00186 arg_full_range = arg_range->clone();
00187 }
00188
00189
00190
00191
00192 const Statement *control_stmt = arg_preds.find_ref(arg);
00193
00194 if (! control_stmt)
00195 control_stmt = &stmt();
00196
00197 RangeAccessor control_accessor(*_control_ranges_ref, *control_stmt);
00198 const Expression * arg_control_range = control_accessor.get_range_ref(arg);
00199
00200 if (arg_control_range && arg_control_range->op() != OMEGA_OP)
00201 _modify_expr(arg_full_range,
00202 intersect_ranges(arg_full_range, _accessor,
00203 arg_control_range, _accessor));
00204
00205
00206
00207 const Symbol &var = stmt().lhs().symbol();
00208
00209 if (arg_full_range && is_var_in_expr(*arg_full_range, var)) {
00210
00211 Expression *subst_range;
00212
00213 if (range_ref())
00214 subst_range = range_ref()->clone();
00215 else
00216 subst_range = 0;
00217
00218 const Expression *my_control_range = control_accessor.get_range_ref(var);
00219 if (my_control_range && my_control_range->op() != OMEGA_OP)
00220 _modify_expr(subst_range,
00221 intersect_ranges(subst_range, _accessor,
00222 my_control_range, _accessor));
00223
00224 arg_full_range = _accessor.subst_var_and_simplify(arg_full_range, var,
00225 subst_range);
00226
00227 if (subst_range)
00228 delete subst_range;
00229 }
00230
00231 return arg_full_range;
00232 }
00233
00234
00235
00236
00237
00238
00239
00240 Expression *
00241 SSAFullRangeData::_union_args(bool &new_all_args_are_defined)
00242 {
00243 Expression *new_range = new RangeExpr(constant(1), constant(0));
00244 new_all_args_are_defined = true;
00245 Iterator<Symbol> iter = args;
00246
00247 for ( ; iter.valid(); ++iter) {
00248 Symbol &arg = iter.current();
00249 SSARangeOrData &range_or_data = arg_ranges_or_data[arg];
00250 const Expression *arg_range = 0;
00251
00252 if (range_or_data.is_range())
00253 arg_range = range_or_data.range_ref();
00254 else
00255 arg_range = range_or_data.data().range_ref();
00256
00257 if (arg_range && is_empty_range(*arg_range))
00258 new_all_args_are_defined = false;
00259 else {
00260 Expression *arg_full_range;
00261
00262 if (! union_arg_ranges
00263 && ( ! range_or_data.is_data()
00264 || range_or_data.data().toporder <= toporder))
00265
00266 arg_full_range = id(arg);
00267 else
00268 arg_full_range = _arg_full_range(arg);
00269
00270
00271
00272 if (_debug_level >= 30) {
00273 cout << "! unioning ";
00274
00275 if (new_range)
00276 cout << *new_range;
00277 else
00278 cout << "NULL";
00279
00280 cout << " with ";
00281
00282 if (arg_full_range)
00283 cout << *arg_full_range;
00284 else
00285 cout << "NULL";
00286
00287 cout << endl;
00288 }
00289
00290 if (arg_full_range && is_empty_range(*arg_full_range))
00291 new_all_args_are_defined = false;
00292 else
00293 _modify_expr(new_range, union_ranges(new_range, _accessor,
00294 arg_full_range,
00295 _accessor));
00296
00297 if (arg_full_range)
00298 delete arg_full_range;
00299 }
00300 }
00301
00302 return new_range;
00303 }
00304
00305
00306
00307
00308 bool
00309 SSAFullRangeData::update(bool in_widening_phase GIV(true))
00310 {
00311 bool changed = false;
00312
00313
00314
00315 KeyIterator<Symbol, SSARangeOrData> iter = arg_ranges_or_data;
00316
00317 for ( ; iter.valid(); ++iter)
00318 if (iter.current_data().is_data()) {
00319 const SSAFullRangeData &arg_data = iter.current_data().data();
00320
00321 if (! is_poisoned
00322 && (arg_data.timestamp() != timestamp()
00323 || arg_data.is_poisoned)) {
00324 is_poisoned = true;
00325 changed = true;
00326 }
00327 }
00328
00329
00330
00331 if (is_phi_stmt) {
00332 bool new_all_args_are_defined;
00333 Expression *new_range = _union_args(new_all_args_are_defined);
00334
00335 if (! new_range && ! union_arg_ranges) {
00336 union_arg_ranges = true;
00337 new_range = _union_args(new_all_args_are_defined);
00338 }
00339
00340 if (in_widening_phase) {
00341 if (needs_widening && are_all_args_defined)
00342 _modify_expr(new_range, widen_range(new_range, _range, _accessor));
00343 }
00344 else
00345 _modify_expr(new_range, narrow_range(new_range, _range, _accessor));
00346
00347 are_all_args_defined = new_all_args_are_defined;
00348
00349 if ((! _range && new_range)
00350 || (_range && ! new_range)
00351 || (_range && _range->compare(*new_range) != 0)) {
00352
00353 _modify_expr(_range, new_range);
00354 new_range = 0;
00355 changed = true;
00356 }
00357
00358 if (new_range)
00359 delete new_range;
00360 }
00361
00362 ++num_updates;
00363
00364 if (_debug_level >= 20) {
00365 cout << stmt().tag() << ": ";
00366 int zero = 0;
00367 stmt().write(cout, zero);
00368 cout << " " << *this << endl;
00369 }
00370
00371
00372
00373
00374 if (! is_phi_stmt)
00375 changed = true;
00376
00377 return changed;
00378 }
00379
00380
00381
00382
00383 RefSet<SSAFullRangeData> *
00384 SSAFullRangeData::succs() const
00385 {
00386 RefSet<SSAFullRangeData> *my_succs = new RefSet<SSAFullRangeData>;
00387 KeyIterator<Symbol, SSARangeOrData> iter = arg_ranges_or_data;
00388
00389 for ( ; iter.valid(); ++iter)
00390 if (iter.current_data().is_data()
00391 && ! iter.current_data().data().computed
00392 && iter.current_data().data().timestamp() == timestamp())
00393
00394 my_succs->ins(iter.current_data().data());
00395
00396 return my_succs;
00397 }
00398
00399
00400
00401
00402 Listable *
00403 SSAFullRangeData::listable_clone() const
00404 {
00405 return new SSAFullRangeData(*this);
00406 }
00407
00408
00409
00410
00411 void
00412 SSAFullRangeData::print(ostream &o) const
00413 {
00414 o << "[";
00415 o << "stmt=" << _stmt_ref->tag();
00416 o << ", ts=" << _timestamp;
00417 o << ", range=";
00418
00419 if (_range)
00420 o << *_range;
00421 else
00422 o << "NULL";
00423
00424 o << ", psnd=" << is_poisoned;
00425 o << ", iter=" << needs_iteration;
00426 o << ", wide=" << needs_widening;
00427 o << ", adef=" << are_all_args_defined;
00428
00429 o << ", tord=" << toporder;
00430 o << ", nupd=" << num_updates;
00431 o << ", unar=" << union_arg_ranges;
00432 o << ", comp=" << computed;
00433 o << ", dfor=" << df_order;
00434 o << ", lwlk=" << low_link;
00435 o << ", args={";
00436
00437 Iterator<Symbol> arg_iter = args;
00438
00439 if (arg_iter.valid()) {
00440 o << arg_iter.current().name_ref() << ":"
00441 << arg_ranges_or_data[arg_iter.current()];
00442 ++arg_iter;
00443
00444 for ( ; arg_iter.valid(); ++arg_iter)
00445 o << ", " << arg_iter.current().name_ref() << ":"
00446 << arg_ranges_or_data[arg_iter.current()];
00447 }
00448
00449 o << "}";
00450 o << ", pred={";
00451
00452 KeyIterator<Symbol,Statement> pred_iter = arg_preds;
00453
00454 if (pred_iter.valid()) {
00455 o << pred_iter.current_key().name_ref() << ":"
00456 << pred_iter.current_data().tag();
00457 ++pred_iter;
00458
00459 for ( ; pred_iter.valid(); ++pred_iter)
00460 o << ", " << pred_iter.current_key().name_ref()
00461 << ":" << pred_iter.current_data().tag();
00462 }
00463
00464 o << "}";
00465 o << ", users={";
00466
00467 Iterator<SSAFullRangeData> user_iter = users;
00468
00469 if (user_iter.valid()) {
00470 o << user_iter.current().stmt().tag();
00471 ++user_iter;
00472
00473 for ( ; user_iter.valid(); ++user_iter)
00474 o << ", " << user_iter.current().stmt().tag();
00475 }
00476
00477 o << "}";
00478 o << "]";
00479 }
00480
00481
00482
00483
00484 int
00485 SSAFullRangeData::structures_OK() const
00486 {
00487 return (_stmt_ref->structures_OK()
00488 && arg_ranges_or_data.structures_OK());
00489 }
00490