Polaris: GSAFullRangeData.cc Source File

GSAFullRangeData.cc

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