00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "constraint.h"
00022 #include "managed.h"
00023 #include "exp.h"
00024 #include "boomerang.h"
00025 #include "log.h"
00026 #include <sstream>
00027
00028 void ConstraintMap::print(std::ostream& os) {
00029 iterator kk;
00030 bool first = true;
00031 for (kk = cmap.begin(); kk != cmap.end(); kk++) {
00032 if (first) first = false;
00033 else os << ", ";
00034 os << kk->first << " = " << kk->second;
00035 }
00036 os << "\n";
00037 }
00038
00039 extern char debug_buffer[];
00040 char* ConstraintMap::prints() {
00041 std::ostringstream ost;
00042 print(ost);
00043 strncpy(debug_buffer, ost.str().c_str(), DEBUG_BUFSIZE-1);
00044 debug_buffer[DEBUG_BUFSIZE-1] = '\0';
00045 return debug_buffer;
00046 }
00047
00048 void ConstraintMap::makeUnion(ConstraintMap& o) {
00049 std::map<Exp*, Exp*, lessExpStar>::iterator it;
00050 std::pair<std::map<Exp*, Exp*, lessExpStar>::iterator, bool> ret;
00051 for (it = o.cmap.begin(); it != o.cmap.end(); it++) {
00052
00053 ret = cmap.insert(*it);
00054
00055
00056 if (ret.second == false) {
00057
00058
00059 TypeVal* Tret = (TypeVal*)ret.first->second;
00060 Type* ty1 = Tret->getType();
00061 TypeVal* Toth = (TypeVal*)it->second;
00062 Type* ty2 = Toth->getType();
00063 if (ty1 && ty2 && *ty1 != *ty2) {
00064 Tret->setType(ty1->mergeWith(ty2));
00065
00066 }
00067 }
00068 }
00069 }
00070
00071 void ConstraintMap::insert(Exp* term) {
00072 assert(term->isEquality());
00073 Exp* lhs = ((Binary*)term)->getSubExp1();
00074 Exp* rhs = ((Binary*)term)->getSubExp2();
00075 cmap[lhs] = rhs;
00076 }
00077
00078
00079 void EquateMap::print(std::ostream& os) {
00080 iterator ee;
00081 for (ee = emap.begin(); ee != emap.end(); ee++) {
00082 os << " " << ee->first << " = " << ee->second.prints();
00083 }
00084 os << "\n";
00085 }
00086
00087 char* EquateMap::prints() {
00088 std::ostringstream ost;
00089 print(ost);
00090 strncpy(debug_buffer, ost.str().c_str(), DEBUG_BUFSIZE-1);
00091 debug_buffer[DEBUG_BUFSIZE-1] = '\0';
00092 return debug_buffer;
00093 }
00094
00095
00096 void ConstraintMap::substitute(ConstraintMap& other) {
00097 std::map<Exp*, Exp*, lessExpStar>::iterator oo, cc;
00098 for (oo = other.cmap.begin(); oo != other.cmap.end(); oo++) {
00099 bool ch;
00100 for (cc = cmap.begin(); cc != cmap.end(); cc++) {
00101 Exp* newVal = cc->second->searchReplaceAll(oo->first, oo->second, ch);
00102 if (ch) {
00103 if (*cc->first == *newVal)
00104
00105 cmap.erase(cc);
00106 else
00107 cmap[cc->first] = newVal;
00108 } else
00109
00110 newVal = cc->second;
00111 Exp* newKey = cc->first-> searchReplaceAll(oo->first, oo->second, ch);
00112 if (ch) {
00113 cmap.erase(cc->first);
00114
00115 if (!(*newKey == *newVal))
00116 cmap[newKey] = newVal;
00117 }
00118 }
00119 }
00120 }
00121
00122 void ConstraintMap::substAlpha() {
00123 ConstraintMap alphaDefs;
00124 std::map<Exp*, Exp*, lessExpStar>::iterator cc;
00125 for (cc = cmap.begin(); cc != cmap.end(); cc++) {
00126
00127 if (!cc->first->isTypeVal() || !cc->second->isTypeVal())
00128 continue;
00129 Type *t1, *t2;
00130 t1 = ((TypeVal*)cc->first )->getType();
00131 t2 = ((TypeVal*)cc->second)->getType();
00132 int numAlpha = 0;
00133 if (t1->isPointerToAlpha()) numAlpha++;
00134 if (t2->isPointerToAlpha()) numAlpha++;
00135 if (numAlpha != 1)
00136 continue;
00137
00138 if (t1->isPointerToAlpha())
00139 alphaDefs.cmap[cc->first] = cc->second;
00140 else
00141 alphaDefs.cmap[cc->second] = cc->first;
00142 }
00143
00144
00145 for (cc = alphaDefs.begin(); cc != alphaDefs.end(); cc++)
00146 cmap.erase(cc->first);
00147
00148
00149 substitute(alphaDefs);
00150 }
00151
00152
00153
00154 Constraints::~Constraints() {
00155 LocationSet::iterator cc;
00156 for (cc = conSet.begin(); cc != conSet.end(); cc++) {
00157 delete *cc;
00158 }
00159 }
00160
00161
00162 void Constraints::substIntoDisjuncts(ConstraintMap& in) {
00163 ConstraintMap::iterator kk;
00164 for (kk = in.begin(); kk != in.end(); kk++) {
00165 Exp* from = kk->first;
00166 Exp* to = kk->second;
00167 bool ch;
00168 std::list<Exp*>::iterator dd;
00169 for (dd = disjunctions.begin(); dd != disjunctions.end(); dd++) {
00170 (*dd)->searchReplaceAll(from, to, ch);
00171 *dd = (*dd)->simplifyConstraint();
00172 }
00173 }
00174
00175 alphaSubst();
00176 }
00177
00178 void Constraints::substIntoEquates(ConstraintMap& in) {
00179
00180
00181 ConstraintMap extra;
00182 ConstraintMap cur = in;
00183 while (cur.size()) {
00184 extra.clear();
00185 ConstraintMap::iterator kk;
00186 for (kk = cur.begin(); kk != cur.end(); kk++) {
00187 Exp* lhs = kk->first;
00188 std::map<Exp*, LocationSet, lessExpStar>::iterator it = equates.find(lhs);
00189 if (it != equates.end()) {
00190
00191
00192 Exp* val = kk->second;
00193 LocationSet& ls = it->second;
00194 LocationSet::iterator ll;
00195 for (ll = ls.begin(); ll != ls.end(); ll++) {
00196 ConstraintMap::iterator ff;
00197 ff = fixed.find(*ll);
00198 if (ff != fixed.end()) {
00199 if (!unify(val, ff->second, extra)) {
00200 if (VERBOSE || DEBUG_TA)
00201 LOG << "Constraint failure: " << *ll << " constrained to be " <<
00202 ((TypeVal*)val)->getType()->getCtype() << " and " <<
00203 ((TypeVal*)ff->second)->getType()->getCtype() << "\n";
00204 return;
00205 }
00206 } else
00207 extra[*ll] = val;
00208 }
00209 if (((TypeVal*)val)->getType()->isComplete()) {
00210
00211
00212
00213 for (ll = ls.begin(); ll != ls.end(); ll++) {
00214 Exp* newFixed = new Binary(opEquals,
00215 *ll,
00216 val);
00217 extra.insert(newFixed);
00218 }
00219 equates.erase(it);
00220 }
00221 }
00222 }
00223 fixed.makeUnion(extra);
00224 cur = extra;
00225 }
00226 }
00227
00228
00229
00230
00231
00232
00233 Exp* nextDisjunct(Exp*& remainder) {
00234 if (remainder == NULL) return NULL;
00235 if (remainder->isDisjunction()) {
00236 Exp* d1 = ((Binary*)remainder)->getSubExp1();
00237 Exp* d2 = ((Binary*)remainder)->getSubExp2();
00238 if (d1->isDisjunction()) {
00239 remainder = d1;
00240 return d2;
00241 }
00242 remainder = d2;
00243 return d1;
00244 }
00245
00246 Exp* ret = remainder;
00247 remainder = NULL;
00248 return ret;
00249 }
00250
00251 Exp* nextConjunct(Exp*& remainder) {
00252 if (remainder == NULL) return NULL;
00253 if (remainder->isConjunction()) {
00254 Exp* c1 = ((Binary*)remainder)->getSubExp1();
00255 Exp* c2 = ((Binary*)remainder)->getSubExp2();
00256 if (c1->isConjunction()) {
00257 remainder = c1;
00258 return c2;
00259 }
00260 remainder = c2;
00261 return c1;
00262 }
00263
00264 Exp* ret = remainder;
00265 remainder = NULL;
00266 return ret;
00267 }
00268
00269 bool Constraints::solve(std::list<ConstraintMap>& solns) {
00270 LOG << conSet.size() << " constraints:";
00271 std::ostringstream os; conSet.print(os); LOG << os.str().c_str();
00272
00273
00274 LocationSet::iterator cc;
00275 for (cc = conSet.begin(); cc != conSet.end(); cc++) {
00276 Exp* c = *cc;
00277 if (!c->isEquality()) continue;
00278 Exp* left = ((Binary*)c)->getSubExp1();
00279 if (!left->isTypeOf()) continue;
00280 Exp* leftSub = ((Unary*)left)->getSubExp1();
00281 if (!leftSub->isAddrOf()) continue;
00282 Exp* right = ((Binary*)c)->getSubExp2();
00283 if (!right->isTypeVal()) continue;
00284 Type* t = ((TypeVal*)right)->getType();
00285 if (!t->isPointer()) continue;
00286
00287 Exp* clone = c->clone();
00288
00289 left = ((Binary*)clone)->getSubExp1();
00290 leftSub = ((Unary*)left)->getSubExp1();
00291 Exp* something = ((Unary*)leftSub)->getSubExp1();
00292 ((Unary*)left)->setSubExp1ND(something);
00293 ((Unary*)leftSub)->setSubExp1ND(NULL);
00294 delete leftSub;
00295
00296 right = ((Binary*)clone)->getSubExp2();
00297 t = ((TypeVal*)right)->getType();
00298 ((TypeVal*)right)->setType(((PointerType*)t)->getPointsTo()->clone());
00299 delete t;
00300 conSet.remove(c);
00301 conSet.insert(clone);
00302 delete c;
00303 }
00304
00305
00306
00307
00308
00309
00310 for (cc = conSet.begin(); cc != conSet.end(); cc++) {
00311 Exp* c = *cc;
00312 if (c->isTrue()) continue;
00313 if (c->isFalse()) {
00314 if (VERBOSE || DEBUG_TA)
00315 LOG << "Constraint failure: always false constraint\n";
00316 return false;
00317 }
00318 if (c->isDisjunction()) {
00319 disjunctions.push_back(c);
00320 continue;
00321 }
00322
00323 Exp* rem = c, *term;
00324 while ((term = nextConjunct(rem)) != NULL) {
00325 assert(term->isEquality());
00326 Exp* lhs = ((Binary*)term)->getSubExp1();
00327 Exp* rhs = ((Binary*)term)->getSubExp2();
00328 if (rhs->isTypeOf()) {
00329
00330
00331 equates.addEquate(lhs, rhs);
00332 } else {
00333
00334
00335 assert(rhs->isTypeVal());
00336 fixed[lhs] = rhs;
00337 }
00338 }
00339 }
00340
00341 {LOG << "\n" << (unsigned)disjunctions.size() << " disjunctions: "; std::list<Exp*>::iterator dd;
00342 for (dd = disjunctions.begin(); dd != disjunctions.end(); dd++) LOG << *dd << ",\n"; LOG << "\n";}
00343 LOG << fixed.size() << " fixed: " << fixed.prints();
00344 LOG << equates.size() << " equates: " << equates.prints();
00345
00346
00347 substIntoDisjuncts(fixed);
00348
00349
00350
00351 substIntoEquates(fixed);
00352
00353 LOG << "\nAfter substitute fixed into equates:\n";
00354 {LOG << "\n" << (unsigned)disjunctions.size() << " disjunctions: "; std::list<Exp*>::iterator dd;
00355 for (dd = disjunctions.begin(); dd != disjunctions.end(); dd++) LOG << *dd << ",\n"; LOG << "\n";}
00356 LOG << fixed.size() << " fixed: " << fixed.prints();
00357 LOG << equates.size() << " equates: " << equates.prints();
00358
00359
00360 substIntoDisjuncts(fixed);
00361
00362 LOG << "\nAfter second substitute fixed into disjunctions:\n";
00363 {LOG << "\n" << (unsigned)disjunctions.size() << " disjunctions: "; std::list<Exp*>::iterator dd;
00364 for (dd = disjunctions.begin(); dd != disjunctions.end(); dd++) LOG << *dd << ",\n"; LOG << "\n";}
00365 LOG << fixed.size() << " fixed: " << fixed.prints();
00366 LOG << equates.size() << " equates: " << equates.prints();
00367
00368 ConstraintMap soln;
00369 bool ret = doSolve(disjunctions.begin(), soln, solns);
00370 if (ret) {
00371
00372
00373
00374
00375 std::list<ConstraintMap>::iterator it;
00376 for (it = solns.begin(); it != solns.end(); it++)
00377 it->substAlpha();
00378 }
00379 return ret;
00380 }
00381
00382 static int level = 0;
00383
00384
00385
00386 bool Constraints::doSolve(std::list<Exp*>::iterator it, ConstraintMap& soln, std::list<ConstraintMap>& solns) {
00387 LOG << "Begin doSolve at level " << ++level << "\n";
00388 LOG << "Soln now: " << soln.prints() << "\n";
00389 if (it == disjunctions.end()) {
00390
00391
00392
00393
00394
00395
00396
00397 soln.makeUnion(fixed);
00398 solns.push_back(soln);
00399 LOG << "Exiting doSolve at level " << level-- << " returning true\n";
00400 return true;
00401 }
00402
00403 Exp* dj = *it;
00404
00405 Exp* rem1 = dj;
00406 bool anyUnified = false;
00407 Exp* d;
00408 while ((d = nextDisjunct(rem1)) != NULL) {
00409 LOG << " $$ d is " << d << ", rem1 is " << ((rem1==0)?"NULL":rem1->prints()) << " $$\n";
00410
00411
00412
00413 ConstraintMap extra;
00414 Exp* c;
00415 Exp* rem2 = d;
00416 bool unified = true;
00417 while ((c = nextConjunct(rem2)) != NULL) {
00418 LOG << " $$ c is " << c << ", rem2 is " << ((rem2==0)?"NULL":rem2->prints()) << " $$\n";
00419 if (c->isFalse()) {
00420 unified = false;
00421 break;
00422 }
00423 assert(c->isEquality());
00424 Exp* lhs = ((Binary*)c)->getSubExp1();
00425 Exp* rhs = ((Binary*)c)->getSubExp2();
00426 extra.insert(lhs, rhs);
00427 ConstraintMap::iterator kk;
00428 kk = fixed.find(lhs);
00429 if (kk != fixed.end()) {
00430 unified &= unify(rhs, kk->second, extra);
00431 LOG << "Unified now " << unified << "; extra now " << extra.prints() << "\n";
00432 if (!unified) break;
00433 }
00434 }
00435 if (unified)
00436
00437 anyUnified = true;
00438 if (!unified) continue;
00439
00440
00441
00442
00443 ConstraintMap oldSoln = soln;
00444 soln.makeUnion(extra);
00445 doSolve(++it, soln, solns);
00446
00447
00448
00449 soln = oldSoln;
00450 LOG << "After doSolve returned: soln back to: " << soln.prints() << "\n";
00451
00452 it--;
00453
00454 }
00455
00456
00457 LOG << "Exiting doSolve at level " << level-- << " returning " << anyUnified << "\n";
00458 return anyUnified;
00459 }
00460
00461 bool Constraints::unify(Exp* x, Exp* y, ConstraintMap& extra) {
00462 LOG << "Unifying " << x << " with " << y << " result ";
00463 assert(x->isTypeVal());
00464 assert(y->isTypeVal());
00465 Type* xtype = ((TypeVal*)x)->getType();
00466 Type* ytype = ((TypeVal*)y)->getType();
00467 if (xtype->isPointer() && ytype->isPointer()) {
00468 Type* xPointsTo = ((PointerType*)xtype)->getPointsTo();
00469 Type* yPointsTo = ((PointerType*)ytype)->getPointsTo();
00470 if (((PointerType*)xtype)->pointsToAlpha() ||
00471 ((PointerType*)ytype)->pointsToAlpha()) {
00472
00473
00474 if (((PointerType*)xtype)->pointsToAlpha())
00475 extra.constrain(xPointsTo, yPointsTo);
00476 else
00477 extra.constrain(yPointsTo, xPointsTo);
00478 LOG << "true\n";
00479 return true;
00480 }
00481 LOG << (*xPointsTo == *yPointsTo) << "\n";
00482 return *xPointsTo == *yPointsTo;
00483 } else if (xtype->isSize()) {
00484 if (ytype->getSize() == 0) {
00485 LOG << "true\n";
00486 return true;
00487 } else {
00488 LOG << (xtype->getSize() == ytype->getSize()) << "\n";
00489 return xtype->getSize() == ytype->getSize();
00490 }
00491 } else if (ytype->isSize()) {
00492 if (xtype->getSize() == 0) {
00493 LOG << "true\n";
00494 return true;
00495 } else {
00496 LOG << (xtype->getSize() == ytype->getSize()) << "\n";
00497 return xtype->getSize() == ytype->getSize();
00498 }
00499 }
00500
00501 LOG << (*xtype == *ytype) << "\n";
00502 return *xtype == *ytype;
00503 }
00504
00505 void Constraints::alphaSubst() {
00506 std::list<Exp*>::iterator it;
00507 for (it = disjunctions.begin(); it != disjunctions.end(); it++) {
00508
00509 if (!(*it)->isConjunction())
00510
00511 continue;
00512
00513 Exp* temp = (*it)->clone();
00514 Exp* term;
00515 bool found = false;
00516 Exp* trm1 = NULL;
00517 Exp* trm2 = NULL;
00518 Type* t1 = NULL, *t2;
00519 while ((term = nextConjunct(temp)) != NULL) {
00520 if (!term->isEquality())
00521 continue;
00522 trm1 = ((Binary*)term)->getSubExp1();
00523 if (!trm1->isTypeVal()) continue;
00524 trm2 = ((Binary*)term)->getSubExp2();
00525 if (!trm2->isTypeVal()) continue;
00526
00527 t1 = ((TypeVal*)trm1)->getType();
00528 if (t1->isPointerToAlpha()) {
00529 found = true;
00530 break;
00531 }
00532 t2 = ((TypeVal*)trm2)->getType();
00533 if (t2->isPointerToAlpha()) {
00534 found = true;
00535 break;
00536 }
00537 }
00538 if (!found) continue;
00539
00540 Exp* val, *alpha;
00541 if (t1->isPointerToAlpha()) {
00542 alpha = trm1;
00543 val = trm2;
00544 } else {
00545 val = trm1;
00546 alpha = trm2;
00547 }
00548
00549 bool change;
00550 *it = (*it)->searchReplaceAll(alpha, val, change);
00551 *it = (*it)->simplifyConstraint();
00552 }
00553 }
00554
00555 void Constraints::print(std::ostream& os) {
00556 os << "\n" << std::dec << (int)disjunctions.size() << " disjunctions: ";
00557 std::list<Exp*>::iterator dd;
00558 for (dd = disjunctions.begin(); dd != disjunctions.end(); dd++)
00559 os << *dd << ",\n";
00560 os << "\n";
00561 os << (int)fixed.size() << " fixed: ";
00562 fixed.print(os);
00563 os << (int)equates.size() << " equates: ";
00564 equates.print(os);
00565 }
00566
00567 char* Constraints::prints() {
00568 std::ostringstream ost;
00569 print(ost);
00570 strncpy(debug_buffer, ost.str().c_str(), DEBUG_BUFSIZE-1);
00571 debug_buffer[DEBUG_BUFSIZE-1] = '\0';
00572 return debug_buffer;
00573 }