Polaris: GSAControlRangeData.cc Source File

GSAControlRangeData.cc

Go to the documentation of this file.
00001 ///
00002 ///
00003 /// \file GSAControlRangeData.cc
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 "GSAControlRangeData.h"
00012 #include "RangeExpr.h"
00013 #include "range_util.h"
00014 
00015 /// Template instantiations
00016 
00017 template class TypedBaseMap<Statement,GSAControlRangeData>;
00018 template class ProtoMap<Statement,GSAControlRangeData>;
00019 template class Map<Statement,GSAControlRangeData>;
00020 template ostream & operator << (ostream &,
00021                                 const Map<Statement,GSAControlRangeData> &);
00022 template class KeyIterator<Statement,GSAControlRangeData>;
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 /// Constructors
00033 
00034 GSAControlRangeData::GSAControlRangeData(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 GSAControlRangeData::GSAControlRangeData(const GSAControlRangeData &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 /// Destructor
00062 
00063 GSAControlRangeData::~GSAControlRangeData()
00064 {
00065 }
00066 
00067 
00068 /// has_asserts
00069 ///   Return true if the given statement has assertions.
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 /// compute_icdom_ref
00085 ///   Compute my immediate control dominator and its successor statement
00086 ///   which dominates me.
00087 
00088 void
00089 GSAControlRangeData::_compute_icdom_ref() 
00090 {
00091     GSAControlRangeData *dom = _idom_ref;
00092     const Statement *succ = 0;
00093     
00094     if (dom) {
00095     const Statement &dom_stmt = dom->stmt();
00096     succ = &stmt();
00097 
00098     /// ...  My immediate dominator is my immediate control dominator only if:
00099     /// ...    - My immediate dominator has ASSERT assertions.
00100         /// ...    - My Immediate dominator is a DO or IF statement, where:
00101         /// ...        - I'm a control flow successor of that DO or IF statement.
00102         /// ...        - I'm not the destination of a DO loop exit.
00103         /// ...        - I'm not the ENDIF of an IF () THEN ... ENDIF statement,
00104         /// ...          where the flow control of the THEN case will reach me.
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 /// add_asserts_to_ranges
00129 ///   Add any relation assertions for the given statement to
00130 ///   the given set of ranges.
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 /// get_local_ranges
00172 ///   Return the set of new control ranges for the control-flow edge from
00173 ///   this statement to the given statement.
00174 
00175 Map<Symbol, Set<Expression> > &
00176 GSAControlRangeData::_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 GSAControlRangeData::_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 /// get_succ_range_ref
00251 ///   Get the control range associated with the given variable and exiting
00252 ///   control-flow edge whose sink is the given statement.
00253 
00254 Expression *
00255 GSAControlRangeData::_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     /// ...  This assignment must be here to prevent an infinite recursion
00271     /// ...  originating from one the the intersect_ranges() operations
00272     /// ...  below.
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 /// get_range_ref
00315 ///   Get the control range associated with the given variable.
00316 
00317 Expression *
00318 GSAControlRangeData::get_range_ref(const Symbol &var)
00319 {
00320     GSAControlRangeData *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 /// num_computed_ranges
00330 
00331 int
00332 GSAControlRangeData::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 /// range_vars
00345 
00346 RefSet<Symbol> *
00347 GSAControlRangeData::range_vars()
00348 {
00349     RefSet<Symbol> *my_range_vars = 0;
00350 
00351     GSAControlRangeData *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 /// clear
00370 
00371 void
00372 GSAControlRangeData::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 /// clear
00384 
00385 void
00386 GSAControlRangeData::clear_ranges()
00387 {
00388     _om_ref = 0;
00389     _out_ranges.clear();
00390 }
00391 
00392 
00393 /// listable_clone
00394 
00395 Listable *
00396 GSAControlRangeData::listable_clone() const
00397 {
00398     return new GSAControlRangeData(*this);
00399 }
00400 
00401 
00402 /// print_data_ref
00403 
00404 static void
00405 _print_data_ref(ostream &o, const GSAControlRangeData *data)
00406 {
00407     if (data)
00408     o << data->stmt().tag();
00409     else
00410     o << "NULL";
00411 }
00412 
00413 
00414 /// print
00415 
00416 void
00417 GSAControlRangeData::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 /// structures_OK
00477 
00478 int
00479 GSAControlRangeData::structures_OK() const
00480 {
00481     return 1;
00482 }
00483 
 © 1995-2005 University of Illinois, Urbana-Champaign. All rights reserved.  Fri Mar 25 23:05:53 2005