// Substitute s into all members of the set void LocationSet::substitute(Assign& a) { Exp* lhs = a.getLeft(); if (lhs == NULL) return; Exp* rhs = a.getRight(); if (rhs == NULL) return; // ? Will this ever happen? std::set<Exp*, lessExpStar>::iterator it; // Note: it's important not to change the pointer in the set of pointers to expressions, without removing and // inserting again. Otherwise, the set becomes out of order, and operations such as set comparison fail! // To avoid any funny behaviour when iterating the loop, we use the following two sets LocationSet removeSet; // These will be removed after the loop LocationSet removeAndDelete; // These will be removed then deleted LocationSet insertSet; // These will be inserted after the loop bool change; for (it = lset.begin(); it != lset.end(); it++) { Exp* loc = *it; Exp* replace; if (loc->search(lhs, replace)) { if (rhs->isTerminal()) { // This is no longer a location of interest (e.g. %pc) removeSet.insert(loc); continue; } loc = loc->clone()->searchReplaceAll(lhs, rhs, change); if (change) { loc = loc->simplifyArith(); loc = loc->simplify(); // If the result is no longer a register or memory (e.g. // r[28]-4), then delete this expression and insert any // components it uses (in the example, just r[28]) if (!loc->isRegOf() && !loc->isMemOf()) { // Note: can't delete the expression yet, because the // act of insertion into the remove set requires silent // calls to the compare function removeAndDelete.insert(*it); loc->addUsedLocs(insertSet); continue; } // Else we just want to replace it // Regardless of whether the top level expression pointer has // changed, remove and insert it from the set of pointers removeSet.insert(*it); // Note: remove the unmodified ptr insertSet.insert(loc); } } } makeDiff(removeSet); // Remove the items to be removed makeDiff(removeAndDelete); // These are to be removed as well makeUnion(insertSet); // Insert the items to be added // Now delete the expressions that are no longer needed std::set<Exp*, lessExpStar>::iterator dd; for (dd = removeAndDelete.lset.begin(); dd != removeAndDelete.lset.end(); dd++) delete *dd; // Plug that memory leak }
void BoolAssign::setLeftFromList(const std::list<Statement *> &stmts) { assert(stmts.size() == 1); Assign *first = static_cast<Assign *>(stmts.front()); assert(first->getKind() == StmtType::Assign); m_lhs = first->getLeft(); }
bool StrengthReductionReversalPass::execute(UserProc *proc) { StatementList stmts; proc->getStatements(stmts); for (Statement *s : stmts) { if (!s->isAssign()) { continue; } Assign *as = static_cast<Assign *>(s); // of the form x = x{p} + c if ((as->getRight()->getOper() == opPlus) && as->getRight()->getSubExp1()->isSubscript() && (*as->getLeft() == *as->getRight()->getSubExp1()->getSubExp1()) && as->getRight()->getSubExp2()->isIntConst()) { int c = as->getRight()->access<Const, 2>()->getInt(); auto r = as->getRight()->access<RefExp, 1>(); if (r->getDef() && r->getDef()->isPhi()) { PhiAssign *p = static_cast<PhiAssign *>(r->getDef()); if (p->getNumDefs() == 2) { Statement *first = p->begin()->getDef(); Statement *second = p->rbegin()->getDef(); if (first == as) { // want the increment in second std::swap(first, second); } // first must be of form x := 0 if (first && first->isAssign() && static_cast<Assign *>(first)->getRight()->isIntConst() && static_cast<Assign *>(first)->getRight()->access<Const>()->getInt() == 0) { // ok, fun, now we need to find every reference to p and // replace with x{p} * c StatementList stmts2; proc->getStatements(stmts2); for (Statement *stmt2 : stmts2) { if (stmt2 != as) { stmt2->searchAndReplace( *r, Binary::get(opMult, r->clone(), Const::get(c))); } } // that done we can replace c with 1 in as as->getRight()->access<Const, 2>()->setInt(1); } } } } } return true; }