Polaris: PropConstMap.cc Source File

PropConstMap.cc

Go to the documentation of this file.
00001 ///
00002 ///
00003 /// \file PropConstMap.cc
00004 ///
00005 #include "../macros.h"
00006 
00007 #include "PropConstMap.h"
00008 
00009 /// Template instantiations:
00010 
00011 template class Array<PropConstElem>;
00012 
00013 
00014 
00015 void
00016 _collect_uses(const Expression &expr, IntSet &use_set,
00017           const Map<Symbol, IntElem> &candidates)
00018 {
00019     if (expr.op() == ID_OP) {
00020     const IntElem *elem = candidates.find_ref(expr.symbol());
00021 
00022     if (elem)
00023         use_set.ins(elem->value());
00024     }
00025     else {
00026     Iterator<Expression> iter = expr.arg_list();
00027 
00028     for ( ; iter.valid(); ++iter)
00029         _collect_uses(iter.current(), use_set, candidates);
00030     }
00031 }
00032 
00033 PropConstValue::PropConstValue(const Expression &expr, const Statement &stmt,
00034                    int stmt_toporder,
00035                    const Map<Symbol,IntElem> &candidates)
00036 {
00037     _expr = expr.clone();
00038     _stmt = &stmt;
00039     _toporder = stmt_toporder;
00040 
00041     _collect_uses(expr, _use_set, candidates);
00042 }
00043 
00044 PropConstValue::PropConstValue(const PropConstValue &other)
00045 {
00046     _expr = other.expr().clone();
00047     _stmt = other._stmt;
00048     _toporder = other._toporder;
00049     _use_set = other._use_set;
00050 }
00051 
00052 PropConstValue::~PropConstValue()
00053 {
00054     delete _expr;
00055 }
00056 
00057 Listable *
00058 PropConstValue::listable_clone() const
00059 {
00060     return new PropConstValue(*this);
00061 }
00062 
00063 void
00064 PropConstValue::print(ostream &o) const
00065 {
00066     o << "[expr=" << *_expr;
00067     o << ", stmt=" << _stmt->tag();
00068     o << ", toporder=" << _toporder;
00069     o << ", use_set=" << _use_set;
00070     o << "]";
00071 }
00072 
00073 int
00074 PropConstValue::structures_OK() const
00075 {
00076     return (_expr->structures_OK()
00077         && _stmt->structures_OK()
00078         && _use_set.structures_OK());
00079 }
00080 
00081 
00082 
00083 PropConstElem::PropConstElem()
00084 {
00085     _last_mod = 0;
00086     _const_val = 0;
00087 }
00088 
00089 PropConstElem::PropConstElem(const PropConstElem &other)
00090 {
00091     *this = other;
00092 }
00093 
00094 PropConstElem::~PropConstElem()
00095 {
00096     /// ...  Nothing to do
00097 }
00098 
00099 const Expression &
00100 PropConstElem::expr() const
00101 {
00102     p_assert(_const_val, "Variable is not constant.");
00103     return _const_val->expr();
00104 }
00105 
00106 const IntSet &
00107 PropConstElem::use_set() const
00108 {
00109     p_assert(_const_val, "Variable is not constant.");
00110     return _const_val->use_set();
00111 }
00112 
00113 const PropConstValue &
00114 PropConstElem::const_val() const
00115 {
00116     p_assert(_const_val, "Variable is not constant.");
00117     return *_const_val;
00118 }    
00119 
00120 void
00121 PropConstElem::constant(const PropConstValue &const_val)
00122 {
00123     p_assert(state() == MAY_BE_CONST,
00124          "Can only change MAY_BE_CONST objects into CONST objects.");
00125     _last_mod = &const_val.stmt();
00126     _const_val = &const_val;
00127 }
00128 
00129 void
00130 PropConstElem::non_const(const Statement &stmt)
00131 {
00132     _last_mod = &stmt;
00133     _const_val = 0;
00134 }
00135 
00136 void
00137 PropConstElem::intersect(const PropConstElem &other,
00138              const Statement &curr_stmt)
00139 {
00140     CONST_STATE my_state = state();
00141     CONST_STATE other_state = other.state();
00142 
00143     if (my_state == MAY_BE_CONST)
00144     *this = other;
00145     else if (other_state == MAY_BE_CONST)
00146     ; // Do nothing
00147     else if (my_state == NON_CONST || other_state == NON_CONST)
00148     non_const(*_last_mod);
00149     else if (my_state == CONST && other_state == CONST) {
00150     /// ...  Check if the two constants conflict
00151 
00152     if (! _const_equal(other))
00153         non_const(curr_stmt);
00154     else if (_const_val->stmt_toporder() > other._const_val->stmt_toporder())
00155         _const_val = other._const_val;
00156     }
00157     else
00158     p_abort("Internal Error: PropConstElem has a bad state.");
00159 
00160     if (_last_mod != other._last_mod)
00161     _last_mod = &curr_stmt;
00162 }
00163 
00164 Boolean
00165 PropConstElem::_const_equal(const PropConstElem &other) const
00166 {
00167     /// ...  Return false if the expressions are unequal constants.
00168 
00169     return (! _const_val
00170         || ! other._const_val
00171         || _const_val == other._const_val
00172         || ((CASTAWAY(Expression &) expr())
00173         == (CASTAWAY(Expression &) other.expr())));
00174 }
00175 
00176 int
00177 PropConstElem::operator == (const PropConstElem &other) const
00178 {
00179     return (state() == other.state()
00180         && _const_equal(other)
00181         && _last_mod == other._last_mod);
00182 }
00183 
00184 PropConstElem &
00185 PropConstElem::operator = (const PropConstElem &other)
00186 {
00187     _last_mod = other._last_mod;
00188     _const_val = other._const_val;
00189     return *this;
00190 }
00191 
00192 ostream &
00193 operator << (ostream &o, const PropConstElem &pcc)
00194 {
00195     pcc.print(o);
00196     return o;
00197 }
00198 
00199 void
00200 PropConstElem::print(ostream &o) const
00201 {
00202     o << "<";
00203 
00204     switch (state()) {
00205     case MAY_BE_CONST:
00206     o << "undef";
00207     break;
00208 
00209     case CONST:
00210     o << _last_mod->tag() << ":" << expr();
00211     break;
00212 
00213     case NON_CONST:
00214     o << _last_mod->tag() << ":?";
00215     break;
00216 
00217     default:
00218     o << "error";
00219     break;          
00220     }
00221 
00222     o << ">";
00223 }
00224 
00225 int
00226 PropConstElem::structures_OK() const
00227 {
00228     if (! _last_mod && _const_val) {
00229     cerr << "\n\nError: PropConstElem:structures_OK: Is in an invalid state.\n";
00230     return 0;
00231     }
00232 
00233     return 1;
00234 }
00235 
00236 
00237 
00238 PropConstIntMap::PropConstIntMap(int num_consts,
00239                  const Array<Symbol *> &tag_to_candidate)
00240 : _const_map(num_consts), _const_elems(num_consts), _undefined_elems(num_consts)
00241 {
00242     _tag_to_candidate = &tag_to_candidate;
00243 
00244     for (int i = 0; i < num_consts; ++i) {
00245     _undefined_elems.ins(i);
00246     _const_map[i] = -9999;
00247     }
00248 }
00249 
00250 PropConstIntMap::PropConstIntMap(const PropConstIntMap &other)
00251 : _const_map(other._const_map), _const_elems(other._const_elems),
00252 _undefined_elems(other._undefined_elems)
00253 {
00254     _tag_to_candidate = other._tag_to_candidate;
00255 }
00256 
00257 PropConstIntMap::~PropConstIntMap()
00258 {
00259 }
00260 
00261 CONST_STATE
00262 PropConstIntMap::state(int sym_tag) const
00263 {
00264     if (_const_elems[sym_tag])
00265     return CONST;
00266     else if (_undefined_elems[sym_tag])
00267     return MAY_BE_CONST;
00268     else
00269     return NON_CONST;
00270 }
00271 
00272 void
00273 PropConstIntMap::constant(int sym_tag, int const_val)
00274 {
00275     _const_elems.ins(sym_tag);
00276     _undefined_elems.del(sym_tag);
00277     _const_map[sym_tag] = const_val;
00278 }
00279 
00280 void
00281 PropConstIntMap::non_const(int sym_tag)
00282 {
00283     _const_elems.del(sym_tag);
00284     _undefined_elems.del(sym_tag);
00285     _const_map[sym_tag] = -9999;
00286 }
00287 
00288 int
00289 PropConstIntMap::int_const_val(int sym_tag) const
00290 {
00291     p_assert(_const_elems[sym_tag], "Variable is not a constant.");
00292 
00293     return _const_map[sym_tag];
00294 }
00295 
00296 void
00297 PropConstIntMap::all_non_const()
00298 {
00299     _const_elems.clear();
00300     _undefined_elems.clear();
00301 
00302     for (int i = 0; i < _const_map.entries(); ++i)
00303     _const_map[i] = -9999;
00304 }
00305 
00306 void
00307 PropConstIntMap::intersect(const PropConstIntMap &other)
00308 {
00309     for (int sym_tag = 0; sym_tag < _const_map.entries(); ++sym_tag) {
00310     if (other._undefined_elems[sym_tag])
00311         ; /// ...  Nothing to do
00312     else if (_undefined_elems[sym_tag]) {
00313         if (other._const_elems[sym_tag])
00314         constant(sym_tag, other._const_map[sym_tag]);
00315         else
00316         non_const(sym_tag);
00317     }
00318     else if (! _const_elems[sym_tag])
00319         ; /// ...  Nothing to do
00320     else if (! other._const_elems[sym_tag]
00321          || _const_map[sym_tag] != other._const_map[sym_tag])
00322         non_const(sym_tag);
00323     }
00324 }
00325 
00326 PropConstIntMap &
00327 PropConstIntMap::operator = (const PropConstIntMap &other)
00328 {
00329     if (this != &other) {
00330     _const_map = other._const_map;
00331     _const_elems = other._const_elems;
00332     _undefined_elems = other._undefined_elems;
00333     _tag_to_candidate = other._tag_to_candidate;
00334     }
00335     return *this;
00336 }
00337 
00338 int
00339 PropConstIntMap::operator == (const PropConstIntMap &other) const
00340 {
00341     if (_const_map.entries() != other._const_map.entries()
00342     || _const_elems != other._const_elems
00343     || _undefined_elems != other._undefined_elems)
00344 
00345     return 0;
00346 
00347     for (int sym_tag = _const_elems.first();
00348      sym_tag != -1;
00349      sym_tag = _const_elems.next(sym_tag))
00350     if (_const_map[sym_tag] != other._const_map[sym_tag])
00351         return 0;
00352 
00353     return 1;
00354 }
00355 
00356 ostream &
00357 operator << (ostream &o, const PropConstIntMap &pcm)
00358 {
00359     pcm.print(o);
00360     return o;
00361 }
00362 
00363 void
00364 PropConstIntMap::print(ostream &o) const
00365 {
00366     o << "[_const_map=";
00367     _const_map.print(o);
00368     o << ", _const_elems=";
00369     _const_elems.print(o);
00370     o << ", _undefined_elems=";
00371     _undefined_elems.print(o);
00372     o << "]";
00373 }
00374 
00375 void
00376 PropConstIntMap::pretty_print(ostream &o) const
00377 {
00378     const int max_elems = 6;    /// ...  Max. number of constants per line
00379     
00380     int elems_on_line = max_elems;
00381 
00382     for (int sym_tag = 0; sym_tag < _const_map.entries(); sym_tag++) {
00383     if (++elems_on_line >= max_elems) {
00384         o << "\n    ";
00385         elems_on_line = 0;
00386     }
00387     
00388     o << (*_tag_to_candidate)[sym_tag]->name_ref() << ":";
00389 
00390     switch (state(sym_tag)) {
00391     case MAY_BE_CONST:
00392         o << "undef";
00393         break;
00394         
00395     case CONST:
00396         o << _const_map[sym_tag];
00397         break;
00398         
00399     case NON_CONST:
00400         o << "?";
00401         break;
00402         
00403     default:
00404         o << "error";
00405         break;          
00406     }
00407 
00408     o << ", ";
00409     }
00410 }
00411 
00412 int
00413 PropConstIntMap::structures_OK() const
00414 {
00415     if (! _const_map.structures_OK()
00416     || ! _const_elems.structures_OK()
00417     || ! _undefined_elems.structures_OK())
00418     return 0;
00419 
00420     IntSet inter_elems = _const_elems & _undefined_elems;
00421 
00422     if (inter_elems.entries()) {
00423     cerr << "PropConstIntMap::structures_OK() found a variable marked as\n";
00424     cerr << "constant and undefined.";
00425 
00426     return 0;
00427     }
00428 
00429     return 1;
00430 }
00431 
00432 
00433 
00434 PropConstMap::PropConstMap(int num_consts,
00435                const Array<Symbol *> &tag_to_candidate)
00436 : _const_map(num_consts), _int_const_map(num_consts, tag_to_candidate)
00437 {
00438     _tag_to_candidate = &tag_to_candidate;
00439 }
00440 
00441 PropConstMap::PropConstMap(const PropConstMap &other)
00442 : _const_map(other._const_map), _int_const_map(other._int_const_map)
00443 {
00444     _tag_to_candidate = other._tag_to_candidate;
00445 }
00446 
00447 PropConstMap::~PropConstMap()
00448 {
00449     /// ...  Nothing to do
00450 }
00451 
00452 void
00453 PropConstMap::all_non_const(const Statement &stmt)
00454 {
00455     _int_const_map.all_non_const();
00456 
00457     for (int sym_tag = 0; sym_tag < _const_map.entries(); ++sym_tag)
00458     _const_map[sym_tag].non_const(stmt);
00459 }
00460 
00461 void
00462 PropConstMap::intersect(const PropConstMap &other, const Statement &stmt)
00463 {
00464     _int_const_map.intersect(other._int_const_map);
00465 
00466     for (int sym_tag = 0; sym_tag < _const_map.entries(); ++sym_tag)
00467     _const_map[sym_tag].intersect(other._const_map[sym_tag], stmt);
00468 }
00469 
00470 PropConstMap &
00471 PropConstMap::operator = (const PropConstMap &other)
00472 {
00473     if (this != &other) {
00474     _int_const_map = other._int_const_map;
00475     _const_map = other._const_map;
00476     _tag_to_candidate = other._tag_to_candidate;
00477     }
00478     return *this;
00479 }
00480 
00481 int
00482 PropConstMap::operator == (const PropConstMap &other) const
00483 {
00484     if (_int_const_map != other._int_const_map)
00485     return 0;
00486 
00487     if (_const_map.entries() != other._const_map.entries())
00488     return 0;
00489 
00490     for (int sym_tag = 0; sym_tag < _const_map.entries(); ++sym_tag)
00491     if (_const_map[sym_tag] != other._const_map[sym_tag])
00492         return 0;
00493 
00494     return 1;
00495 }
00496 
00497 ostream &
00498 operator << (ostream &o, const PropConstMap &pcm)
00499 {
00500     pcm.print(o);
00501     return o;
00502 }
00503 
00504 void
00505 PropConstMap::print(ostream &o) const
00506 {
00507     o << "[int_const_map=";
00508     _int_const_map.print(o);
00509     o << ", const_map=";
00510     _const_map.print(o);
00511     o << "]";
00512 }
00513 
00514 void
00515 PropConstMap::pretty_print(ostream &o) const
00516 {
00517     _int_const_map.pretty_print(o);
00518 
00519     const int max_elems = 4;    /// ...  Max. number of constants per line
00520     
00521     int elems_on_line = max_elems;
00522 
00523     for (int sym_tag = 0; sym_tag < _const_map.entries(); sym_tag++) {
00524     if (++elems_on_line >= max_elems) {
00525         o << "\n    ";
00526         elems_on_line = 0;
00527     }
00528     
00529     o << (*_tag_to_candidate)[sym_tag]->name_ref() << ":"
00530         << _const_map[sym_tag] << ", ";
00531     }
00532 }
00533 
00534 int
00535 PropConstMap::structures_OK() const
00536 {
00537     if (! _int_const_map.structures_OK() || ! _const_map.structures_OK())
00538     return 0;
00539 
00540     for (int sym_tag = 0; sym_tag < _const_map.entries(); sym_tag++)
00541     if (! _const_map[sym_tag].structures_OK())
00542         return 0;
00543 
00544     return 1;
00545 }
00546 
 © 1995-2005 University of Illinois, Urbana-Champaign. All rights reserved.  Fri Mar 25 23:06:02 2005