00001
00002
00003
00004
00005 #include "Collection/Iterator.h"
00006 #include "Collection/KeyIterator.h"
00007 #include "utilities/expression_util.h"
00008 #include "Symtab.h"
00009
00010 #include "RangeAccessor.h"
00011 #include "SSAControlRangeData.h"
00012 #include "RangeExpr.h"
00013 #include "range_util.h"
00014
00015
00016
00017 template class TypedBaseMap<Statement,SSAControlRangeData>;
00018 template class ProtoMap<Statement,SSAControlRangeData>;
00019 template class Map<Statement,SSAControlRangeData>;
00020 template ostream & operator << (ostream &,
00021 const Map<Statement,SSAControlRangeData> &);
00022 template class KeyIterator<Statement,SSAControlRangeData>;
00023
00024 template class TypedBaseMap<Statement,Map<Symbol, Set<Expression> > >;
00025 template class ProtoMap<Statement,Map<Symbol, Set<Expression> > >;
00026 template class Map<Statement,Map<Symbol, Set<Expression> > >;
00027 template ostream & operator << (ostream &,
00028 const Map<Statement,Map<Symbol, Set<Expression> > > &);
00029 template class KeyIterator<Statement,Map<Symbol, Set<Expression> > >;
00030
00031
00032
00033
00034 SSAControlRangeData::SSAControlRangeData(const Statement &stmt,
00035 RangeDict &range_dict,
00036 ExprSet &range_values)
00037 {
00038 _range_dict_ref = &range_dict;
00039 _range_values_ref = &range_values;
00040 _stmt_ref = &stmt;
00041 _idom_ref = 0;
00042
00043 clear();
00044 }
00045
00046 SSAControlRangeData::SSAControlRangeData(const SSAControlRangeData &other)
00047 {
00048 _range_dict_ref = other._range_dict_ref;
00049 _range_values_ref = other._range_values_ref;
00050 _stmt_ref = other._stmt_ref;
00051 _idom_ref = other._idom_ref;
00052 _icdom_ref = other._icdom_ref;
00053 _icdom_succ_ref = other._icdom_succ_ref;
00054 _icdom_valid = other._icdom_valid;
00055 _om_ref = other._om_ref;
00056 _local_ranges = other._local_ranges;
00057 _out_ranges = other._out_ranges;
00058 }
00059
00060
00061
00062
00063 SSAControlRangeData::~SSAControlRangeData()
00064 {
00065 }
00066
00067
00068
00069
00070
00071 static bool
00072 _has_asserts(const Statement &stmt)
00073 {
00074 Iterator<Assertion> assert_iter = stmt.assertions();
00075
00076 for ( ; assert_iter.valid(); ++assert_iter)
00077 if (assert_iter.current().type() == AS_RELATION)
00078 return true;
00079
00080 return false;
00081 }
00082
00083
00084
00085
00086
00087
00088 void
00089 SSAControlRangeData::_compute_icdom_ref()
00090 {
00091 SSAControlRangeData *dom = _idom_ref;
00092 const Statement *succ = 0;
00093
00094 if (dom) {
00095 const Statement &dom_stmt = dom->stmt();
00096 succ = &stmt();
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 if (! _has_asserts(dom_stmt)
00107 && ((dom_stmt.stmt_class() != IF_STMT
00108 && dom_stmt.stmt_class() != ELSEIF_STMT
00109 && dom_stmt.stmt_class() != DO_STMT)
00110 || ! dom_stmt.succ().member(* CASTAWAY(Statement *) succ)
00111 || (dom_stmt.stmt_class() == DO_STMT
00112 && succ->prev_ref()->stmt_class() == ENDDO_STMT)
00113 || (succ->stmt_class() == ENDIF_STMT
00114 && (succ->prev_ref()->stmt_class() != IMPLIED_GOTO_STMT
00115 || succ->prev_ref()->pred().entries() > 0)))){
00116
00117 succ = dom->icdom_succ_ref();
00118 dom = dom->icdom_ref();
00119 }
00120 }
00121
00122 _icdom_ref = dom;
00123 _icdom_succ_ref = succ;
00124 _icdom_valid = true;
00125 }
00126
00127
00128
00129
00130
00131
00132 static void
00133 _add_asserts_to_ranges(Map<Symbol, Set<Expression> > &var_ranges,
00134 const Statement &stmt)
00135 {
00136 Iterator<Assertion> assert_iter = stmt.assertions();
00137
00138 for ( ; assert_iter.valid(); ++assert_iter) {
00139 const Assertion &assert = assert_iter.current();
00140
00141 if (assert.type() == AS_RELATION) {
00142 Iterator<Expression> arg_iter = assert.arg_list_guarded();
00143
00144 for ( ; arg_iter.valid(); ++arg_iter) {
00145 Map<Symbol, Set<Expression> > *assert_ranges
00146 = extract_ranges(arg_iter.current(), false);
00147
00148 KeyIterator<Symbol, Set<Expression> > range_iter = *assert_ranges;
00149
00150 for ( ; range_iter.valid(); ++range_iter) {
00151 Set<Expression> *ranges = var_ranges.find_ref(range_iter.current_key());
00152
00153 if (! ranges) {
00154 ranges = new Set<Expression>;
00155 var_ranges.ins(range_iter.current_key(), ranges);
00156 }
00157
00158 Mutator<Expression> elem_iter = range_iter.current_data();
00159
00160 for ( ; elem_iter.valid(); ++elem_iter)
00161 ranges->ins(elem_iter.grab());
00162 }
00163
00164 delete assert_ranges;
00165 }
00166 }
00167 }
00168 }
00169
00170
00171
00172
00173
00174
00175 Map<Symbol, Set<Expression> > &
00176 SSAControlRangeData::_get_local_ranges(const Statement &succ_stmt)
00177 {
00178 Map<Symbol, Set<Expression> > *succ_local_ranges = _local_ranges.find_ref(succ_stmt);
00179
00180 if (! succ_local_ranges) {
00181 if (! contains_func_call(stmt())){
00182 if ((stmt().stmt_class() == IF_STMT
00183 || stmt().stmt_class() == ELSEIF_STMT)
00184 && stmt().next_ref() != stmt().follow_ref()) {
00185
00186 if (&succ_stmt == stmt().next_ref())
00187 succ_local_ranges = extract_ranges(stmt().expr(), false);
00188 else
00189 succ_local_ranges = extract_ranges(stmt().expr(), true);
00190 }
00191 else if (stmt().stmt_class() == DO_STMT
00192 && stmt().index().type().data_type() == INTEGER_TYPE
00193 && stmt().next_ref() != stmt().follow_ref()
00194 && &succ_stmt == stmt().next_ref()) {
00195 RangeAccessor accessor(*_range_dict_ref, stmt());
00196
00197 EXPR_SIGN step_sign = accessor.sign(stmt().step());
00198
00199 if (step_sign != POS_NEG_EXPR) {
00200 Expression *bound_cond, *index_range;
00201
00202 if (step_sign == POS_EXPR) {
00203 bound_cond = le(stmt().init().clone(),
00204 stmt().limit().clone());
00205 index_range = new RangeExpr(stmt().init().clone(),
00206 stmt().limit().clone());
00207 }
00208 else {
00209 bound_cond = ge(stmt().init().clone(),
00210 stmt().limit().clone());
00211 index_range = new RangeExpr(stmt().limit().clone(),
00212 stmt().init().clone());
00213 }
00214
00215 succ_local_ranges = extract_ranges(*bound_cond, false);
00216 delete bound_cond;
00217 index_range = simplify(index_range);
00218
00219 const Symbol &index = stmt().index().symbol();
00220 Set<Expression> *index_ranges = succ_local_ranges->find_ref(index);
00221
00222 if (! index_ranges) {
00223 index_ranges = new Set<Expression>;
00224 succ_local_ranges->ins(index, index_ranges);
00225 }
00226
00227 index_ranges->ins(index_range);
00228 }
00229 }
00230 }
00231
00232 if (! succ_local_ranges)
00233 succ_local_ranges = new Map<Symbol, Set<Expression> >;
00234
00235 _add_asserts_to_ranges(*succ_local_ranges, stmt());
00236 _local_ranges.ins(succ_stmt, succ_local_ranges);
00237 }
00238
00239 return *succ_local_ranges;
00240 }
00241
00242 Set<Expression> *
00243 SSAControlRangeData::_get_local_ranges(const Symbol &var,
00244 const Statement &succ_stmt)
00245 {
00246 return _get_local_ranges(succ_stmt).find_ref(var);
00247 }
00248
00249
00250
00251
00252
00253
00254 Expression *
00255 SSAControlRangeData::_get_succ_range_ref(const Symbol &var,
00256 const Statement &succ_stmt)
00257 {
00258 RefMap<Symbol, Expression> *edge_ranges = _out_ranges.find_ref(succ_stmt);
00259
00260 if (! edge_ranges) {
00261 edge_ranges = new RefMap<Symbol, Expression>;
00262 _out_ranges.ins(succ_stmt, edge_ranges);
00263 }
00264
00265 Expression *range = edge_ranges->find_ref(var);
00266
00267 if (! range) {
00268 range = get_range_ref(var);
00269
00270
00271
00272
00273
00274 if (range)
00275 edge_ranges->ins(var, *range);
00276 else {
00277 if (! _om_ref)
00278 _om_ref = &_range_values_ref->ins(omega());
00279
00280 edge_ranges->ins(var, *_om_ref);
00281 }
00282
00283 Set<Expression> *local_ranges_ref = _get_local_ranges(var, succ_stmt);
00284
00285 if (local_ranges_ref) {
00286 RangeAccessor accessor(*_range_dict_ref, stmt());
00287 Iterator <Expression> local_range_iter = *local_ranges_ref;
00288 Expression *local_range = local_range_iter.current().clone();
00289 ++local_range_iter;
00290
00291 for ( ; local_range_iter.valid(); ++local_range_iter) {
00292 Expression *new_local_range = intersect_ranges(local_range,
00293 accessor,
00294 &local_range_iter.current(),
00295 accessor);
00296 delete local_range;
00297 local_range = new_local_range;
00298 }
00299
00300 Expression *final_range = intersect_ranges(range, accessor, local_range, accessor);
00301 delete local_range;
00302 range = (Expression *) &_range_values_ref->ins(final_range);
00303 edge_ranges->ins(var, *range);
00304 }
00305 }
00306
00307 if (range && range->op() == OMEGA_OP)
00308 range = 0;
00309
00310 return range;
00311 }
00312
00313
00314
00315
00316
00317 Expression *
00318 SSAControlRangeData::get_range_ref(const Symbol &var)
00319 {
00320 SSAControlRangeData *icdom = icdom_ref();
00321
00322 if (! icdom)
00323 return 0;
00324
00325 return icdom->_get_succ_range_ref(var, *icdom_succ_ref());
00326 }
00327
00328
00329
00330
00331 int
00332 SSAControlRangeData::num_computed_ranges() const
00333 {
00334 int num_ranges = 0;
00335 KeyIterator<Statement, RefMap<Symbol, Expression> > iter = _out_ranges;
00336
00337 for ( ; iter.valid(); ++iter)
00338 num_ranges += iter.current_data().entries();
00339
00340 return num_ranges;
00341 }
00342
00343
00344
00345
00346 RefSet<Symbol> *
00347 SSAControlRangeData::range_vars()
00348 {
00349 RefSet<Symbol> *my_range_vars = 0;
00350
00351 SSAControlRangeData *icdom = icdom_ref();
00352
00353 if (icdom) {
00354 my_range_vars = icdom->range_vars();
00355
00356 Map<Symbol, Set<Expression> > &local_ranges = icdom->_get_local_ranges(*icdom_succ_ref());
00357 KeyIterator<Symbol, Set<Expression> > iter = local_ranges;
00358
00359 for ( ; iter.valid(); ++iter)
00360 my_range_vars->ins(iter.current_key());
00361 }
00362 else
00363 my_range_vars = new RefSet<Symbol>;
00364
00365 return my_range_vars;
00366 }
00367
00368
00369
00370
00371 void
00372 SSAControlRangeData::clear()
00373 {
00374 _icdom_ref = 0;
00375 _icdom_succ_ref = 0;
00376 _icdom_valid = false;
00377 _om_ref = 0;
00378 _local_ranges.clear();
00379 _out_ranges.clear();
00380 }
00381
00382
00383
00384
00385 void
00386 SSAControlRangeData::clear_ranges()
00387 {
00388 _om_ref = 0;
00389 _out_ranges.clear();
00390 }
00391
00392
00393
00394
00395 Listable *
00396 SSAControlRangeData::listable_clone() const
00397 {
00398 return new SSAControlRangeData(*this);
00399 }
00400
00401
00402
00403
00404 static void
00405 _print_data_ref(ostream &o, const SSAControlRangeData *data)
00406 {
00407 if (data)
00408 o << data->stmt().tag();
00409 else
00410 o << "NULL";
00411 }
00412
00413
00414
00415
00416 void
00417 SSAControlRangeData::print(ostream &o) const
00418 {
00419 o << "[";
00420 o << "stmt=" << stmt().tag();
00421 o << ", idom_ref=";
00422 _print_data_ref(o, _idom_ref);
00423 o << ", icdom_ref=";
00424
00425 if (_icdom_valid)
00426 _print_data_ref(o, _icdom_ref);
00427 else
00428 o << "???";
00429
00430 o << ", ipdom_succ_ref=";
00431
00432 if (_icdom_valid)
00433 if (_icdom_succ_ref)
00434 o << _icdom_succ_ref->tag();
00435 else
00436 o << "NULL";
00437 else
00438 o << "???";
00439
00440 o << ", local_ranges={";
00441 KeyIterator<Statement, Map<Symbol, Set<Expression> > > local_succ_iter = _local_ranges;
00442
00443 for ( ; local_succ_iter.valid(); ++local_succ_iter) {
00444 o << ", " << local_succ_iter.current_key().tag() << ":{";
00445 KeyIterator<Symbol, Set<Expression> > local_var_iter = local_succ_iter.current_data();
00446
00447 for ( ; local_var_iter.valid(); ++local_var_iter)
00448 o << ", " << local_var_iter.current_key().name_ref() << ":"
00449 << local_var_iter.current_data() << ", ";
00450
00451 o << "}, ";
00452 }
00453
00454 o << "}";
00455 o << ", out_ranges={";
00456 KeyIterator<Statement, RefMap<Symbol, Expression> > out_succ_iter = _out_ranges;
00457
00458 for ( ; out_succ_iter.valid(); ++out_succ_iter) {
00459 o << out_succ_iter.current_key().tag() << ":{";
00460 KeyIterator<Symbol, Expression> out_var_iter = out_succ_iter.current_data();
00461
00462 for ( ; out_var_iter.valid(); ++out_var_iter) {
00463 pretty_print_range(o, out_var_iter.current_data(),
00464 out_var_iter.current_key());
00465 o << ", ";
00466 }
00467
00468 o << "}, ";
00469 }
00470
00471 o << "}";
00472 o << "]";
00473 }
00474
00475
00476
00477
00478 int
00479 SSAControlRangeData::structures_OK() const
00480 {
00481 return 1;
00482 }