本文整理汇总了C++中Exp::clone方法的典型用法代码示例。如果您正苦于以下问题:C++ Exp::clone方法的具体用法?C++ Exp::clone怎么用?C++ Exp::clone使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Exp
的用法示例。
在下文中一共展示了Exp::clone方法的9个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: substitute
// 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
}
示例2: applyAllTo
Exp *ExpTransformer::applyAllTo(Exp *p, bool &bMod)
{
for (std::list<Exp*>::iterator it = cache.begin(); it != cache.end(); it++)
if (*(*it)->getSubExp1() == *p)
return (*it)->getSubExp2()->clone();
Exp *e = p->clone();
Exp *subs[3];
subs[0] = e->getSubExp1();
subs[1] = e->getSubExp2();
subs[2] = e->getSubExp3();
for (int i = 0; i < 3; i++)
if (subs[i]) {
bool mod = false;
subs[i] = applyAllTo(subs[i], mod);
if (mod && i == 0)
e->setSubExp1(subs[i]);
if (mod && i == 1)
e->setSubExp2(subs[i]);
if (mod && i == 2)
e->setSubExp3(subs[i]);
bMod |= mod;
// if (mod) i--;
}
#if 0
LOG << "applyAllTo called on " << e << "\n";
#endif
bool mod;
//do {
mod = false;
for (std::list<ExpTransformer *>::iterator it = transformers.begin(); it != transformers.end(); it++) {
e = (*it)->applyTo(e, mod);
bMod |= mod;
}
//} while (mod);
cache.push_back(new Binary(opEquals, p->clone(), e->clone()));
return e;
}
示例3: Binary
Exp *GenericExpTransformer::applyFuncs(Exp *rhs)
{
Exp *call, *callw = new Binary(opFlagCall, new Const((char *)"memberAtOffset"), new Terminal(opWild));
if (rhs->search(callw, call)) {
assert(call->getSubExp2()->getOper() == opList);
Exp *p1 = applyFuncs(call->getSubExp2()->getSubExp1());
Exp *p2 = applyFuncs(call->getSubExp2()->getSubExp2()->getSubExp1());
assert(p1->getOper() == opTypeVal);
assert(p2->getOper() == opIntConst);
#if 0
Type *ty = p1->getType();
assert(ty && ty->resolvesToCompound());
#else
Type *ty = NULL; // Note: will cause a segfault
#endif
// probably need to make this func take bits in future
int offset = ((Const *)p2)->getInt() * 8;
const char *member = ty->asCompound()->getNameAtOffset(offset);
Exp *result = new Const((char *)member);
bool change;
rhs = rhs->searchReplace(callw->clone(), result->clone(), change);
assert(change);
#if 0
LOG << "replaced " << call << " with " << result << "\n";
#endif
}
callw = new Binary(opFlagCall, new Const((char *)"offsetToMember"), new Terminal(opWild));
if (rhs->search(callw, call)) {
assert(call->getSubExp2()->getOper() == opList);
Exp *p1 = applyFuncs(call->getSubExp2()->getSubExp1());
Exp *p2 = applyFuncs(call->getSubExp2()->getSubExp2()->getSubExp1());
assert(p1->getOper() == opTypeVal);
assert(p2->getOper() == opStrConst);
#if 0 // ADHOC TA
Type *ty = p1->getType();
assert(ty && ty->resolvesToCompound());
#else
Type *ty = NULL; // Note: will cause a segfault
#endif
char *member = ((Const *)p2)->getStr();
int offset = ty->asCompound()->getOffsetTo(member) / 8;
Exp *result = new Const(offset);
bool change;
rhs = rhs->searchReplace(callw->clone(), result->clone(), change);
assert(change);
#if 0
LOG << "replaced " << call << " with " << result << "\n";
#endif
}
callw = new Binary(opFlagCall, new Const((char *)"plus"), new Terminal(opWild));
if (rhs->search(callw, call)) {
assert(call->getSubExp2()->getOper() == opList);
Exp *p1 = applyFuncs(call->getSubExp2()->getSubExp1());
Exp *p2 = applyFuncs(call->getSubExp2()->getSubExp2()->getSubExp1());
assert(p1->getOper() == opIntConst);
assert(p2->getOper() == opIntConst);
int a = ((Const *)p1)->getInt();
int b = ((Const *)p2)->getInt();
Exp *result = new Const(a + b);
bool change;
rhs = rhs->searchReplace(callw->clone(), result->clone(), change);
assert(change);
#if 0
LOG << "replaced " << call << " with " << result << "\n";
#endif
}
callw = new Binary(opFlagCall, new Const((char *)"neg"), new Terminal(opWild));
if (rhs->search(callw, call)) {
Exp *p1 = applyFuncs(call->getSubExp2());
assert(p1->getOper() == opIntConst);
int a = ((Const *)p1)->getInt();
Exp *result = new Const(-a);
bool change;
rhs = rhs->searchReplace(callw->clone(), result->clone(), change);
assert(change);
#if 0
LOG << "replaced " << call << " with " << result << "\n";
#endif
}
return rhs;
}
示例4: checkCond
bool GenericExpTransformer::checkCond(Exp *cond, Exp *bindings)
{
switch (cond->getOper()) {
case opAnd:
return checkCond(cond->getSubExp1(), bindings)
&& checkCond(cond->getSubExp2(), bindings);
case opEquals:
{
Exp *lhs = cond->getSubExp1(), *rhs = cond->getSubExp2();
for (Exp *l = bindings; l->getOper() != opNil; l = l->getSubExp2()) {
Exp *e = l->getSubExp1();
bool change = false;
lhs = lhs->searchReplaceAll(e->getSubExp1()->clone(), e->getSubExp2()->clone(), change);
#if 0
if (change)
LOG << "replaced " << e->getSubExp1() << " with " << e->getSubExp2() << "\n";
#endif
change = false;
rhs = rhs->searchReplaceAll(e->getSubExp1()->clone(), e->getSubExp2()->clone(), change);
#if 0
if (change)
LOG << "replaced " << e->getSubExp1() << " with " << e->getSubExp2() << "\n";
#endif
}
if (lhs->getOper() == opTypeOf) {
#if 0 // ADHOC TA
Type *ty = lhs->getSubExp1()->getType();
#else
Type *ty = NULL;
#endif
if (ty == NULL) {
#if 0
if (VERBOSE)
LOG << "no type for typeof " << lhs << "\n";
#endif
return false;
}
lhs = new TypeVal(ty);
#if 0
LOG << "got typeval: " << lhs << "\n";
#endif
}
if (lhs->getOper() == opKindOf) {
OPER op = lhs->getSubExp1()->getOper();
lhs = new Const(operStrings[op]);
}
rhs = applyFuncs(rhs);
#if 0
LOG << "check equals in cond: " << lhs << " == " << rhs << "\n";
#endif
if (lhs->getOper() == opVar) {
Exp *le;
for (le = bindings; le->getOper() != opNil && le->getSubExp2()->getOper() != opNil; le = le->getSubExp2())
;
assert(le->getOper() != opNil);
le->setSubExp2(new Binary(opList, new Binary(opEquals, lhs->clone(), rhs->clone()), new Terminal(opNil)));
#if 0
LOG << "bindings now: " << bindings << "\n";
#endif
return true;
}
if (*lhs == *rhs)
return true;
#if 0 // ADHOC TA
if (lhs->getOper() == opTypeVal
&& rhs->getOper() == opTypeVal
&& lhs->getType()->resolvesToCompound()
&& rhs->getType()->isCompound())
return true;
#endif
Exp *new_bindings = lhs->match(rhs);
if (new_bindings == NULL)
return false;
#if 0
LOG << "matched lhs with rhs, bindings: " << new_bindings << "\n";
#endif
Exp *le;
for (le = bindings; le->getOper() != opNil && le->getSubExp2()->getOper() != opNil; le = le->getSubExp2())
;
assert(le->getOper() != opNil);
le->setSubExp2(new_bindings);
#if 0
LOG << "bindings now: " << bindings << "\n";
#endif
return true;
}
default:
LOG << "don't know how to handle oper "
<< operStrings[cond->getOper()] << " in cond.\n";
}
return false;
//.........这里部分代码省略.........
示例5: renameBlockVars
bool DataFlow::renameBlockVars(UserProc* proc, int n, bool clearStacks /* = false */ ) {
if (++progress > 200) {
std::cerr << 'r' << std::flush;
progress = 0;
}
bool changed = false;
// Need to clear the Stacks of old, renamed locations like m[esp-4] (these will be deleted, and will cause compare
// failures in the Stacks, so it can't be correctly ordered and hence balanced etc, and will lead to segfaults)
if (clearStacks) Stacks.clear();
// For each statement S in block n
BasicBlock::rtlit rit; StatementList::iterator sit;
PBB bb = BBs[n];
Statement* S;
for (S = bb->getFirstStmt(rit, sit); S; S = bb->getNextStmt(rit, sit)) {
// if S is not a phi function (per Appel)
/* if (!S->isPhi()) */ {
// For each use of some variable x in S (not just assignments)
LocationSet locs;
if (S->isPhi()) {
PhiAssign* pa = (PhiAssign*)S;
Exp* phiLeft = pa->getLeft();
if (phiLeft->isMemOf() || phiLeft->isRegOf())
phiLeft->getSubExp1()->addUsedLocs(locs);
// A phi statement may use a location defined in a childless call, in which case its use collector
// needs updating
PhiAssign::iterator pp;
for (pp = pa->begin(); pp != pa->end(); ++pp) {
Statement* def = pp->def;
if (def && def->isCall())
((CallStatement*)def)->useBeforeDefine(phiLeft->clone());
}
}
else { // Not a phi assignment
S->addUsedLocs(locs);
}
LocationSet::iterator xx;
for (xx = locs.begin(); xx != locs.end(); xx++) {
Exp* x = *xx;
// Don't rename memOfs that are not renamable according to the current policy
if (!canRename(x, proc)) continue;
Statement* def = NULL;
if (x->isSubscript()) { // Already subscripted?
// No renaming required, but redo the usage analysis, in case this is a new return, and also because
// we may have just removed all call livenesses
// Update use information in calls, and in the proc (for parameters)
Exp* base = ((RefExp*)x)->getSubExp1();
def = ((RefExp*)x)->getDef();
if (def && def->isCall()) {
// Calls have UseCollectors for locations that are used before definition at the call
((CallStatement*)def)->useBeforeDefine(base->clone());
continue;
}
// Update use collector in the proc (for parameters)
if (def == NULL)
proc->useBeforeDefine(base->clone());
continue; // Don't re-rename the renamed variable
}
// Else x is not subscripted yet
if (STACKS_EMPTY(x)) {
if (!Stacks[defineAll].empty())
def = Stacks[defineAll].top();
else {
// If the both stacks are empty, use a NULL definition. This will be changed into a pointer
// to an implicit definition at the start of type analysis, but not until all the m[...]
// have stopped changing their expressions (complicates implicit assignments considerably).
def = NULL;
// Update the collector at the start of the UserProc
proc->useBeforeDefine(x->clone());
}
}
else
def = Stacks[x].top();
if (def && def->isCall())
// Calls have UseCollectors for locations that are used before definition at the call
((CallStatement*)def)->useBeforeDefine(x->clone());
// Replace the use of x with x{def} in S
changed = true;
if (S->isPhi()) {
Exp* phiLeft = ((PhiAssign*)S)->getLeft();
phiLeft->setSubExp1(phiLeft->getSubExp1()->expSubscriptVar(x, def /*, this*/));
} else {
S->subscriptVar(x, def /*, this */);
}
}
}
// MVE: Check for Call and Return Statements; these have DefCollector objects that need to be updated
// Do before the below, so CallStatements have not yet processed their defines
if (S->isCall() || S->isReturn()) {
DefCollector* col;
if (S->isCall())
col = ((CallStatement*)S)->getDefCollector();
else
col = ((ReturnStatement*)S)->getCollector();
col->updateDefs(Stacks, proc);
}
// For each definition of some variable a in S
//.........这里部分代码省略.........
示例6: placePhiFunctions
bool DataFlow::placePhiFunctions(UserProc* proc) {
// First free some memory no longer needed
dfnum.resize(0);
semi.resize(0);
ancestor.resize(0);
samedom.resize(0);
vertex.resize(0);
parent.resize(0);
best.resize(0);
bucket.resize(0);
defsites.clear(); // Clear defsites map,
defallsites.clear();
A_orig.clear(); // and A_orig,
defStmts.clear(); // and the map from variable to defining Stmt
bool change = false;
// Set the sizes of needed vectors
unsigned numBB = indices.size();
Cfg* cfg = proc->getCFG();
assert(numBB == cfg->getNumBBs());
A_orig.resize(numBB);
// We need to create A_orig[n] for all n, the array of sets of locations defined at BB n
// Recreate each call because propagation and other changes make old data invalid
unsigned n;
for (n=0; n < numBB; n++) {
BasicBlock::rtlit rit; StatementList::iterator sit;
PBB bb = BBs[n];
for (Statement* s = bb->getFirstStmt(rit, sit); s; s = bb->getNextStmt(rit, sit)) {
LocationSet ls;
LocationSet::iterator it;
s->getDefinitions(ls);
if (s->isCall() && ((CallStatement*)s)->isChildless()) // If this is a childless call
defallsites.insert(n); // then this block defines every variable
for (it = ls.begin(); it != ls.end(); it++) {
if (canRename(*it, proc)) {
A_orig[n].insert((*it)->clone());
defStmts[*it] = s;
}
}
}
}
// For each node n
for (n=0; n < numBB; n++) {
// For each variable a in A_orig[n]
std::set<Exp*, lessExpStar>& s = A_orig[n];
std::set<Exp*, lessExpStar>::iterator aa;
for (aa = s.begin(); aa != s.end(); aa++) {
Exp* a = *aa;
defsites[a].insert(n);
}
}
// For each variable a (in defsites, i.e. defined anywhere)
std::map<Exp*, std::set<int>, lessExpStar>::iterator mm;
for (mm = defsites.begin(); mm != defsites.end(); mm++) {
Exp* a = (*mm).first; // *mm is pair<Exp*, set<int>>
// Special processing for define-alls
// for each n in defallsites
std::set<int>::iterator da;
for (da = defallsites.begin(); da != defallsites.end(); ++da)
defsites[a].insert(*da);
// W <- defsites[a];
std::set<int> W = defsites[a]; // set copy
// While W not empty
while (W.size()) {
// Remove some node n from W
int n = *W.begin(); // Copy first element
W.erase(W.begin()); // Remove first element
// for each y in DF[n]
std::set<int>::iterator yy;
std::set<int>& DFn = DF[n];
for (yy = DFn.begin(); yy != DFn.end(); yy++) {
int y = *yy;
// if y not element of A_phi[a]
std::set<int>& s = A_phi[a];
if (s.find(y) == s.end()) {
// Insert trivial phi function for a at top of block y: a := phi()
change = true;
Statement* as = new PhiAssign(a->clone());
PBB Ybb = BBs[y];
Ybb->prependStmt(as, proc);
// A_phi[a] <- A_phi[a] U {y}
s.insert(y);
// if a !elementof A_orig[y]
if (A_orig[y].find(a) == A_orig[y].end()) {
// W <- W U {y}
W.insert(y);
}
}
}
}
}
return change;
} // end placePhiFunctions
示例7: addSuccessors
void BlockSyntaxNode::addSuccessors(SyntaxNode *root, std::vector<SyntaxNode *> &successors)
{
for (unsigned i = 0; i < statements.size(); i++) {
if (statements[i]->isBlock()) {
//BlockSyntaxNode *b = (BlockSyntaxNode*)statements[i];
// can move previous statements into this block
if (i > 0) {
std::cerr << "successor: move previous statement into block" << std::endl;
SyntaxNode *n = root->clone();
n->setDepth(root->getDepth() + 1);
BlockSyntaxNode *b1 = (BlockSyntaxNode *)this->clone();
BlockSyntaxNode *nb = (BlockSyntaxNode *)b1->getStatement(i);
b1 = (BlockSyntaxNode *)b1->replace(statements[i - 1], NULL);
nb->prependStatement(statements[i - 1]->clone());
n = n->replace(this, b1);
successors.push_back(n);
//PRINT_BEFORE_AFTER
}
} else {
if (statements.size() != 1) {
// can replace statement with a block containing that statement
std::cerr << "successor: replace statement with a block containing the statement" << std::endl;
BlockSyntaxNode *b = new BlockSyntaxNode();
b->addStatement(statements[i]->clone());
SyntaxNode *n = root->clone();
n->setDepth(root->getDepth() + 1);
n = n->replace(statements[i], b);
successors.push_back(n);
//PRINT_BEFORE_AFTER
}
}
// "jump over" style of if-then
if (i < statements.size() - 2 && statements[i]->isBranch()) {
SyntaxNode *b = statements[i];
if (b->getOutEdge(root, 0) == statements[i + 2]
&& (statements[i + 1]->getOutEdge(root, 0) == statements[i + 2]
|| statements[i + 1]->endsWithGoto())) {
std::cerr << "successor: jump over style if then" << std::endl;
BlockSyntaxNode *b1 = (BlockSyntaxNode *)this->clone();
b1 = (BlockSyntaxNode *)b1->replace(statements[i + 1], NULL);
IfThenSyntaxNode *nif = new IfThenSyntaxNode();
Exp *cond = b->getBB()->getCond();
cond = new Unary(opLNot, cond->clone());
cond = cond->simplify();
nif->setCond(cond);
nif->setThen(statements[i + 1]->clone());
nif->setBB(b->getBB());
b1->setStatement(i, nif);
SyntaxNode *n = root->clone();
n->setDepth(root->getDepth() + 1);
n = n->replace(this, b1);
successors.push_back(n);
//PRINT_BEFORE_AFTER
}
}
// if then else
if (i < statements.size() - 2 && statements[i]->isBranch()) {
SyntaxNode *tThen = statements[i]->getOutEdge(root, 0);
SyntaxNode *tElse = statements[i]->getOutEdge(root, 1);
assert(tThen && tElse);
if (((tThen == statements[i + 2] && tElse == statements[i + 1])
|| (tThen == statements[i + 1] && tElse == statements[i + 2]))
&& tThen->getNumOutEdges() == 1 && tElse->getNumOutEdges() == 1) {
SyntaxNode *else_out = tElse->getOutEdge(root, 0);
SyntaxNode *then_out = tThen->getOutEdge(root, 0);
if (else_out == then_out) {
std::cerr << "successor: if then else" << std::endl;
SyntaxNode *n = root->clone();
n->setDepth(root->getDepth() + 1);
n = n->replace(tThen, NULL);
n = n->replace(tElse, NULL);
IfThenElseSyntaxNode *nif = new IfThenElseSyntaxNode();
nif->setCond(statements[i]->getBB()->getCond()->clone());
nif->setBB(statements[i]->getBB());
nif->setThen(tThen->clone());
nif->setElse(tElse->clone());
n = n->replace(statements[i], nif);
successors.push_back(n);
//PRINT_BEFORE_AFTER
}
}
}
// pretested loop
if (i < statements.size() - 2 && statements[i]->isBranch()) {
SyntaxNode *tBody = statements[i]->getOutEdge(root, 0);
SyntaxNode *tFollow = statements[i]->getOutEdge(root, 1);
assert(tBody && tFollow);
if (tBody == statements[i + 1] && tFollow == statements[i + 2]
&& tBody->getNumOutEdges() == 1
&& tBody->getOutEdge(root, 0) == statements[i]) {
std::cerr << "successor: pretested loop" << std::endl;
SyntaxNode *n = root->clone();
n->setDepth(root->getDepth() + 1);
n = n->replace(tBody, NULL);
PretestedLoopSyntaxNode *nloop = new PretestedLoopSyntaxNode();
nloop->setCond(statements[i]->getBB()->getCond()->clone());
//.........这里部分代码省略.........
示例8: Binary
std::list<Statement *> *RTLInstDict::transformPostVars(std::list<Statement *> *rts, bool optimise)
{
std::list<Statement *>::iterator rt;
// Map from var (could be any expression really) to details
std::map<Exp *, transPost, lessExpStar> vars;
int tmpcount = 1; // For making temp names unique
// Exp *matchParam(1, idParam); // ? Was never used anyway
#ifdef DEBUG_POSTVAR
std::cout << "Transforming from:\n";
for (Exp_CIT p = rts->begin(); p != rts->end(); p++) {
std::cout << setw(8) << " ";
(*p)->print(std::cout);
std::cout << "\n";
}
#endif
// First pass: Scan for post-variables and usages of their referents
for (rt = rts->begin(); rt != rts->end(); rt++) {
// ss appears to be a list of expressions to be searched
// It is either the LHS and RHS of an assignment, or it's the parameters of a flag call
Binary *ss;
if ((*rt)->isAssign()) {
Exp *lhs = ((Assign *)*rt)->getLeft();
Exp *rhs = ((Assign *)*rt)->getRight();
// Look for assignments to post-variables
if (lhs && lhs->isPostVar()) {
if (vars.find(lhs) == vars.end()) {
// Add a record in the map for this postvar
transPost &el = vars[lhs];
el.used = false;
el.type = ((Assign *)*rt)->getType();
// Constuct a temporary. We should probably be smarter and actually check that it's not otherwise
// used here.
std::string tmpname = el.type->getTempName() + (tmpcount++) + "post" ;
el.tmp = Location::tempOf(new Const(tmpname.c_str()));
// Keep a copy of the referrent. For example, if the lhs is r[0]', base is r[0]
el.base = lhs->getSubExp1();
el.post = lhs; // The whole post-var, e.g. r[0]'
el.isNew = true;
// The emulator generator sets optimise false
// I think this forces always generating the temps (MVE)
if (!optimise) {
el.used = true;
el.isNew = false;
}
}
}
// For an assignment, the two expressions to search are the left and right hand sides (could just put the
// whole assignment on, I suppose)
ss = new Binary(opList,
lhs->clone(),
new Binary(opList,
rhs->clone(),
new Terminal(opNil)));
} else if ((*rt)->isFlagAssgn()) {
// An opFlagCall is assumed to be a Binary with a string and an opList of parameters
ss = (Binary *)((Binary *)*rt)->getSubExp2();
} else
ss = NULL;
/* Look for usages of post-variables' referents
* Trickier than you'd think, as we need to make sure to skip over the post-variables themselves. ie match
* r[0] but not r[0]'
* Note: back with SemStrs, we could use a match expression which was a wildcard prepended to the base
* expression; this would match either the base (r[0]) or the post-var (r[0]').
* Can't really use this with Exps, so we search twice; once for the base, and once for the post, and if we
* get more with the former, then we have a use of the base (consider r[0] + r[0]')
*/
for (std::map<Exp *, transPost, lessExpStar>::iterator sr = vars.begin(); sr != vars.end(); sr++) {
if (sr->second.isNew) {
// Make sure we don't match a var in its defining statement
sr->second.isNew = false;
continue;
}
Binary *cur;
for (cur = ss; !cur->isNil(); cur = (Binary *)cur->getSubExp2()) {
if (sr->second.used)
break; // Don't bother; already know it's used
Exp *s = cur->getSubExp1();
if (!s) continue;
if (*s == *sr->second.base) {
sr->second.used = true;
break;
}
std::list<Exp *> res1, res2;
s->searchAll(sr->second.base, res1);
s->searchAll(sr->second.post, res2);
// Each match of a post will also match the base.
// But if there is a bare (non-post) use of the base, there will be a result in res1 that is not in res2
if (res1.size() > res2.size())
sr->second.used = true;
}
}
//.........这里部分代码省略.........
示例9: solve
bool Constraints::solve(std::list<ConstraintMap>& solns) {
LOG << conSet.size() << " constraints:";
std::ostringstream os; conSet.print(os); LOG << os.str().c_str();
// Replace Ta[loc] = ptr(alpha) with
// Tloc = alpha
LocationSet::iterator cc;
for (cc = conSet.begin(); cc != conSet.end(); cc++) {
Exp* c = *cc;
if (!c->isEquality()) continue;
Exp* left = ((Binary*)c)->getSubExp1();
if (!left->isTypeOf()) continue;
Exp* leftSub = ((Unary*)left)->getSubExp1();
if (!leftSub->isAddrOf()) continue;
Exp* right = ((Binary*)c)->getSubExp2();
if (!right->isTypeVal()) continue;
Type* t = ((TypeVal*)right)->getType();
if (!t->isPointer()) continue;
// Don't modify a key in a map
Exp* clone = c->clone();
// left is typeof(addressof(something)) -> typeof(something)
left = ((Binary*)clone)->getSubExp1();
leftSub = ((Unary*)left)->getSubExp1();
Exp* something = ((Unary*)leftSub)->getSubExp1();
((Unary*)left)->setSubExp1ND(something);
((Unary*)leftSub)->setSubExp1ND(NULL);
delete leftSub;
// right is <alpha*> -> <alpha>
right = ((Binary*)clone)->getSubExp2();
t = ((TypeVal*)right)->getType();
((TypeVal*)right)->setType(((PointerType*)t)->getPointsTo()->clone());
delete t;
conSet.remove(c);
conSet.insert(clone);
delete c;
}
// Sort constraints into a few categories. Disjunctions go to a special
// list, always true is just ignored, and constraints of the form
// typeof(x) = y (where y is a type value) go to a map called fixed.
// Constraint terms of the form Tx = Ty go into a map of LocationSets
// called equates for fast lookup
for (cc = conSet.begin(); cc != conSet.end(); cc++) {
Exp* c = *cc;
if (c->isTrue()) continue;
if (c->isFalse()) {
if (VERBOSE || DEBUG_TA)
LOG << "Constraint failure: always false constraint\n";
return false;
}
if (c->isDisjunction()) {
disjunctions.push_back(c);
continue;
}
// Break up conjunctions into terms
Exp* rem = c, *term;
while ((term = nextConjunct(rem)) != NULL) {
assert(term->isEquality());
Exp* lhs = ((Binary*)term)->getSubExp1();
Exp* rhs = ((Binary*)term)->getSubExp2();
if (rhs->isTypeOf()) {
// Of the form typeof(x) = typeof(z)
// Insert into equates
equates.addEquate(lhs, rhs);
} else {
// Of the form typeof(x) = <typeval>
// Insert into fixed
assert(rhs->isTypeVal());
fixed[lhs] = rhs;
}
}
}
{LOG << "\n" << (unsigned)disjunctions.size() << " disjunctions: "; std::list<Exp*>::iterator dd;
for (dd = disjunctions.begin(); dd != disjunctions.end(); dd++) LOG << *dd << ",\n"; LOG << "\n";}
LOG << fixed.size() << " fixed: " << fixed.prints();
LOG << equates.size() << " equates: " << equates.prints();
// Substitute the fixed types into the disjunctions
substIntoDisjuncts(fixed);
// Substitute the fixed types into the equates. This may generate more
// fixed types
substIntoEquates(fixed);
LOG << "\nAfter substitute fixed into equates:\n";
{LOG << "\n" << (unsigned)disjunctions.size() << " disjunctions: "; std::list<Exp*>::iterator dd;
for (dd = disjunctions.begin(); dd != disjunctions.end(); dd++) LOG << *dd << ",\n"; LOG << "\n";}
LOG << fixed.size() << " fixed: " << fixed.prints();
LOG << equates.size() << " equates: " << equates.prints();
// Substitute again the fixed types into the disjunctions
// (since there may be more fixed types from the above)
substIntoDisjuncts(fixed);
LOG << "\nAfter second substitute fixed into disjunctions:\n";
{LOG << "\n" << (unsigned)disjunctions.size() << " disjunctions: "; std::list<Exp*>::iterator dd;
for (dd = disjunctions.begin(); dd != disjunctions.end(); dd++) LOG << *dd << ",\n"; LOG << "\n";}
LOG << fixed.size() << " fixed: " << fixed.prints();
LOG << equates.size() << " equates: " << equates.prints();
ConstraintMap soln;
//.........这里部分代码省略.........