本文整理汇总了C++中SmallPtrSet::erase方法的典型用法代码示例。如果您正苦于以下问题:C++ SmallPtrSet::erase方法的具体用法?C++ SmallPtrSet::erase怎么用?C++ SmallPtrSet::erase使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类SmallPtrSet
的用法示例。
在下文中一共展示了SmallPtrSet::erase方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: RemoveAccessedObjects
/// RemoveAccessedObjects - Check to see if the specified location may alias any
/// of the stack objects in the DeadStackObjects set. If so, they become live
/// because the location is being loaded.
void DSE::RemoveAccessedObjects(const AliasAnalysis::Location &LoadedLoc,
SmallPtrSet<Value*, 16> &DeadStackObjects) {
const Value *UnderlyingPointer = LoadedLoc.Ptr->getUnderlyingObject();
// A constant can't be in the dead pointer set.
if (isa<Constant>(UnderlyingPointer))
return;
// If the kill pointer can be easily reduced to an alloca, don't bother doing
// extraneous AA queries.
if (isa<AllocaInst>(UnderlyingPointer) || isa<Argument>(UnderlyingPointer)) {
DeadStackObjects.erase(const_cast<Value*>(UnderlyingPointer));
return;
}
SmallVector<Value*, 16> NowLive;
for (SmallPtrSet<Value*, 16>::iterator I = DeadStackObjects.begin(),
E = DeadStackObjects.end(); I != E; ++I) {
// See if the loaded location could alias the stack location.
AliasAnalysis::Location StackLoc(*I, getPointerSize(*I, *AA));
if (!AA->isNoAlias(StackLoc, LoadedLoc))
NowLive.push_back(*I);
}
for (SmallVector<Value*, 16>::iterator I = NowLive.begin(), E = NowLive.end();
I != E; ++I)
DeadStackObjects.erase(*I);
}
示例2:
TEST(SmallPtrSetTest, GrowthTest) {
int i;
int buf[8];
for(i=0; i<8; ++i) buf[i]=0;
SmallPtrSet<int *, 4> s;
typedef SmallPtrSet<int *, 4>::iterator iter;
s.insert(&buf[0]);
s.insert(&buf[1]);
s.insert(&buf[2]);
s.insert(&buf[3]);
EXPECT_EQ(4U, s.size());
i = 0;
for(iter I=s.begin(), E=s.end(); I!=E; ++I, ++i)
(**I)++;
EXPECT_EQ(4, i);
for(i=0; i<8; ++i)
EXPECT_EQ(i<4?1:0,buf[i]);
s.insert(&buf[4]);
s.insert(&buf[5]);
s.insert(&buf[6]);
s.insert(&buf[7]);
i = 0;
for(iter I=s.begin(), E=s.end(); I!=E; ++I, ++i)
(**I)++;
EXPECT_EQ(8, i);
s.erase(&buf[4]);
s.erase(&buf[5]);
s.erase(&buf[6]);
s.erase(&buf[7]);
EXPECT_EQ(4U, s.size());
i = 0;
for(iter I=s.begin(), E=s.end(); I!=E; ++I, ++i)
(**I)++;
EXPECT_EQ(4, i);
for(i=0; i<8; ++i)
EXPECT_EQ(i<4?3:1,buf[i]);
s.clear();
for(i=0; i<8; ++i) buf[i]=0;
for(i=0; i<128; ++i) s.insert(&buf[i%8]); // test repeated entires
EXPECT_EQ(8U, s.size());
for(iter I=s.begin(), E=s.end(); I!=E; ++I, ++i)
(**I)++;
for(i=0; i<8; ++i)
EXPECT_EQ(1,buf[i]);
}
示例3: CollectBasicBlocks
/// \brief Find an insertion point that dominates all uses.
Instruction *ConstantHoisting::
FindConstantInsertionPoint(Function &F, const ConstantInfo &CI) const {
BasicBlock *Entry = &F.getEntryBlock();
// Collect all basic blocks.
SmallPtrSet<BasicBlock *, 4> BBs;
ConstantInfo::RebasedConstantListType::const_iterator RCI, RCE;
for (RCI = CI.RebasedConstants.begin(), RCE = CI.RebasedConstants.end();
RCI != RCE; ++RCI)
for (SmallVectorImpl<User *>::const_iterator U = RCI->Uses.begin(),
E = RCI->Uses.end(); U != E; ++U)
CollectBasicBlocks(BBs, F, *U);
if (BBs.count(Entry))
return Entry->getFirstInsertionPt();
while (BBs.size() >= 2) {
BasicBlock *BB, *BB1, *BB2;
BB1 = *BBs.begin();
BB2 = *llvm::next(BBs.begin());
BB = DT->findNearestCommonDominator(BB1, BB2);
if (BB == Entry)
return Entry->getFirstInsertionPt();
BBs.erase(BB1);
BBs.erase(BB2);
BBs.insert(BB);
}
assert((BBs.size() == 1) && "Expected only one element.");
return (*BBs.begin())->getFirstInsertionPt();
}
示例4: calcRegsPassed
// Calculate the largest possible vregsPassed sets. These are the registers that
// can pass through an MBB live, but may not be live every time. It is assumed
// that all vregsPassed sets are empty before the call.
void MachineVerifier::calcRegsPassed() {
// First push live-out regs to successors' vregsPassed. Remember the MBBs that
// have any vregsPassed.
SmallPtrSet<const MachineBasicBlock*, 8> todo;
for (MachineFunction::const_iterator MFI = MF->begin(), MFE = MF->end();
MFI != MFE; ++MFI) {
const MachineBasicBlock &MBB(*MFI);
BBInfo &MInfo = MBBInfoMap[&MBB];
if (!MInfo.reachable)
continue;
for (MachineBasicBlock::const_succ_iterator SuI = MBB.succ_begin(),
SuE = MBB.succ_end(); SuI != SuE; ++SuI) {
BBInfo &SInfo = MBBInfoMap[*SuI];
if (SInfo.addPassed(MInfo.regsLiveOut))
todo.insert(*SuI);
}
}
// Iteratively push vregsPassed to successors. This will converge to the same
// final state regardless of DenseSet iteration order.
while (!todo.empty()) {
const MachineBasicBlock *MBB = *todo.begin();
todo.erase(MBB);
BBInfo &MInfo = MBBInfoMap[MBB];
for (MachineBasicBlock::const_succ_iterator SuI = MBB->succ_begin(),
SuE = MBB->succ_end(); SuI != SuE; ++SuI) {
if (*SuI == MBB)
continue;
BBInfo &SInfo = MBBInfoMap[*SuI];
if (SInfo.addPassed(MInfo.vregsPassed))
todo.insert(*SuI);
}
}
}
示例5: calcRegsRequired
// Calculate the set of virtual registers that must be passed through each basic
// block in order to satisfy the requirements of successor blocks. This is very
// similar to calcRegsPassed, only backwards.
void MachineVerifier::calcRegsRequired() {
// First push live-in regs to predecessors' vregsRequired.
SmallPtrSet<const MachineBasicBlock*, 8> todo;
for (MachineFunction::const_iterator MFI = MF->begin(), MFE = MF->end();
MFI != MFE; ++MFI) {
const MachineBasicBlock &MBB(*MFI);
BBInfo &MInfo = MBBInfoMap[&MBB];
for (MachineBasicBlock::const_pred_iterator PrI = MBB.pred_begin(),
PrE = MBB.pred_end(); PrI != PrE; ++PrI) {
BBInfo &PInfo = MBBInfoMap[*PrI];
if (PInfo.addRequired(MInfo.vregsLiveIn))
todo.insert(*PrI);
}
}
// Iteratively push vregsRequired to predecessors. This will converge to the
// same final state regardless of DenseSet iteration order.
while (!todo.empty()) {
const MachineBasicBlock *MBB = *todo.begin();
todo.erase(MBB);
BBInfo &MInfo = MBBInfoMap[MBB];
for (MachineBasicBlock::const_pred_iterator PrI = MBB->pred_begin(),
PrE = MBB->pred_end(); PrI != PrE; ++PrI) {
if (*PrI == MBB)
continue;
BBInfo &SInfo = MBBInfoMap[*PrI];
if (SInfo.addRequired(MInfo.vregsRequired))
todo.insert(*PrI);
}
}
}
示例6: findMatInsertPt
/// \brief Find an insertion point that dominates all uses.
Instruction *ConstantHoistingPass::findConstantInsertionPoint(
const ConstantInfo &ConstInfo) const {
assert(!ConstInfo.RebasedConstants.empty() && "Invalid constant info entry.");
// Collect all basic blocks.
SmallPtrSet<BasicBlock *, 8> BBs;
for (auto const &RCI : ConstInfo.RebasedConstants)
for (auto const &U : RCI.Uses)
BBs.insert(findMatInsertPt(U.Inst, U.OpndIdx)->getParent());
if (BBs.count(Entry))
return &Entry->front();
while (BBs.size() >= 2) {
BasicBlock *BB, *BB1, *BB2;
BB1 = *BBs.begin();
BB2 = *std::next(BBs.begin());
BB = DT->findNearestCommonDominator(BB1, BB2);
if (BB == Entry)
return &Entry->front();
BBs.erase(BB1);
BBs.erase(BB2);
BBs.insert(BB);
}
assert((BBs.size() == 1) && "Expected only one element.");
Instruction &FirstInst = (*BBs.begin())->front();
return findMatInsertPt(&FirstInst);
}
示例7: UpdateGVDependencies
void GlobalDCEPass::UpdateGVDependencies(GlobalValue &GV) {
SmallPtrSet<GlobalValue *, 8> Deps;
for (User *User : GV.users())
ComputeDependencies(User, Deps);
Deps.erase(&GV); // Remove self-reference.
for (GlobalValue *GVU : Deps) {
GVDependencies.insert(std::make_pair(GVU, &GV));
}
}
示例8: assert
/// Find an insertion point that dominates all uses.
SmallPtrSet<Instruction *, 8> ConstantHoistingPass::findConstantInsertionPoint(
const ConstantInfo &ConstInfo) const {
assert(!ConstInfo.RebasedConstants.empty() && "Invalid constant info entry.");
// Collect all basic blocks.
SmallPtrSet<BasicBlock *, 8> BBs;
SmallPtrSet<Instruction *, 8> InsertPts;
for (auto const &RCI : ConstInfo.RebasedConstants)
for (auto const &U : RCI.Uses)
BBs.insert(findMatInsertPt(U.Inst, U.OpndIdx)->getParent());
if (BBs.count(Entry)) {
InsertPts.insert(&Entry->front());
return InsertPts;
}
if (BFI) {
findBestInsertionSet(*DT, *BFI, Entry, BBs);
for (auto BB : BBs) {
BasicBlock::iterator InsertPt = BB->begin();
for (; isa<PHINode>(InsertPt) || InsertPt->isEHPad(); ++InsertPt)
;
InsertPts.insert(&*InsertPt);
}
return InsertPts;
}
while (BBs.size() >= 2) {
BasicBlock *BB, *BB1, *BB2;
BB1 = *BBs.begin();
BB2 = *std::next(BBs.begin());
BB = DT->findNearestCommonDominator(BB1, BB2);
if (BB == Entry) {
InsertPts.insert(&Entry->front());
return InsertPts;
}
BBs.erase(BB1);
BBs.erase(BB2);
BBs.insert(BB);
}
assert((BBs.size() == 1) && "Expected only one element.");
Instruction &FirstInst = (*BBs.begin())->front();
InsertPts.insert(findMatInsertPt(&FirstInst));
return InsertPts;
}
示例9:
/// Return a set of basic blocks to insert sinked instructions.
///
/// The returned set of basic blocks (BBsToSinkInto) should satisfy:
///
/// * Inside the loop \p L
/// * For each UseBB in \p UseBBs, there is at least one BB in BBsToSinkInto
/// that domintates the UseBB
/// * Has minimum total frequency that is no greater than preheader frequency
///
/// The purpose of the function is to find the optimal sinking points to
/// minimize execution cost, which is defined as "sum of frequency of
/// BBsToSinkInto".
/// As a result, the returned BBsToSinkInto needs to have minimum total
/// frequency.
/// Additionally, if the total frequency of BBsToSinkInto exceeds preheader
/// frequency, the optimal solution is not sinking (return empty set).
///
/// \p ColdLoopBBs is used to help find the optimal sinking locations.
/// It stores a list of BBs that is:
///
/// * Inside the loop \p L
/// * Has a frequency no larger than the loop's preheader
/// * Sorted by BB frequency
///
/// The complexity of the function is O(UseBBs.size() * ColdLoopBBs.size()).
/// To avoid expensive computation, we cap the maximum UseBBs.size() in its
/// caller.
static SmallPtrSet<BasicBlock *, 2>
findBBsToSinkInto(const Loop &L, const SmallPtrSetImpl<BasicBlock *> &UseBBs,
const SmallVectorImpl<BasicBlock *> &ColdLoopBBs,
DominatorTree &DT, BlockFrequencyInfo &BFI) {
SmallPtrSet<BasicBlock *, 2> BBsToSinkInto;
if (UseBBs.size() == 0)
return BBsToSinkInto;
BBsToSinkInto.insert(UseBBs.begin(), UseBBs.end());
SmallPtrSet<BasicBlock *, 2> BBsDominatedByColdestBB;
// For every iteration:
// * Pick the ColdestBB from ColdLoopBBs
// * Find the set BBsDominatedByColdestBB that satisfy:
// - BBsDominatedByColdestBB is a subset of BBsToSinkInto
// - Every BB in BBsDominatedByColdestBB is dominated by ColdestBB
// * If Freq(ColdestBB) < Freq(BBsDominatedByColdestBB), remove
// BBsDominatedByColdestBB from BBsToSinkInto, add ColdestBB to
// BBsToSinkInto
for (BasicBlock *ColdestBB : ColdLoopBBs) {
BBsDominatedByColdestBB.clear();
for (BasicBlock *SinkedBB : BBsToSinkInto)
if (DT.dominates(ColdestBB, SinkedBB))
BBsDominatedByColdestBB.insert(SinkedBB);
if (BBsDominatedByColdestBB.size() == 0)
continue;
if (adjustedSumFreq(BBsDominatedByColdestBB, BFI) >
BFI.getBlockFreq(ColdestBB)) {
for (BasicBlock *DominatedBB : BBsDominatedByColdestBB) {
BBsToSinkInto.erase(DominatedBB);
}
BBsToSinkInto.insert(ColdestBB);
}
}
// If the total frequency of BBsToSinkInto is larger than preheader frequency,
// do not sink.
if (adjustedSumFreq(BBsToSinkInto, BFI) >
BFI.getBlockFreq(L.getLoopPreheader()))
BBsToSinkInto.clear();
return BBsToSinkInto;
}
示例10: computeDFS
/// computeDFS - Computes the DFS-in and DFS-out numbers of the dominator tree
/// of the given MachineFunction. These numbers are then used in other parts
/// of the PHI elimination process.
void StrongPHIElimination::computeDFS(MachineFunction& MF) {
SmallPtrSet<MachineDomTreeNode*, 8> frontier;
SmallPtrSet<MachineDomTreeNode*, 8> visited;
unsigned time = 0;
MachineDominatorTree& DT = getAnalysis<MachineDominatorTree>();
MachineDomTreeNode* node = DT.getRootNode();
std::vector<MachineDomTreeNode*> worklist;
worklist.push_back(node);
while (!worklist.empty()) {
MachineDomTreeNode* currNode = worklist.back();
if (!frontier.count(currNode)) {
frontier.insert(currNode);
++time;
preorder.insert(std::make_pair(currNode->getBlock(), time));
}
bool inserted = false;
for (MachineDomTreeNode::iterator I = currNode->begin(), E = currNode->end();
I != E; ++I)
if (!frontier.count(*I) && !visited.count(*I)) {
worklist.push_back(*I);
inserted = true;
break;
}
if (!inserted) {
frontier.erase(currNode);
visited.insert(currNode);
maxpreorder.insert(std::make_pair(currNode->getBlock(), time));
worklist.pop_back();
}
}
}
示例11: while
/// \brief Find nearest common dominator of all uses.
/// FIXME: Replace this with NearestCommonDominator once it is in common code.
BasicBlock *
ConstantHoisting::findIDomOfAllUses(const ConstantUseListType &Uses) const {
// Collect all basic blocks.
SmallPtrSet<BasicBlock *, 8> BBs;
for (auto const &U : Uses)
BBs.insert(findMatInsertPt(U.Inst, U.OpndIdx)->getParent());
if (BBs.count(Entry))
return Entry;
while (BBs.size() >= 2) {
BasicBlock *BB, *BB1, *BB2;
BB1 = *BBs.begin();
BB2 = *std::next(BBs.begin());
BB = DT->findNearestCommonDominator(BB1, BB2);
if (BB == Entry)
return Entry;
BBs.erase(BB1);
BBs.erase(BB2);
BBs.insert(BB);
}
assert((BBs.size() == 1) && "Expected only one element.");
return *BBs.begin();
}
示例12: TGError
const CodeGenRegister::SubRegMap &
CodeGenRegister::getSubRegs(CodeGenRegBank &RegBank) {
// Only compute this map once.
if (SubRegsComplete)
return SubRegs;
SubRegsComplete = true;
std::vector<Record*> SubList = TheDef->getValueAsListOfDefs("SubRegs");
std::vector<Record*> IdxList = TheDef->getValueAsListOfDefs("SubRegIndices");
if (SubList.size() != IdxList.size())
throw TGError(TheDef->getLoc(), "Register " + getName() +
" SubRegIndices doesn't match SubRegs");
// First insert the direct subregs and make sure they are fully indexed.
SmallVector<CodeGenSubRegIndex*, 8> Indices;
for (unsigned i = 0, e = SubList.size(); i != e; ++i) {
CodeGenRegister *SR = RegBank.getReg(SubList[i]);
CodeGenSubRegIndex *Idx = RegBank.getSubRegIdx(IdxList[i]);
Indices.push_back(Idx);
if (!SubRegs.insert(std::make_pair(Idx, SR)).second)
throw TGError(TheDef->getLoc(), "SubRegIndex " + Idx->getName() +
" appears twice in Register " + getName());
}
// Keep track of inherited subregs and how they can be reached.
SmallPtrSet<CodeGenRegister*, 8> Orphans;
// Clone inherited subregs and place duplicate entries in Orphans.
// Here the order is important - earlier subregs take precedence.
for (unsigned i = 0, e = SubList.size(); i != e; ++i) {
CodeGenRegister *SR = RegBank.getReg(SubList[i]);
const SubRegMap &Map = SR->getSubRegs(RegBank);
// Add this as a super-register of SR now all sub-registers are in the list.
// This creates a topological ordering, the exact order depends on the
// order getSubRegs is called on all registers.
SR->SuperRegs.push_back(this);
for (SubRegMap::const_iterator SI = Map.begin(), SE = Map.end(); SI != SE;
++SI) {
if (!SubRegs.insert(*SI).second)
Orphans.insert(SI->second);
// Noop sub-register indexes are possible, so avoid duplicates.
if (SI->second != SR)
SI->second->SuperRegs.push_back(this);
}
}
// Expand any composed subreg indices.
// If dsub_2 has ComposedOf = [qsub_1, dsub_0], and this register has a
// qsub_1 subreg, add a dsub_2 subreg. Keep growing Indices and process
// expanded subreg indices recursively.
for (unsigned i = 0; i != Indices.size(); ++i) {
CodeGenSubRegIndex *Idx = Indices[i];
const CodeGenSubRegIndex::CompMap &Comps = Idx->getComposites();
CodeGenRegister *SR = SubRegs[Idx];
const SubRegMap &Map = SR->getSubRegs(RegBank);
// Look at the possible compositions of Idx.
// They may not all be supported by SR.
for (CodeGenSubRegIndex::CompMap::const_iterator I = Comps.begin(),
E = Comps.end(); I != E; ++I) {
SubRegMap::const_iterator SRI = Map.find(I->first);
if (SRI == Map.end())
continue; // Idx + I->first doesn't exist in SR.
// Add I->second as a name for the subreg SRI->second, assuming it is
// orphaned, and the name isn't already used for something else.
if (SubRegs.count(I->second) || !Orphans.erase(SRI->second))
continue;
// We found a new name for the orphaned sub-register.
SubRegs.insert(std::make_pair(I->second, SRI->second));
Indices.push_back(I->second);
}
}
// Process the composites.
ListInit *Comps = TheDef->getValueAsListInit("CompositeIndices");
for (unsigned i = 0, e = Comps->size(); i != e; ++i) {
DagInit *Pat = dynamic_cast<DagInit*>(Comps->getElement(i));
if (!Pat)
throw TGError(TheDef->getLoc(), "Invalid dag '" +
Comps->getElement(i)->getAsString() +
"' in CompositeIndices");
DefInit *BaseIdxInit = dynamic_cast<DefInit*>(Pat->getOperator());
if (!BaseIdxInit || !BaseIdxInit->getDef()->isSubClassOf("SubRegIndex"))
throw TGError(TheDef->getLoc(), "Invalid SubClassIndex in " +
Pat->getAsString());
CodeGenSubRegIndex *BaseIdx = RegBank.getSubRegIdx(BaseIdxInit->getDef());
// Resolve list of subreg indices into R2.
CodeGenRegister *R2 = this;
for (DagInit::const_arg_iterator di = Pat->arg_begin(),
de = Pat->arg_end(); di != de; ++di) {
DefInit *IdxInit = dynamic_cast<DefInit*>(*di);
if (!IdxInit || !IdxInit->getDef()->isSubClassOf("SubRegIndex"))
throw TGError(TheDef->getLoc(), "Invalid SubClassIndex in " +
Pat->getAsString());
CodeGenSubRegIndex *Idx = RegBank.getSubRegIdx(IdxInit->getDef());
const SubRegMap &R2Subs = R2->getSubRegs(RegBank);
//.........这里部分代码省略.........
示例13: runOnMachineFunction
bool PeepholeOptimizer::runOnMachineFunction(MachineFunction &MF) {
if (DisablePeephole)
return false;
TM = &MF.getTarget();
TII = TM->getInstrInfo();
MRI = &MF.getRegInfo();
DT = Aggressive ? &getAnalysis<MachineDominatorTree>() : 0;
bool Changed = false;
SmallPtrSet<MachineInstr*, 8> LocalMIs;
SmallSet<unsigned, 4> ImmDefRegs;
DenseMap<unsigned, MachineInstr*> ImmDefMIs;
for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) {
MachineBasicBlock *MBB = &*I;
bool SeenMoveImm = false;
LocalMIs.clear();
ImmDefRegs.clear();
ImmDefMIs.clear();
bool First = true;
MachineBasicBlock::iterator PMII;
for (MachineBasicBlock::iterator
MII = I->begin(), MIE = I->end(); MII != MIE; ) {
MachineInstr *MI = &*MII;
LocalMIs.insert(MI);
if (MI->isLabel() || MI->isPHI() || MI->isImplicitDef() ||
MI->isKill() || MI->isInlineAsm() || MI->isDebugValue() ||
MI->hasUnmodeledSideEffects()) {
++MII;
continue;
}
if (MI->isBitcast()) {
if (optimizeBitcastInstr(MI, MBB)) {
// MI is deleted.
LocalMIs.erase(MI);
Changed = true;
MII = First ? I->begin() : llvm::next(PMII);
continue;
}
} else if (MI->isCompare()) {
if (optimizeCmpInstr(MI, MBB)) {
// MI is deleted.
LocalMIs.erase(MI);
Changed = true;
MII = First ? I->begin() : llvm::next(PMII);
continue;
}
}
if (isMoveImmediate(MI, ImmDefRegs, ImmDefMIs)) {
SeenMoveImm = true;
} else {
Changed |= optimizeExtInstr(MI, MBB, LocalMIs);
if (SeenMoveImm)
Changed |= foldImmediate(MI, MBB, ImmDefRegs, ImmDefMIs);
}
First = false;
PMII = MII;
++MII;
}
}
return Changed;
}
示例14: FindBackAndExitEdges
/// FindBackAndExitEdges - Search for back and exit edges for all blocks
/// within the function loops, calculated using loop information.
void BranchPredictionInfo::FindBackAndExitEdges(Function &F) {
SmallPtrSet<const BasicBlock *, 64> LoopsVisited;
SmallPtrSet<const BasicBlock *, 64> BlocksVisited;
int count = 0;
if(F.getName() == "hypre_SMGResidual")
count = count + 1;
for (LoopInfo::iterator LIT = LI->begin(), LIE = LI->end();
LIT != LIE; ++LIT) {
Loop *rootLoop = *LIT;
BasicBlock *rootHeader = rootLoop->getHeader();
// Check if we already visited this loop.
if (LoopsVisited.count(rootHeader))
continue;
// Create a stack to hold loops (inner most on the top).
SmallVectorImpl<Loop *> Stack(8);
SmallPtrSet<const BasicBlock *, 8> InStack;
// Put the current loop into the Stack.
Stack.push_back(rootLoop);
InStack.insert(rootHeader);
do {
Loop *loop = Stack.back();
// Search for new inner loops.
bool foundNew = false;
for (Loop::iterator I = loop->begin(), E = loop->end(); I != E; ++I) {
Loop *innerLoop = *I;
BasicBlock *innerHeader = innerLoop->getHeader();
// Skip visited inner loops.
if (!LoopsVisited.count(innerHeader)) {
Stack.push_back(innerLoop);
InStack.insert(innerHeader);
foundNew = true;
break;
}
}
// If a new loop is found, continue.
// Otherwise, it is time to expand it, because it is the most inner loop
// yet unprocessed.
if (foundNew)
continue;
// The variable "loop" is now the unvisited inner most loop.
BasicBlock *header = loop->getHeader();
// Search for all basic blocks on the loop.
for (Loop::block_iterator LBI = loop->block_begin(),
LBE = loop->block_end(); LBI != LBE; ++LBI) {
BasicBlock *lpBB = *LBI;
if (!BlocksVisited.insert(lpBB))
continue;
// Set the number of back edges to this loop head (lpBB) as zero.
BackEdgesCount[lpBB] = 0;
// For each loop block successor, check if the block pointing is
// outside the loop.
TerminatorInst *TI = lpBB->getTerminator();
for (unsigned s = 0; s < TI->getNumSuccessors(); ++s) {
BasicBlock *successor = TI->getSuccessor(s);
Edge edge = std::make_pair(lpBB, successor);
// If the successor matches any loop header on the stack,
// then it is a backedge.
if (InStack.count(successor)) {
listBackEdges.insert(edge);
++BackEdgesCount[lpBB];
}
// If the successor is not present in the loop block list, then it is
// an exit edge.
if (!loop->contains(successor))
listExitEdges.insert(edge);
}
}
// Cleaning the visited loop.
LoopsVisited.insert(header);
Stack.pop_back();
InStack.erase(header);
} while (!InStack.empty());
}
}
示例15: VisitLoop
bool WebAssemblyFixIrreducibleControlFlow::VisitLoop(MachineFunction &MF,
MachineLoopInfo &MLI,
MachineLoop *Loop) {
MachineBasicBlock *Header = Loop ? Loop->getHeader() : &*MF.begin();
SetVector<MachineBasicBlock *> RewriteSuccs;
// DFS through Loop's body, looking for for irreducible control flow. Loop is
// natural, and we stay in its body, and we treat any nested loops
// monolithically, so any cycles we encounter indicate irreducibility.
SmallPtrSet<MachineBasicBlock *, 8> OnStack;
SmallPtrSet<MachineBasicBlock *, 8> Visited;
SmallVector<SuccessorList, 4> LoopWorklist;
LoopWorklist.push_back(SuccessorList(Header));
OnStack.insert(Header);
Visited.insert(Header);
while (!LoopWorklist.empty()) {
SuccessorList &Top = LoopWorklist.back();
if (Top.HasNext()) {
MachineBasicBlock *Next = Top.Next();
if (Next == Header || (Loop && !Loop->contains(Next)))
continue;
if (LLVM_LIKELY(OnStack.insert(Next).second)) {
if (!Visited.insert(Next).second) {
OnStack.erase(Next);
continue;
}
MachineLoop *InnerLoop = MLI.getLoopFor(Next);
if (InnerLoop != Loop)
LoopWorklist.push_back(SuccessorList(InnerLoop));
else
LoopWorklist.push_back(SuccessorList(Next));
} else {
RewriteSuccs.insert(Top.getBlock());
}
continue;
}
OnStack.erase(Top.getBlock());
LoopWorklist.pop_back();
}
// Most likely, we didn't find any irreducible control flow.
if (LLVM_LIKELY(RewriteSuccs.empty()))
return false;
DEBUG(dbgs() << "Irreducible control flow detected!\n");
// Ok. We have irreducible control flow! Create a dispatch block which will
// contains a jump table to any block in the problematic set of blocks.
MachineBasicBlock *Dispatch = MF.CreateMachineBasicBlock();
MF.insert(MF.end(), Dispatch);
MLI.changeLoopFor(Dispatch, Loop);
// Add the jump table.
const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
MachineInstrBuilder MIB = BuildMI(*Dispatch, Dispatch->end(), DebugLoc(),
TII.get(WebAssembly::BR_TABLE_I32));
// Add the register which will be used to tell the jump table which block to
// jump to.
MachineRegisterInfo &MRI = MF.getRegInfo();
unsigned Reg = MRI.createVirtualRegister(&WebAssembly::I32RegClass);
MIB.addReg(Reg);
// Collect all the blocks which need to have their successors rewritten,
// add the successors to the jump table, and remember their index.
DenseMap<MachineBasicBlock *, unsigned> Indices;
SmallVector<MachineBasicBlock *, 4> SuccWorklist(RewriteSuccs.begin(),
RewriteSuccs.end());
while (!SuccWorklist.empty()) {
MachineBasicBlock *MBB = SuccWorklist.pop_back_val();
auto Pair = Indices.insert(std::make_pair(MBB, 0));
if (!Pair.second)
continue;
unsigned Index = MIB.getInstr()->getNumExplicitOperands() - 1;
DEBUG(dbgs() << printMBBReference(*MBB) << " has index " << Index << "\n");
Pair.first->second = Index;
for (auto Pred : MBB->predecessors())
RewriteSuccs.insert(Pred);
MIB.addMBB(MBB);
Dispatch->addSuccessor(MBB);
MetaBlock Meta(MBB);
for (auto *Succ : Meta.successors())
if (Succ != Header && (!Loop || Loop->contains(Succ)))
SuccWorklist.push_back(Succ);
}
// Rewrite the problematic successors for every block in RewriteSuccs.
// For simplicity, we just introduce a new block for every edge we need to
// rewrite. Fancier things are possible.
for (MachineBasicBlock *MBB : RewriteSuccs) {
DenseMap<MachineBasicBlock *, MachineBasicBlock *> Map;
for (auto *Succ : MBB->successors()) {
if (!Indices.count(Succ))
continue;
MachineBasicBlock *Split = MF.CreateMachineBasicBlock();
//.........这里部分代码省略.........