本文整理汇总了C++中PBB::getFirstStmt方法的典型用法代码示例。如果您正苦于以下问题:C++ PBB::getFirstStmt方法的具体用法?C++ PBB::getFirstStmt怎么用?C++ PBB::getFirstStmt使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类PBB
的用法示例。
在下文中一共展示了PBB::getFirstStmt方法的5个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: findLiveAtDomPhi
// Helper function for UserProc::propagateStatements()
// Works on basic block n; call from UserProc with n=0 (entry BB)
// If an SSA location is in usedByDomPhi it means it is used in a phi that dominates its assignment
// However, it could turn out that the phi is dead, in which case we don't want to keep the associated entries in
// usedByDomPhi. So we maintain the map defdByPhi which maps locations defined at a phi to the phi statements. Every
// time we see a use of a location in defdByPhi, we remove that map entry. At the end of the procedure we therefore have
// only dead phi statements in the map, so we can delete the associated entries in defdByPhi and also remove the dead
// phi statements.
// We add to the set usedByDomPhi0 whenever we see a location referenced by a phi parameter. When we see a definition
// for such a location, we remove it from the usedByDomPhi0 set (to save memory) and add it to the usedByDomPhi set.
// For locations defined before they are used in a phi parameter, there will be no entry in usedByDomPhi, so we ignore
// it. Remember that each location is defined only once, so that's the time to decide if it is dominated by a phi use or
// not.
void DataFlow::findLiveAtDomPhi(int n, LocationSet& usedByDomPhi, LocationSet& usedByDomPhi0,
std::map<Exp*, PhiAssign*, lessExpStar>& defdByPhi) {
// For each statement this BB
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->isPhi()) {
// For each phi parameter, insert an entry into usedByDomPhi0
PhiAssign* pa = (PhiAssign*)S;
PhiAssign::iterator it;
for (it = pa->begin(); it != pa->end(); ++it) {
if (it->e) {
RefExp* re = new RefExp(it->e, it->def);
usedByDomPhi0.insert(re);
}
}
// Insert an entry into the defdByPhi map
RefExp* wrappedLhs = new RefExp(pa->getLeft(), pa);
defdByPhi[wrappedLhs] = pa;
// Fall through to the below, because phi uses are also legitimate uses
}
LocationSet ls;
S->addUsedLocs(ls);
// Consider uses of this statement
LocationSet::iterator it;
for (it = ls.begin(); it != ls.end(); ++it) {
// Remove this entry from the map, since it is not unused
defdByPhi.erase(*it);
}
// Now process any definitions
ls.clear();
S->getDefinitions(ls);
for (it = ls.begin(); it != ls.end(); ++it) {
RefExp* wrappedDef = new RefExp(*it, S);
// If this definition is in the usedByDomPhi0 set, then it is in fact dominated by a phi use, so move it to
// the final usedByDomPhi set
if (usedByDomPhi0.find(wrappedDef) != usedByDomPhi0.end()) {
usedByDomPhi0.remove(wrappedDef);
usedByDomPhi.insert(wrappedDef);
}
}
}
// Visit each child in the dominator graph
// Note: this is a linear search!
// Note also that usedByDomPhi0 may have some irrelevant entries, but this will do no harm, and attempting to erase
// the irrelevant ones would probably cost more than leaving them alone
int sz = idom.size();
for (int c = 0; c < sz; ++c) {
if (idom[c] != n) continue;
// Recurse to the child
findLiveAtDomPhi(c, usedByDomPhi, usedByDomPhi0, defdByPhi);
}
}
示例2: setDominanceNums
void DataFlow::setDominanceNums(int n, int& currNum) {
BasicBlock::rtlit rit; StatementList::iterator sit;
PBB bb = BBs[n];
Statement* S;
for (S = bb->getFirstStmt(rit, sit); S; S = bb->getNextStmt(rit, sit))
S->setDomNumber(currNum++);
int sz = idom.size();
for (int c = 0; c < sz; ++c) {
if (idom[c] != n) continue;
// Recurse to the child
setDominanceNums(c, currNum);
}
}
示例3: createReturnBlock
/*==============================================================================
* FUNCTION: createReturnBlock
* OVERVIEW: Create a Return or a Oneway BB if a return statement already exists
* PARAMETERS: pProc: pointer to enclosing UserProc
* BB_rtls: list of RTLs for the current BB (not including pRtl)
* pRtl: pointer to the current RTL with the semantics for the return statement (including a
* ReturnStatement as the last statement)
* RETURNS: Pointer to the newly created BB
*============================================================================*/
PBB FrontEnd::createReturnBlock(UserProc* pProc, std::list<RTL*>* BB_rtls, RTL* pRtl) {
Cfg* pCfg = pProc->getCFG();
PBB pBB;
// Add the RTL to the list; this has the semantics for the return instruction as well as the ReturnStatement
// The last Statement may get replaced with a GotoStatement
if (BB_rtls == NULL) BB_rtls = new std::list<RTL*>; // In case no other semantics
BB_rtls->push_back(pRtl);
ADDRESS retAddr = pProc->getTheReturnAddr();
std::cout << "retAddr = " << std::hex << retAddr << " rtl = " <<std::hex<< pRtl->getAddress() << "\n";
// LOG << "retAddr = " << retAddr << " rtl = " << pRtl->getAddress() << "\n";
if (retAddr == NO_ADDRESS) {
// Create the basic block
pBB = pCfg->newBB(BB_rtls, RET, 0);
Statement* s = pRtl->getList().back(); // The last statement should be the ReturnStatement
pProc->setTheReturnAddr((ReturnStatement*)s, pRtl->getAddress());
} else {
// We want to replace the *whole* RTL with a branch to THE first return's RTL. There can sometimes be extra
// semantics associated with a return (e.g. Pentium return adds to the stack pointer before setting %pc and
// branching). Other semantics (e.g. SPARC returning a value as part of the restore instruction) are assumed to
// appear in a previous RTL. It is assumed that THE return statement will have the same semantics (NOTE: may
// not always be valid). To avoid this assumption, we need branches to statements, not just to native addresses
// (RTLs).
PBB retBB = pProc->getCFG()->findRetNode();
assert(retBB);
if (retBB->getFirstStmt()->isReturn()) {
// ret node has no semantics, clearly we need to keep ours
pRtl->deleteLastStmt();
} else
pRtl->clear();
pRtl->appendStmt(new GotoStatement(retAddr));
try {
pBB = pCfg->newBB(BB_rtls, ONEWAY, 1);
// if BB already exists but is incomplete, exception is thrown
pCfg->addOutEdge(pBB, retAddr, true);
// Visit the return instruction. This will be needed in most cases to split the return BB (if it has other
// instructions before the return instruction).
targetQueue.visit(pCfg, retAddr, pBB);
} catch(Cfg::BBAlreadyExistsError &) {
if (VERBOSE)
LOG << "not visiting " << retAddr << " due to exception\n";
}
}
return pBB;
}
示例4: 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
//.........这里部分代码省略.........
示例5: 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