managed.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2003, Mike Van Emmerik
00003  *
00004  * See the file "LICENSE.TERMS" for information on usage and
00005  * redistribution of this file, and for a DISCLAIMER OF ALL
00006  * WARRANTIES.
00007  *
00008  */
00009 
00010 /*==============================================================================
00011  * FILE:       managed.cpp
00012  * OVERVIEW:   Implementation of "managed" classes such as StatementSet, which feature makeUnion etc
00013  *============================================================================*/
00014 
00015 /*
00016  * $Revision: 1.25 $    // 1.15.2.13
00017  *
00018  * 26 Aug 03 - Mike: Split off from statement.cpp
00019  * 21 Jun 05 - Mike: Added AssignSet
00020  */
00021 
00022 #include <sstream>
00023 
00024 #include "types.h"
00025 #include "managed.h"
00026 #include "statement.h"
00027 #include "exp.h"
00028 #include "log.h"
00029 #include "boomerang.h"
00030 #include "proc.h"
00031 
00032 extern char debug_buffer[];     // For prints functions
00033 
00034 
00035 std::ostream& operator<<(std::ostream& os, StatementSet* ss) {
00036     ss->print(os);
00037     return os;
00038 }
00039 
00040 std::ostream& operator<<(std::ostream& os, AssignSet* as) {
00041     as->print(os);
00042     return os;
00043 }
00044 
00045 std::ostream& operator<<(std::ostream& os, LocationSet* ls) {
00046     ls->print(os);
00047     return os;
00048 }
00049 
00050 
00051 //
00052 // StatementSet methods
00053 //
00054 
00055 // Make this set the union of itself and other
00056 void StatementSet::makeUnion(StatementSet& other) {
00057     std::set<Statement*>::iterator it;
00058     for (it = other.sset.begin(); it != other.sset.end(); it++) {
00059         sset.insert(*it);
00060     }
00061 }
00062 
00063 // Make this set the difference of itself and other
00064 void StatementSet::makeDiff(StatementSet& other) {
00065     std::set<Statement*>::iterator it;
00066     for (it = other.sset.begin(); it != other.sset.end(); it++) {
00067         sset.erase(*it);
00068     }
00069 }
00070 
00071 
00072 // Make this set the intersection of itself and other
00073 void StatementSet::makeIsect(StatementSet& other) {
00074     std::set<Statement*>::iterator it, ff;
00075     for (it = sset.begin(); it != sset.end(); it++) {
00076         ff = other.sset.find(*it);
00077         if (ff == other.sset.end())
00078             // Not in both sets
00079             sset.erase(it);
00080     }
00081 }
00082 
00083 // Check for the subset relation, i.e. are all my elements also in the set
00084 // other. Effectively (this intersect other) == this
00085 bool StatementSet::isSubSetOf(StatementSet& other) {
00086     std::set<Statement*>::iterator it, ff;
00087     for (it = sset.begin(); it != sset.end(); it++) {
00088         ff = other.sset.find(*it);
00089         if (ff == other.sset.end())
00090             return false;
00091     }
00092     return true;
00093 }
00094 
00095 
00096 // Remove this Statement. Return false if it was not found
00097 bool StatementSet::remove(Statement* s) {
00098     if (sset.find(s) != sset.end()) {
00099         sset.erase(s);
00100         return true;
00101     }
00102     return false;
00103 }
00104 
00105 // Search for s in this Statement set. Return true if found
00106 bool StatementSet::exists(Statement* s) {
00107     std::set<Statement*>::iterator it = sset.find(s);
00108     return (it != sset.end());
00109 }
00110 
00111 // Find a definition for loc in this Statement set. Return true if found
00112 bool StatementSet::definesLoc(Exp* loc) {
00113     for (iterator it = sset.begin(); it != sset.end(); it++) {
00114         if ((*it)->definesLoc(loc))
00115             return true;
00116     }
00117     return false;
00118 }
00119 
00120 // Print to a string, for debugging
00121 char* StatementSet::prints() {
00122     std::ostringstream ost;
00123     std::set<Statement*>::iterator it;
00124     for (it = sset.begin(); it != sset.end(); it++) {
00125         if (it != sset.begin()) ost << ",\t";
00126         ost << *it;
00127     }
00128     ost << "\n";
00129     strncpy(debug_buffer, ost.str().c_str(), DEBUG_BUFSIZE-1);
00130     debug_buffer[DEBUG_BUFSIZE-1] = '\0';
00131     return debug_buffer;
00132 }
00133 
00134 void StatementSet::dump() {
00135     print(std::cerr);
00136 }
00137 
00138 void StatementSet::print(std::ostream& os) {
00139     std::set<Statement*>::iterator it;
00140     for (it = sset.begin(); it != sset.end(); it++) {
00141         if (it != sset.begin()) os << ",\t";
00142         os << *it;
00143     }
00144     os << "\n";
00145 }
00146 
00147 // Print just the numbers to stream os
00148 void StatementSet::printNums(std::ostream& os) {
00149     os << std::dec;
00150     for (iterator it = sset.begin(); it != sset.end(); ) {
00151         if (*it)
00152             (*it)->printNum(os);
00153         else
00154             os << "-";              // Special case for NULL definition
00155         if (++it != sset.end())
00156             os << " ";
00157     }
00158 }
00159 
00160 bool StatementSet::operator<(const StatementSet& o) const {
00161     if (sset.size() < o.sset.size()) return true;
00162     if (sset.size() > o.sset.size()) return false;
00163     std::set<Statement*>::const_iterator it1, it2;
00164     for (it1 = sset.begin(), it2 = o.sset.begin(); it1 != sset.end();
00165       it1++, it2++) {
00166         if (*it1 < *it2) return true;
00167         if (*it1 > *it2) return false;
00168     }
00169     return false;
00170 }
00171 
00172 //
00173 // AssignSet methods
00174 //
00175 
00176 // Make this set the union of itself and other
00177 void AssignSet::makeUnion(AssignSet& other) {
00178     iterator it;
00179     for (it = other.aset.begin(); it != other.aset.end(); it++) {
00180         aset.insert(*it);
00181     }
00182 }
00183 
00184 // Make this set the difference of itself and other
00185 void AssignSet::makeDiff(AssignSet& other) {
00186     iterator it;
00187     for (it = other.aset.begin(); it != other.aset.end(); it++) {
00188         aset.erase(*it);
00189     }
00190 }
00191 
00192 
00193 // Make this set the intersection of itself and other
00194 void AssignSet::makeIsect(AssignSet& other) {
00195     iterator it, ff;
00196     for (it = aset.begin(); it != aset.end(); it++) {
00197         ff = other.aset.find(*it);
00198         if (ff == other.aset.end())
00199             // Not in both sets
00200             aset.erase(it);
00201     }
00202 }
00203 
00204 // Check for the subset relation, i.e. are all my elements also in the set
00205 // other. Effectively (this intersect other) == this
00206 bool AssignSet::isSubSetOf(AssignSet& other) {
00207     iterator it, ff;
00208     for (it = aset.begin(); it != aset.end(); it++) {
00209         ff = other.aset.find(*it);
00210         if (ff == other.aset.end())
00211             return false;
00212     }
00213     return true;
00214 }
00215 
00216 
00217 // Remove this Assign. Return false if it was not found
00218 bool AssignSet::remove(Assign* a) {
00219     if (aset.find(a) != aset.end()) {
00220         aset.erase(a);
00221         return true;
00222     }
00223     return false;
00224 }
00225 
00226 // Search for a in this Assign set. Return true if found
00227 bool AssignSet::exists(Assign* a) {
00228     iterator it = aset.find(a);
00229     return (it != aset.end());
00230 }
00231 
00232 // Find a definition for loc in this Assign set. Return true if found
00233 bool AssignSet::definesLoc(Exp* loc) {
00234     Assign* as = new Assign(loc, new Terminal(opWild));
00235     iterator ff = aset.find(as);
00236     return ff != aset.end();
00237 }
00238 
00239 // Find a definition for loc on the LHS in this Assign set. If found, return pointer to the Assign with that LHS
00240 Assign* AssignSet::lookupLoc(Exp* loc) {
00241     Assign* as = new Assign(loc, new Terminal(opWild));
00242     iterator ff = aset.find(as);
00243     if (ff == aset.end()) return NULL;
00244     return *ff;
00245 }
00246 
00247 // Print to a string, for debugging
00248 char* AssignSet::prints() {
00249     std::ostringstream ost;
00250     iterator it;
00251     for (it = aset.begin(); it != aset.end(); it++) {
00252         if (it != aset.begin()) ost << ",\t";
00253         ost << *it;
00254     }
00255     ost << "\n";
00256     strncpy(debug_buffer, ost.str().c_str(), DEBUG_BUFSIZE-1);
00257     debug_buffer[DEBUG_BUFSIZE-1] = '\0';
00258     return debug_buffer;
00259 }
00260 
00261 void AssignSet::dump() {
00262     print(std::cerr);
00263 }
00264 
00265 void AssignSet::print(std::ostream& os) {
00266     iterator it;
00267     for (it = aset.begin(); it != aset.end(); it++) {
00268         if (it != aset.begin()) os << ",\t";
00269         os << *it;
00270     }
00271     os << "\n";
00272 }
00273 
00274 // Print just the numbers to stream os
00275 void AssignSet::printNums(std::ostream& os) {
00276     os << std::dec;
00277     for (iterator it = aset.begin(); it != aset.end(); ) {
00278         if (*it)
00279             (*it)->printNum(os);
00280         else
00281             os << "-";              // Special case for NULL definition
00282         if (++it != aset.end())
00283             os << " ";
00284     }
00285 }
00286 
00287 bool AssignSet::operator<(const AssignSet& o) const {
00288     if (aset.size() < o.aset.size()) return true;
00289     if (aset.size() > o.aset.size()) return false;
00290     const_iterator it1, it2;
00291     for (it1 = aset.begin(), it2 = o.aset.begin(); it1 != aset.end();
00292       it1++, it2++) {
00293         if (*it1 < *it2) return true;
00294         if (*it1 > *it2) return false;
00295     }
00296     return false;
00297 }
00298 
00299 //
00300 // LocationSet methods
00301 //
00302 
00303 // Assignment operator
00304 LocationSet& LocationSet::operator=(const LocationSet& o) {
00305     lset.clear();
00306     std::set<Exp*, lessExpStar>::const_iterator it;
00307     for (it = o.lset.begin(); it != o.lset.end(); it++) {
00308         lset.insert((*it)->clone());
00309     }
00310     return *this;
00311 }
00312 
00313 // Copy constructor
00314 LocationSet::LocationSet(const LocationSet& o) {
00315     std::set<Exp*, lessExpStar>::const_iterator it;
00316     for (it = o.lset.begin(); it != o.lset.end(); it++)
00317         lset.insert((*it)->clone());
00318 }
00319 
00320 char* LocationSet::prints() {
00321     std::ostringstream ost;
00322     std::set<Exp*, lessExpStar>::iterator it;
00323     for (it = lset.begin(); it != lset.end(); it++) {
00324         if (it != lset.begin()) ost << ",\t";
00325         ost << *it;
00326     }
00327     strncpy(debug_buffer, ost.str().c_str(), DEBUG_BUFSIZE-1);
00328     debug_buffer[DEBUG_BUFSIZE-1] = '\0';
00329     return debug_buffer;
00330 }
00331 
00332 void LocationSet::dump() {
00333     print(std::cerr);
00334 }
00335 
00336 void LocationSet::print(std::ostream& os) {
00337     std::set<Exp*, lessExpStar>::iterator it;
00338     for (it = lset.begin(); it != lset.end(); it++) {
00339         if (it != lset.begin()) os << ",\t";
00340         os << *it;
00341     }
00342 }
00343 
00344 void LocationSet::remove(Exp* given) {
00345     std::set<Exp*, lessExpStar>::iterator it = lset.find(given);
00346     if (it == lset.end()) return;
00347 //std::cerr << "LocationSet::remove at " << std::hex << (unsigned)this << " of " << *it << "\n";
00348 //std::cerr << "before: "; print();
00349     // NOTE: if the below uncommented, things go crazy. Valgrind says that
00350     // the deleted value gets used next in LocationSet::operator== ?!
00351     //delete *it;         // These expressions were cloned when created
00352     lset.erase(it);
00353 //std::cerr << "after : "; print();
00354 }
00355 
00356 // Remove locations defined by any of the given set of statements
00357 // Used for killing in liveness sets
00358 void LocationSet::removeIfDefines(StatementSet& given) {
00359     StatementSet::iterator it;
00360     for (it = given.begin(); it != given.end(); ++it) {
00361         Statement* s = (Statement*)*it;
00362         LocationSet defs;
00363         s->getDefinitions(defs);
00364         LocationSet::iterator dd;
00365         for (dd = defs.begin(); dd != defs.end(); ++dd) 
00366             lset.erase(*dd);
00367     }
00368 }
00369 
00370 // Make this set the union of itself and other
00371 void LocationSet::makeUnion(LocationSet& other) {
00372     iterator it;
00373     for (it = other.lset.begin(); it != other.lset.end(); it++) {
00374         lset.insert(*it);
00375     }
00376 }
00377 
00378 // Make this set the set difference of itself and other
00379 void LocationSet::makeDiff(LocationSet& other) {
00380     std::set<Exp*, lessExpStar>::iterator it;
00381     for (it = other.lset.begin(); it != other.lset.end(); it++) {
00382         lset.erase(*it);
00383     }
00384 }
00385 
00386 bool LocationSet::operator==(const LocationSet& o) const {
00387     // We want to compare the locations, not the pointers
00388     if (size() != o.size()) return false;
00389     std::set<Exp*, lessExpStar>::const_iterator it1, it2;
00390     for (it1 = lset.begin(), it2 = o.lset.begin(); it1 != lset.end(); it1++, it2++) {
00391         if (!(**it1 == **it2)) return false;
00392     }
00393     return true;
00394 }
00395 
00396 bool LocationSet::exists(Exp* e) {
00397     return lset.find(e) != lset.end();
00398 }
00399 
00400 // This set is assumed to be of subscripted locations (e.g. a Collector), and we want to find the unsubscripted
00401 // location e in the set
00402 Exp* LocationSet::findNS(Exp* e) {
00403     // Note: can't search with a wildcard, since it doesn't have the weak ordering required (I think)
00404     RefExp r(e, NULL);
00405     // Note: the below assumes that NULL is less than any other pointer
00406     iterator it = lset.lower_bound(&r);
00407     if (it == lset.end())
00408         return NULL;
00409     if ((*((RefExp*) *it)->getSubExp1() == *e))
00410         return *it;
00411     else
00412         return NULL;
00413 }
00414 
00415 // Given an unsubscripted location e, return true if e{-} or e{0} exists in the set
00416 bool LocationSet::existsImplicit(Exp* e) {
00417     RefExp r(e, NULL);
00418     iterator it = lset.lower_bound(&r);     // First element >= r
00419     // Note: the below relies on the fact that NULL is less than any other pointer. Try later entries in the set:
00420     while (it != lset.end()) {
00421         if (!(*it)->isSubscript()) return false;        // Looking for e{something} (could be e.g. %pc)
00422         if (!(*((RefExp*) *it)->getSubExp1() == *e))    // Gone past e{anything}?
00423             return false;                               // Yes, then e{-} or e{0} cannot exist
00424         if (((RefExp*) *it)->isImplicitDef())           // Check for e{-} or e{0}
00425             return true;                                // Found
00426         ++it;                                           // Else check next entry
00427     }
00428     return false;
00429 }
00430 
00431 // Find a location with a different def, but same expression. For example, pass r28{10},
00432 // return true if r28{20} in the set. If return true, dr points to the first different ref
00433 bool LocationSet::findDifferentRef(RefExp* e, Exp *&dr) {
00434     RefExp search(e->getSubExp1()->clone(), (Statement*)-1);
00435     std::set<Exp*, lessExpStar>::iterator pos = lset.find(&search);
00436     if (pos == lset.end()) return false;
00437     while (pos != lset.end()) {
00438         // Exit if we've gone to a new base expression
00439         // E.g. searching for r13{10} and **pos is r14{0}
00440         // Note: we want a ref-sensitive compare, but with the outer refs stripped off
00441         // For example: m[r29{10} - 16]{any} is different from m[r29{20} - 16]{any}
00442         if (!(*(*pos)->getSubExp1() == *e->getSubExp1())) break;
00443         // Bases are the same; return true if only different ref
00444         if (!(**pos == *e)) {
00445             dr = *pos;
00446             return true; 
00447         } 
00448         ++pos;
00449     }
00450     return false;
00451 }
00452 
00453 // Add a subscript (to definition d) to each element
00454 void LocationSet::addSubscript(Statement* d /* , Cfg* cfg */) {
00455     std::set<Exp*, lessExpStar>::iterator it;
00456     std::set<Exp*, lessExpStar> newSet;
00457     for (it = lset.begin(); it != lset.end(); it++)
00458         newSet.insert((*it)->expSubscriptVar(*it, d /* , cfg */));
00459     lset = newSet;          // Replace the old set!
00460     // Note: don't delete the old exps; they are copied in the new set
00461 }
00462 
00463 // Substitute s into all members of the set
00464 void LocationSet::substitute(Assign& a) {
00465     Exp* lhs = a.getLeft();
00466     if (lhs == NULL) return;
00467     Exp* rhs = a.getRight();
00468     if (rhs == NULL) return;        // ? Will this ever happen?
00469     std::set<Exp*, lessExpStar>::iterator it;
00470     // Note: it's important not to change the pointer in the set of pointers to expressions, without removing and
00471     // inserting again. Otherwise, the set becomes out of order, and operations such as set comparison fail!
00472     // To avoid any funny behaviour when iterating the loop, we use the following two sets
00473     LocationSet removeSet;          // These will be removed after the loop
00474     LocationSet removeAndDelete;    // These will be removed then deleted
00475     LocationSet insertSet;          // These will be inserted after the loop
00476     bool change;
00477     for (it = lset.begin(); it != lset.end(); it++) {
00478         Exp* loc = *it;
00479         Exp* replace;
00480         if (loc->search(lhs, replace)) {
00481             if (rhs->isTerminal()) {
00482                 // This is no longer a location of interest (e.g. %pc)
00483                 removeSet.insert(loc);
00484                 continue;
00485             }
00486             loc = loc->clone()->searchReplaceAll(lhs, rhs, change);
00487             if (change) {
00488                 loc = loc->simplifyArith();
00489                 loc = loc->simplify();
00490                 // If the result is no longer a register or memory (e.g.
00491                 // r[28]-4), then delete this expression and insert any
00492                 // components it uses (in the example, just r[28])
00493                 if (!loc->isRegOf() && !loc->isMemOf()) {
00494                     // Note: can't delete the expression yet, because the
00495                     // act of insertion into the remove set requires silent
00496                     // calls to the compare function
00497                     removeAndDelete.insert(*it);
00498                     loc->addUsedLocs(insertSet);
00499                     continue;
00500                 }
00501                 // Else we just want to replace it
00502                 // Regardless of whether the top level expression pointer has
00503                 // changed, remove and insert it from the set of pointers
00504                 removeSet.insert(*it);      // Note: remove the unmodified ptr
00505                 insertSet.insert(loc);
00506             }
00507         }
00508     }
00509     makeDiff(removeSet);       // Remove the items to be removed
00510     makeDiff(removeAndDelete); // These are to be removed as well
00511     makeUnion(insertSet);      // Insert the items to be added
00512     // Now delete the expressions that are no longer needed
00513     std::set<Exp*, lessExpStar>::iterator dd;
00514     for (dd = removeAndDelete.lset.begin(); dd != removeAndDelete.lset.end();
00515       dd++)
00516         delete *dd;             // Plug that memory leak
00517 }
00518 
00519 //
00520 // StatementList methods
00521 //
00522 
00523 bool StatementList::remove(Statement* s) {
00524     std::list<Statement*>::iterator it;
00525     for (it = slist.begin(); it != slist.end(); it++) {
00526         if (*it == s) {
00527             slist.erase(it);
00528             return true;
00529         }
00530     }
00531     return false;
00532 }
00533 
00534 void StatementList::append(StatementList& sl) {
00535     for (iterator it = sl.slist.begin(); it != sl.slist.end(); it++) {
00536         slist.push_back(*it);
00537     }
00538 }
00539 
00540 void StatementList::append(StatementSet& ss) {
00541     for (StatementSet::iterator it = ss.begin(); it != ss.end(); it++) {
00542         slist.push_back(*it);
00543     }
00544 }
00545 
00546 char* StatementList::prints() {
00547     std::ostringstream ost;
00548     for (iterator it = slist.begin(); it != slist.end(); it++) {
00549         ost << *it << ",\t";
00550     }
00551     strncpy(debug_buffer, ost.str().c_str(), DEBUG_BUFSIZE-1);
00552     debug_buffer[DEBUG_BUFSIZE-1] = '\0';
00553     return debug_buffer;
00554 }
00555 
00556 //
00557 // StatementVec methods
00558 //
00559 
00560 void StatementVec::putAt(int idx, Statement* s) {
00561     if (idx >= (int)svec.size())
00562         svec.resize(idx+1, NULL);
00563     svec[idx] = s;
00564 }
00565 
00566 StatementVec::iterator StatementVec::remove(iterator it) {
00567 /*
00568     iterator oldoldit = it;
00569     iterator oldit = it;
00570     for (it++; it != svec.end(); it++, oldit++) 
00571         *oldit = *it;
00572     svec.resize(svec.size()-1);
00573     return oldoldit;
00574 */
00575     return svec.erase(it);
00576 }
00577 
00578 char* StatementVec::prints() {
00579     std::ostringstream ost;
00580     iterator it;
00581     for (it = svec.begin(); it != svec.end(); it++) {
00582         ost << *it << ",\t";
00583     }
00584     strncpy(debug_buffer, ost.str().c_str(), DEBUG_BUFSIZE-1);
00585     debug_buffer[DEBUG_BUFSIZE-1] = '\0';
00586     return debug_buffer;
00587 }
00588 
00589 // Print just the numbers to stream os
00590 void StatementVec::printNums(std::ostream& os) {
00591     iterator it;
00592     os << std::dec;
00593     for (it = svec.begin(); it != svec.end(); ) {
00594         if (*it)
00595             (*it)->printNum(os);
00596         else
00597             os << "-";              // Special case for no definition
00598         if (++it != svec.end())
00599             os << " ";
00600     }
00601 }
00602 
00603 
00604 // Special intersection method: this := a intersect b
00605 void StatementList::makeIsect(StatementList& a, LocationSet& b) {
00606     slist.clear();
00607     for (iterator it = a.slist.begin(); it != a.slist.end(); ++it) {
00608         Assignment* as = (Assignment*)*it;
00609         if (b.exists(as->getLeft()))
00610             slist.push_back(as);
00611     }
00612 }
00613 
00614 void StatementList::makeCloneOf(StatementList& o) {
00615     slist.clear();
00616     for (iterator it = o.slist.begin(); it != o.slist.end(); it++)
00617         slist.push_back((*it)->clone());
00618 }
00619 
00620 // Return true if loc appears on the left of any statements in this list
00621 // Note: statements in this list are assumed to be assignments
00622 bool StatementList::existsOnLeft(Exp* loc) {
00623     for (iterator it = slist.begin(); it != slist.end(); it++) {
00624         if (*((Assignment*)*it)->getLeft() == *loc)
00625             return true;
00626     }
00627     return false;
00628 }
00629 
00630 // Remove the first definition where loc appears on the left
00631 // Note: statements in this list are assumed to be assignments
00632 void StatementList::removeDefOf(Exp* loc) {
00633     for (iterator it = slist.begin(); it != slist.end(); it++) {
00634         if (*((Assignment*)*it)->getLeft() == *loc) {
00635             erase(it);
00636             return;
00637         }
00638     }
00639 }
00640 
00641 // Find the first Assignment with loc on the LHS
00642 Assignment* StatementList::findOnLeft(Exp* loc) {
00643     if (slist.size() == 0)
00644         return NULL;
00645     for (iterator it = slist.begin(); it != slist.end(); it++) {
00646         Exp *left = ((Assignment*)*it)->getLeft();
00647         if (*left == *loc)
00648             return (Assignment*)*it;
00649         if (left->isLocal()) {
00650             Location *l = (Location*)left;
00651             Exp *e = l->getProc()->expFromSymbol(((Const*)l->getSubExp1())->getStr());
00652             if (e && ((*e == *loc) || (e->isSubscript() && *e->getSubExp1() == *loc))) {
00653                 return (Assignment*)*it;
00654             }
00655         }
00656     }
00657     return NULL;
00658 }
00659 
00660 void LocationSet::diff(LocationSet* o) {
00661     std::set<Exp*, lessExpStar>::iterator it;
00662     bool printed2not1 = false;
00663     for (it = o->lset.begin(); it != o->lset.end(); it++) {
00664         Exp* oe = *it;
00665         if (lset.find(oe) == lset.end()) {
00666             if (!printed2not1) {
00667                 printed2not1 = true;
00668                 std::cerr << "In set 2 but not set 1:\n";
00669             }
00670             std::cerr << oe << "\t";
00671         }
00672     }
00673     if (printed2not1)
00674         std::cerr << "\n";
00675     bool printed1not2 = false;
00676     for (it = lset.begin(); it != lset.end(); it++) {
00677         Exp* e = *it;
00678         if (o->lset.find(e) == o->lset.end()) {
00679             if (!printed1not2) {
00680                 printed1not2 = true;
00681                 std::cerr << "In set 1 but not set 2:\n";
00682             }
00683             std::cerr << e << "\t";
00684         }
00685     }
00686     if (printed1not2)
00687         std::cerr << "\n";
00688 }
00689 Range::Range() : stride(1), lowerBound(MIN), upperBound(MAX)
00690 {
00691     base = new Const(0);
00692 }
00693 
00694 Range::Range(int stride, int lowerBound, int upperBound, Exp *base) : 
00695         stride(stride), lowerBound(lowerBound), upperBound(upperBound), base(base) {
00696     if (lowerBound == upperBound && lowerBound == 0 && (base->getOper() == opMinus || base->getOper() == opPlus) &&
00697         base->getSubExp2()->isIntConst()) {
00698         this->lowerBound = ((Const*)base->getSubExp2())->getInt();
00699         if (base->getOper() == opMinus)
00700             this->lowerBound = -this->lowerBound;
00701         this->upperBound = this->lowerBound;
00702         this->base = base->getSubExp1();
00703     } else {
00704         if (base == NULL)
00705             base = new Const(0);
00706         if (lowerBound > upperBound)
00707             this->upperBound = lowerBound;
00708         if (upperBound < lowerBound)
00709             this->lowerBound = upperBound;
00710     }
00711 }
00712 
00713 void Range::print(std::ostream &os)
00714 {
00715     assert(lowerBound <= upperBound);
00716     if (base->isIntConst() && ((Const*)base)->getInt() == 0 &&
00717         lowerBound == MIN && upperBound == MAX) {
00718         os << "T";
00719         return;
00720     }
00721     bool needPlus = false;
00722     if (lowerBound == upperBound) {
00723         if (!base->isIntConst() || ((Const*)base)->getInt() != 0) {
00724             if (lowerBound != 0) {
00725                 os << lowerBound;
00726                 needPlus = true;
00727             }
00728         } else {
00729             needPlus = true;
00730             os << lowerBound;
00731         }
00732     } else {
00733         if (stride != 1)
00734             os << stride;
00735         os << "[";
00736         if (lowerBound == MIN)
00737             os << "-inf";
00738         else
00739             os << lowerBound;
00740         os << ", ";
00741         if (upperBound == MAX)
00742             os << "inf";
00743         else
00744             os << upperBound;
00745         os << "]";
00746         needPlus = true;
00747     }
00748     if (!base->isIntConst() || ((Const*)base)->getInt() != 0) {
00749         if (needPlus)
00750             os << " + ";
00751         base->print(os);
00752     }
00753 }
00754 
00755 void Range::unionWith(Range &r)
00756 {
00757     if (VERBOSE && DEBUG_RANGE_ANALYSIS)
00758         LOG << "unioning " << this << " with " << r << " got ";
00759     if (base->getOper() == opMinus && r.base->getOper() == opMinus &&
00760         *base->getSubExp1() == *r.base->getSubExp1() &&
00761         base->getSubExp2()->isIntConst() && r.base->getSubExp2()->isIntConst()) {
00762         int c1 = ((Const*)base->getSubExp2())->getInt();
00763         int c2 = ((Const*)r.base->getSubExp2())->getInt();
00764         if (c1 != c2) {
00765             if (lowerBound == r.lowerBound && upperBound == r.upperBound &&
00766                 lowerBound == 0) {
00767                 lowerBound = std::min(-c1, -c2);
00768                 upperBound = std::max(-c1, -c2);
00769                 base = base->getSubExp1();
00770                 if (VERBOSE && DEBUG_RANGE_ANALYSIS)
00771                     LOG << this << "\n";
00772                 return;
00773             }
00774         }
00775     }
00776     if (!(*base == *r.base)) {
00777         stride = 1; lowerBound = MIN; upperBound = MAX; base = new Const(0);
00778         if (VERBOSE && DEBUG_RANGE_ANALYSIS)
00779             LOG << this << "\n";
00780         return;
00781     }
00782     if (stride != r.stride)
00783         stride = std::min(stride, r.stride);
00784     if (lowerBound != r.lowerBound)
00785         lowerBound = std::min(lowerBound, r.lowerBound);
00786     if (upperBound != r.upperBound)
00787         upperBound = std::max(upperBound, r.upperBound);
00788     if (VERBOSE && DEBUG_RANGE_ANALYSIS)
00789         LOG << this << "\n";
00790 }
00791 
00792 void Range::widenWith(Range &r)
00793 {
00794     if (VERBOSE && DEBUG_RANGE_ANALYSIS)
00795         LOG << "widening " << this << " with " << r << " got ";
00796     if (!(*base == *r.base)) {
00797         stride = 1; lowerBound = MIN; upperBound = MAX; base = new Const(0);
00798         if (VERBOSE && DEBUG_RANGE_ANALYSIS)
00799             LOG << this << "\n";
00800         return;
00801     }
00802     // ignore stride for now
00803     if (r.getLowerBound() < lowerBound) 
00804         lowerBound = MIN;
00805     if (r.getUpperBound() > upperBound)
00806         upperBound = MAX;
00807     if (VERBOSE && DEBUG_RANGE_ANALYSIS)
00808         LOG << this << "\n";
00809 }
00810 Range &RangeMap::getRange(Exp *loc) {
00811     if (ranges.find(loc) == ranges.end()) {
00812         return *(new Range(1, Range::MIN, Range::MAX, new Const(0)));
00813     }
00814     return ranges[loc];
00815 }
00816 
00817 void RangeMap::unionwith(RangeMap &other)
00818 {
00819     for (std::map<Exp*, Range, lessExpStar>::iterator it = other.ranges.begin(); it != other.ranges.end(); it++) {
00820         if (ranges.find((*it).first) == ranges.end()) {
00821             ranges[(*it).first] = (*it).second;
00822         } else {
00823             ranges[(*it).first].unionWith((*it).second);
00824         }
00825     }
00826 }
00827 
00828 void RangeMap::widenwith(RangeMap &other)
00829 {
00830     for (std::map<Exp*, Range, lessExpStar>::iterator it = other.ranges.begin(); it != other.ranges.end(); it++) {
00831         if (ranges.find((*it).first) == ranges.end()) {
00832             ranges[(*it).first] = (*it).second;
00833         } else {
00834             ranges[(*it).first].widenWith((*it).second);
00835         }
00836     }
00837 }
00838 
00839 
00840 void RangeMap::print(std::ostream &os)
00841 {
00842     for (std::map<Exp*, Range, lessExpStar>::iterator it = ranges.begin(); it != ranges.end(); it++) {
00843         if (it != ranges.begin())
00844             os << ", ";
00845         (*it).first->print(os);
00846         os << " -> ";
00847         (*it).second.print(os);
00848     }
00849 }
00850 
00851 Exp *RangeMap::substInto(Exp *e, std::set<Exp*, lessExpStar> *only)
00852 {
00853     bool changes;
00854     int count = 0;
00855     do {
00856         changes = false;
00857         for (std::map<Exp*, Range, lessExpStar>::iterator it = ranges.begin(); it != ranges.end(); it++) {
00858             if (only && only->find((*it).first) == only->end())
00859                 continue;
00860             bool change = false;
00861             Exp *eold = e->clone();
00862             if ((*it).second.getLowerBound() == (*it).second.getUpperBound()) {
00863                 e = e->searchReplaceAll((*it).first, (new Binary(opPlus, (*it).second.getBase(), new Const((*it).second.getLowerBound())))->simplify(), change);
00864             }
00865             if (change) {
00866                 e = e->simplify()->simplifyArith();
00867                 if (VERBOSE && DEBUG_RANGE_ANALYSIS)
00868                     LOG << "applied " << (*it).first << " to " << eold << " to get " << e << "\n";
00869                 changes = true;
00870             }
00871         }
00872         count++;
00873         assert(count < 5);
00874     } while(changes);
00875     return e;
00876 }
00877 
00878 void RangeMap::killAllMemOfs()
00879 {
00880     for (std::map<Exp*, Range, lessExpStar>::iterator it = ranges.begin(); it != ranges.end(); it++) {
00881         if ((*it).first->isMemOf()) {
00882             Range empty;
00883             (*it).second.unionWith(empty);
00884         }
00885     }
00886 }
00887 
00888 bool Range::operator==(Range &other)
00889 {
00890     return stride == other.stride && lowerBound == other.lowerBound && upperBound == other.upperBound && *base == *other.base;
00891 }
00892 
00893 // return true if this range map is a subset of the other range map
00894 bool RangeMap::isSubset(RangeMap &other) {
00895     for (std::map<Exp*, Range, lessExpStar>::iterator it = ranges.begin(); it != ranges.end(); it++) {
00896         if (other.ranges.find((*it).first) == other.ranges.end()) {
00897             if (VERBOSE && DEBUG_RANGE_ANALYSIS)
00898                 LOG << "did not find " << (*it).first << " in other, not a subset\n";
00899             return false;
00900         }
00901         Range &r = other.ranges[(*it).first];
00902         if (!((*it).second == r)) {
00903             if (VERBOSE && DEBUG_RANGE_ANALYSIS)
00904                 LOG << "range for " << (*it).first << " in other " << r << " is not equal to range in this " << (*it).second << ", not a subset\n";
00905             return false;
00906         }
00907     }
00908     return true;
00909 }
00910 
00911 
00912 //  class ConnectionGraph
00913 
00914 void ConnectionGraph::add(Exp* a, Exp* b) {
00915     iterator ff = emap.find(a);
00916     while (ff != emap.end() && *ff->first == *a) {
00917         if (*ff->second == *b) return;      // Don't add a second entry
00918         ++ff;
00919     }
00920     std::pair<Exp*, Exp*> pr;
00921     pr.first = a; pr.second = b;
00922     emap.insert(pr);
00923 }
00924 
00925 void ConnectionGraph::connect(Exp* a, Exp* b) {
00926     add(a, b);
00927     add(b, a);
00928 }
00929 
00930 int ConnectionGraph::count(Exp* e) {
00931     iterator ff = emap.find(e);
00932     int n = 0;
00933     while (ff != emap.end() && *ff->first == *e) {
00934         ++n;
00935         ++ff;
00936     }
00937     return n;
00938 }
00939 
00940 bool ConnectionGraph::isConnected(Exp* a, Exp* b) {
00941     iterator ff = emap.find(a);
00942     while (ff != emap.end() && *ff->first == *a) {
00943         if (*ff->second == *b)
00944             return true;                    // Found the connection
00945         ++ff;
00946     }
00947     return false;
00948 }
00949     
00950 
00951 // Modify the map so that a <-> b becomes a <-> c
00952 void ConnectionGraph::update(Exp* a, Exp* b, Exp* c) {
00953     // find a->b
00954     iterator ff = emap.find(a);
00955     while (ff != emap.end() && *ff->first == *a) {
00956         if (*ff->second == *b) {
00957             ff->second = c;         // Now a->c
00958             break;
00959         }
00960         ++ff;
00961     }
00962     // find b -> a
00963     ff = emap.find(b);
00964     while (ff != emap.end() && *ff->first == *b) {
00965         if (*ff->second == *a) {
00966             emap.erase(ff);
00967             add(c, a);              // Now c->a
00968             break;
00969         }
00970         ++ff;
00971     }
00972 }
00973 
00974 // Remove the mapping at *aa, and return a valid iterator for looping
00975 ConnectionGraph::iterator ConnectionGraph::remove(iterator aa) {
00976     assert (aa != emap.end());
00977     Exp* b = aa->second;
00978     emap.erase(aa++);
00979     iterator bb = emap.find(b);
00980     assert(bb != emap.end());
00981     if (bb == aa)
00982         ++aa;
00983     emap.erase(bb);
00984     return aa;
00985 }
00986 
00987 // For debugging
00988 void dumpConnectionGraph(ConnectionGraph* cg) {
00989     ConnectionGraph::iterator cc;
00990     for (cc = cg->begin(); cc != cg->end(); ++cc)
00991         std::cerr << cc->first << " <-> " << cc->second << "\n";
00992 }
00993 
00994 void ConnectionGraph::dump() {
00995     iterator cc;
00996     for (cc = begin(); cc != end(); ++cc)
00997         std::cerr << cc->first << " <-> " << cc->second << "\n";
00998 }

Generated on Tue Sep 19 21:18:25 2006 for Boomerang by  doxygen 1.4.6