void ConstraintMap::substAlpha() { ConstraintMap alphaDefs; std::map<Exp*, Exp*, lessExpStar>::iterator cc; for (cc = cmap.begin(); cc != cmap.end(); cc++) { // Looking for entries with two TypeVals, where exactly one is an alpha if (!cc->first->isTypeVal() || !cc->second->isTypeVal()) continue; Type *t1, *t2; t1 = ((TypeVal*)cc->first )->getType(); t2 = ((TypeVal*)cc->second)->getType(); int numAlpha = 0; if (t1->isPointerToAlpha()) numAlpha++; if (t2->isPointerToAlpha()) numAlpha++; if (numAlpha != 1) continue; // This is such an equality. Copy it to alphaDefs if (t1->isPointerToAlpha()) alphaDefs.cmap[cc->first] = cc->second; else alphaDefs.cmap[cc->second] = cc->first; } // Remove these from the solution for (cc = alphaDefs.begin(); cc != alphaDefs.end(); cc++) cmap.erase(cc->first); // Now substitute into the remainder substitute(alphaDefs); }
void Constraints::substIntoDisjuncts(ConstraintMap& in) { ConstraintMap::iterator kk; for (kk = in.begin(); kk != in.end(); kk++) { Exp* from = kk->first; Exp* to = kk->second; bool ch; std::list<Exp*>::iterator dd; for (dd = disjunctions.begin(); dd != disjunctions.end(); dd++) { (*dd)->searchReplaceAll(from, to, ch); *dd = (*dd)->simplifyConstraint(); } } // Now do alpha substitution alphaSubst(); }
// ------------------------------------------------------------- // OptimizerImplementation::p_gatherGlobalConstraints // ------------------------------------------------------------- void OptimizerImplementation::p_gatherGlobalConstraints(const ConstraintMap& tmpglobal) { ConstraintMap::const_iterator c; for (c = tmpglobal.begin(); c != tmpglobal.end(); ++c) { std::string name(c->first); ConstraintPtr cons(c->second); if (cons->lhs()) { ConstraintMap::iterator gc(p_allGlobalConstraints.find(name)); if (gc != p_allGlobalConstraints.end()) { gc->second->addToLHS(cons->lhs()); } else { p_allGlobalConstraints[name] = cons; } } } }
bool Constraints::unify(Exp* x, Exp* y, ConstraintMap& extra) { LOG << "Unifying " << x << " with " << y << " result "; assert(x->isTypeVal()); assert(y->isTypeVal()); Type* xtype = ((TypeVal*)x)->getType(); Type* ytype = ((TypeVal*)y)->getType(); if (xtype->isPointer() && ytype->isPointer()) { Type* xPointsTo = ((PointerType*)xtype)->getPointsTo(); Type* yPointsTo = ((PointerType*)ytype)->getPointsTo(); if (((PointerType*)xtype)->pointsToAlpha() || ((PointerType*)ytype)->pointsToAlpha()) { // A new constraint: xtype must be equal to ytype; at least // one of these is a variable type if (((PointerType*)xtype)->pointsToAlpha()) extra.constrain(xPointsTo, yPointsTo); else extra.constrain(yPointsTo, xPointsTo); LOG << "true\n"; return true; } LOG << (*xPointsTo == *yPointsTo) << "\n"; return *xPointsTo == *yPointsTo; } else if (xtype->isSize()) { if (ytype->getSize() == 0) { // Assume size=0 means unknown LOG << "true\n"; return true; } else { LOG << (xtype->getSize() == ytype->getSize()) << "\n"; return xtype->getSize() == ytype->getSize(); } } else if (ytype->isSize()) { if (xtype->getSize() == 0) { // Assume size=0 means unknown LOG << "true\n"; return true; } else { LOG << (xtype->getSize() == ytype->getSize()) << "\n"; return xtype->getSize() == ytype->getSize(); } } // Otherwise, just compare the sizes LOG << (*xtype == *ytype) << "\n"; return *xtype == *ytype; }
void Constraints::substIntoEquates(ConstraintMap& in) { // Substitute the fixed types into the equates. This may generate more // fixed types ConstraintMap extra; ConstraintMap cur = in; while (cur.size()) { extra.clear(); ConstraintMap::iterator kk; for (kk = cur.begin(); kk != cur.end(); kk++) { Exp* lhs = kk->first; std::map<Exp*, LocationSet, lessExpStar>::iterator it = equates.find(lhs); if (it != equates.end()) { // Possibly new constraints that // typeof(elements in it->second) == val Exp* val = kk->second; LocationSet& ls = it->second; LocationSet::iterator ll; for (ll = ls.begin(); ll != ls.end(); ll++) { ConstraintMap::iterator ff; ff = fixed.find(*ll); if (ff != fixed.end()) { if (!unify(val, ff->second, extra)) { if (VERBOSE || DEBUG_TA) LOG << "Constraint failure: " << *ll << " constrained to be " << ((TypeVal*)val)->getType()->getCtype() << " and " << ((TypeVal*)ff->second)->getType()->getCtype() << "\n"; return; } } else extra[*ll] = val; // A new constant constraint } if (((TypeVal*)val)->getType()->isComplete()) { // We have a complete type equal to one or more variables // Remove the equate, and generate more fixed // e.g. Ta = Tb,Tc and Ta = K => Tb=K, Tc=K for (ll = ls.begin(); ll != ls.end(); ll++) { Exp* newFixed = new Binary(opEquals, *ll, // e.g. Tb val); // e.g. K extra.insert(newFixed); } equates.erase(it); } } } fixed.makeUnion(extra); cur = extra; // Take care of any "ripple effect" } // Repeat until no ripples }
// Constraints up to but not including iterator it have been unified. // The current solution is soln // The set of all solutions is in solns bool Constraints::doSolve(std::list<Exp*>::iterator it, ConstraintMap& soln, std::list<ConstraintMap>& solns) { LOG << "Begin doSolve at level " << ++level << "\n"; LOG << "Soln now: " << soln.prints() << "\n"; if (it == disjunctions.end()) { // We have gotten to the end with no unification failures // Copy the current set of constraints as a solution //if (soln.size() == 0) // Awkward. There is a trivial solution, but we have no constraints // So make a constraint of always-true //soln.insert(new Terminal(opTrue)); // Copy the fixed constraints soln.makeUnion(fixed); solns.push_back(soln); LOG << "Exiting doSolve at level " << level-- << " returning true\n"; return true; } Exp* dj = *it; // Iterate through each disjunction d of dj Exp* rem1 = dj; // Remainder bool anyUnified = false; Exp* d; while ((d = nextDisjunct(rem1)) != NULL) { LOG << " $$ d is " << d << ", rem1 is " << ((rem1==0)?"NULL":rem1->prints()) << " $$\n"; // Match disjunct d against the fixed types; it could be compatible, // compatible and generate an additional constraint, or be // incompatible ConstraintMap extra; // Just for this disjunct Exp* c; Exp* rem2 = d; bool unified = true; while ((c = nextConjunct(rem2)) != NULL) { LOG << " $$ c is " << c << ", rem2 is " << ((rem2==0)?"NULL":rem2->prints()) << " $$\n"; if (c->isFalse()) { unified = false; break; } assert(c->isEquality()); Exp* lhs = ((Binary*)c)->getSubExp1(); Exp* rhs = ((Binary*)c)->getSubExp2(); extra.insert(lhs, rhs); ConstraintMap::iterator kk; kk = fixed.find(lhs); if (kk != fixed.end()) { unified &= unify(rhs, kk->second, extra); LOG << "Unified now " << unified << "; extra now " << extra.prints() << "\n"; if (!unified) break; } } if (unified) // True if any disjuncts had all the conjuncts satisfied anyUnified = true; if (!unified) continue; // Use this disjunct // We can't just difference out extra if this fails; it may remove // elements from soln that should not be removed // So need a copy of the old set in oldSoln ConstraintMap oldSoln = soln; soln.makeUnion(extra); doSolve(++it, soln, solns); // Revert to the previous soln (whether doSolve returned true or not) // If this recursion did any good, it will have gotten to the end and // added the resultant soln to solns soln = oldSoln; LOG << "After doSolve returned: soln back to: " << soln.prints() << "\n"; // Back to the current disjunction it--; // Continue for more disjuncts this disjunction } // We have run out of disjuncts. Return true if any disjuncts had no // unification failures LOG << "Exiting doSolve at level " << level-- << " returning " << anyUnified << "\n"; return anyUnified; }