Polaris: PropCtrlRangeWS.cc Source File

PropCtrlRangeWS.cc

Go to the documentation of this file.
00001 ///
00002 ///
00003 /// \file PropCtrlRangeWS.cc
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 /// add_to_mod_set
00016 ///   Add the given set of variables to my mod_set.
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     /// ...  Also place any aliased variables in the set.
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 /// add_asserts_to_ranges
00051 ///   Add any ranges derived from ASSERT directives to my set of new
00052 ///   variable ranges.
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 /// Constructors
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     /// ...  _add_to_mod_set(stmt.act_refs());
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 /// Destructor
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 /// add_range_refs
00177 ///   Add references to the ranges of the second range map to the first
00178 ///   range map.
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 ///  _are_vars_in_expr
00204 ///    Return true if the given expression uses any of the variables in the
00205 ///    given set.
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 /// update_out_ranges
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 /// print_var_set
00263 ///   Print the given set of symbols.
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 /// print_range_map
00285 ///   Print the given map from variables to set of ranges
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 /// print
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 /// structures_OK
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
 © 1995-2005 University of Illinois, Urbana-Champaign. All rights reserved.  Fri Mar 25 23:06:03 2005