本文整理汇总了C++中DominatorTreeWrapperPass类的典型用法代码示例。如果您正苦于以下问题:C++ DominatorTreeWrapperPass类的具体用法?C++ DominatorTreeWrapperPass怎么用?C++ DominatorTreeWrapperPass使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了DominatorTreeWrapperPass类的10个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: runOnFunction
bool StackProtector::runOnFunction(Function &Fn) {
F = &Fn;
M = F->getParent();
DominatorTreeWrapperPass *DTWP =
getAnalysisIfAvailable<DominatorTreeWrapperPass>();
DT = DTWP ? &DTWP->getDomTree() : nullptr;
TLI = TM->getSubtargetImpl(Fn)->getTargetLowering();
HasPrologue = false;
HasIRCheck = false;
Attribute Attr = Fn.getFnAttribute("stack-protector-buffer-size");
if (Attr.isStringAttribute() &&
Attr.getValueAsString().getAsInteger(10, SSPBufferSize))
return false; // Invalid integer string
if (!RequiresStackProtector())
return false;
// TODO(etienneb): Functions with funclets are not correctly supported now.
// Do nothing if this is funclet-based personality.
if (Fn.hasPersonalityFn()) {
EHPersonality Personality = classifyEHPersonality(Fn.getPersonalityFn());
if (isFuncletEHPersonality(Personality))
return false;
}
++NumFunProtected;
return InsertStackProtectors();
}
示例2: runOnLoop
bool LoopUnswitch::runOnLoop(Loop *L, LPPassManager &LPM_Ref) {
if (skipOptnoneFunction(L))
return false;
LI = &getAnalysis<LoopInfo>();
LPM = &LPM_Ref;
DominatorTreeWrapperPass *DTWP =
getAnalysisIfAvailable<DominatorTreeWrapperPass>();
DT = DTWP ? &DTWP->getDomTree() : 0;
currentLoop = L;
Function *F = currentLoop->getHeader()->getParent();
bool Changed = false;
do {
assert(currentLoop->isLCSSAForm(*DT));
redoLoop = false;
Changed |= processCurrentLoop();
} while(redoLoop);
if (Changed) {
// FIXME: Reconstruct dom info, because it is not preserved properly.
if (DT)
DT->recalculate(*F);
}
return Changed;
}
示例3: FindContextVariables
void LowerEmAsyncify::FindContextVariables(AsyncCallEntry & Entry) {
BasicBlock *AfterCallBlock = Entry.AfterCallBlock;
Function & F = *AfterCallBlock->getParent();
// Create a new entry block as if in the callback function
// theck check variables that no longer properly dominate their uses
BasicBlock *EntryBlock = BasicBlock::Create(TheModule->getContext(), "", &F, &F.getEntryBlock());
BranchInst::Create(AfterCallBlock, EntryBlock);
DominatorTreeWrapperPass DTW;
DTW.runOnFunction(F);
DominatorTree& DT = DTW.getDomTree();
// These blocks may be using some values defined at or before AsyncCallBlock
BasicBlockSet Ramifications = FindReachableBlocksFrom(AfterCallBlock);
SmallPtrSet<Value*, 256> ContextVariables;
Values Pending;
// Examine the instructions, find all variables that we need to store in the context
for (BasicBlockSet::iterator RI = Ramifications.begin(), RE = Ramifications.end(); RI != RE; ++RI) {
for (BasicBlock::iterator I = (*RI)->begin(), E = (*RI)->end(); I != E; ++I) {
for (unsigned i = 0, NumOperands = I->getNumOperands(); i < NumOperands; ++i) {
Value *O = I->getOperand(i);
if (Instruction *Inst = dyn_cast<Instruction>(O)) {
if (Inst == Entry.AsyncCallInst) continue; // for the original async call, we will load directly from async return value
if (ContextVariables.count(Inst) != 0) continue; // already examined
if (!DT.dominates(Inst, I->getOperandUse(i))) {
// `I` is using `Inst`, yet `Inst` does not dominate `I` if we arrive directly at AfterCallBlock
// so we need to save `Inst` in the context
ContextVariables.insert(Inst);
Pending.push_back(Inst);
}
} else if (Argument *Arg = dyn_cast<Argument>(O)) {
// count() should be as fast/slow as insert, so just insert here
ContextVariables.insert(Arg);
}
}
}
}
// restore F
EntryBlock->eraseFromParent();
Entry.ContextVariables.clear();
Entry.ContextVariables.reserve(ContextVariables.size());
for (SmallPtrSet<Value*, 256>::iterator I = ContextVariables.begin(), E = ContextVariables.end(); I != E; ++I) {
Entry.ContextVariables.push_back(*I);
}
}
示例4: runOnFunction
bool LazyValueInfo::runOnFunction(Function &F) {
AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
const DataLayout &DL = F.getParent()->getDataLayout();
DominatorTreeWrapperPass *DTWP =
getAnalysisIfAvailable<DominatorTreeWrapperPass>();
DT = DTWP ? &DTWP->getDomTree() : nullptr;
TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
if (PImpl)
getCache(PImpl, AC, &DL, DT).clear();
// Fully lazy.
return false;
}
示例5: runOnFunction
bool StackProtector::runOnFunction(Function &Fn) {
F = &Fn;
M = F->getParent();
DominatorTreeWrapperPass *DTWP =
getAnalysisIfAvailable<DominatorTreeWrapperPass>();
DT = DTWP ? &DTWP->getDomTree() : nullptr;
TLI = TM->getSubtargetImpl(Fn)->getTargetLowering();
Attribute Attr = Fn.getFnAttribute("stack-protector-buffer-size");
if (Attr.isStringAttribute() &&
Attr.getValueAsString().getAsInteger(10, SSPBufferSize))
return false; // Invalid integer string
if (!RequiresStackProtector())
return false;
++NumFunProtected;
return InsertStackProtectors();
}
示例6: runOnFunction
bool StackProtector::runOnFunction(Function &Fn) {
F = &Fn;
M = F->getParent();
DominatorTreeWrapperPass *DTWP =
getAnalysisIfAvailable<DominatorTreeWrapperPass>();
DT = DTWP ? &DTWP->getDomTree() : 0;
TLI = TM->getTargetLowering();
if (!RequiresStackProtector())
return false;
Attribute Attr = Fn.getAttributes().getAttribute(
AttributeSet::FunctionIndex, "stack-protector-buffer-size");
if (Attr.isStringAttribute())
Attr.getValueAsString().getAsInteger(10, SSPBufferSize);
++NumFunProtected;
return InsertStackProtectors();
}
示例7: doMemToReg
void doMemToReg(Function &F) {
std::vector<AllocaInst*> Allocas;
BasicBlock &BB = F.getEntryBlock(); // Get the entry node for the function
DominatorTreeWrapperPass DTW;
DTW.runOnFunction(F);
DominatorTree& DT = DTW.getDomTree();
while (1) {
Allocas.clear();
// Find allocas that are safe to promote, by looking at all instructions in
// the entry node
for (BasicBlock::iterator I = BB.begin(), E = --BB.end(); I != E; ++I)
if (AllocaInst *AI = dyn_cast<AllocaInst>(I)) // Is it an alloca?
if (isAllocaPromotable(AI))
Allocas.push_back(AI);
if (Allocas.empty()) break;
PromoteMemToReg(Allocas, DT);
}
}
示例8: runOnLoop
bool LoopInstSimplify::runOnLoop(Loop *L, LPPassManager &LPM) {
if (skipOptnoneFunction(L))
return false;
DominatorTreeWrapperPass *DTWP =
getAnalysisIfAvailable<DominatorTreeWrapperPass>();
DominatorTree *DT = DTWP ? &DTWP->getDomTree() : nullptr;
LoopInfo *LI = &getAnalysis<LoopInfo>();
DataLayoutPass *DLP = getAnalysisIfAvailable<DataLayoutPass>();
const DataLayout *DL = DLP ? &DLP->getDataLayout() : nullptr;
const TargetLibraryInfo *TLI = &getAnalysis<TargetLibraryInfo>();
AssumptionTracker *AT = &getAnalysis<AssumptionTracker>();
SmallVector<BasicBlock*, 8> ExitBlocks;
L->getUniqueExitBlocks(ExitBlocks);
array_pod_sort(ExitBlocks.begin(), ExitBlocks.end());
SmallPtrSet<const Instruction*, 8> S1, S2, *ToSimplify = &S1, *Next = &S2;
// The bit we are stealing from the pointer represents whether this basic
// block is the header of a subloop, in which case we only process its phis.
typedef PointerIntPair<BasicBlock*, 1> WorklistItem;
SmallVector<WorklistItem, 16> VisitStack;
SmallPtrSet<BasicBlock*, 32> Visited;
bool Changed = false;
bool LocalChanged;
do {
LocalChanged = false;
VisitStack.clear();
Visited.clear();
VisitStack.push_back(WorklistItem(L->getHeader(), false));
while (!VisitStack.empty()) {
WorklistItem Item = VisitStack.pop_back_val();
BasicBlock *BB = Item.getPointer();
bool IsSubloopHeader = Item.getInt();
// Simplify instructions in the current basic block.
for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) {
Instruction *I = BI++;
// The first time through the loop ToSimplify is empty and we try to
// simplify all instructions. On later iterations ToSimplify is not
// empty and we only bother simplifying instructions that are in it.
if (!ToSimplify->empty() && !ToSimplify->count(I))
continue;
// Don't bother simplifying unused instructions.
if (!I->use_empty()) {
Value *V = SimplifyInstruction(I, DL, TLI, DT, AT);
if (V && LI->replacementPreservesLCSSAForm(I, V)) {
// Mark all uses for resimplification next time round the loop.
for (User *U : I->users())
Next->insert(cast<Instruction>(U));
I->replaceAllUsesWith(V);
LocalChanged = true;
++NumSimplified;
}
}
bool res = RecursivelyDeleteTriviallyDeadInstructions(I, TLI);
if (res) {
// RecursivelyDeleteTriviallyDeadInstruction can remove
// more than one instruction, so simply incrementing the
// iterator does not work. When instructions get deleted
// re-iterate instead.
BI = BB->begin(); BE = BB->end();
LocalChanged |= res;
}
if (IsSubloopHeader && !isa<PHINode>(I))
break;
}
// Add all successors to the worklist, except for loop exit blocks and the
// bodies of subloops. We visit the headers of loops so that we can process
// their phis, but we contract the rest of the subloop body and only follow
// edges leading back to the original loop.
for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE;
++SI) {
BasicBlock *SuccBB = *SI;
if (!Visited.insert(SuccBB).second)
continue;
const Loop *SuccLoop = LI->getLoopFor(SuccBB);
if (SuccLoop && SuccLoop->getHeader() == SuccBB
&& L->contains(SuccLoop)) {
VisitStack.push_back(WorklistItem(SuccBB, true));
SmallVector<BasicBlock*, 8> SubLoopExitBlocks;
SuccLoop->getExitBlocks(SubLoopExitBlocks);
for (unsigned i = 0; i < SubLoopExitBlocks.size(); ++i) {
BasicBlock *ExitBB = SubLoopExitBlocks[i];
if (LI->getLoopFor(ExitBB) == L && Visited.insert(ExitBB).second)
VisitStack.push_back(WorklistItem(ExitBB, false));
}
//.........这里部分代码省略.........
示例9: assert
//.........这里部分代码省略.........
// To save space, for each async call in the callback function, we just ignore the sync case, and leave it to the scheduler
// TODO need an option for this
{
for (std::vector<AsyncCallEntry>::iterator EI = AsyncCallEntries.begin(), EE = AsyncCallEntries.end(); EI != EE; ++EI) {
AsyncCallEntry & CurEntry = *EI;
Instruction *MappedAsyncCallInst = cast<Instruction>(VMap[CurEntry.AsyncCallInst]);
BasicBlock *MappedAsyncCallBlock = MappedAsyncCallInst->getParent();
BasicBlock *MappedAfterCallBlock = cast<BasicBlock>(VMap[CurEntry.AfterCallBlock]);
// for the sync case of the call, go to NewBlock (instead of MappedAfterCallBlock)
BasicBlock *NewBlock = BasicBlock::Create(TheModule->getContext(), "", CurCallbackFunc, MappedAfterCallBlock);
MappedAsyncCallBlock->getTerminator()->setSuccessor(1, NewBlock);
// store the return value
if (!MappedAsyncCallInst->use_empty()) {
CallInst *RawRetValAddr = CallInst::Create(GetAsyncReturnValueAddrFunction, "", NewBlock);
BitCastInst *RetValAddr = new BitCastInst(RawRetValAddr, MappedAsyncCallInst->getType()->getPointerTo(), "AsyncRetValAddr", NewBlock);
new StoreInst(MappedAsyncCallInst, RetValAddr, NewBlock);
}
// tell the scheduler that we want to keep the current async stack frame
CallInst::Create(DoNotUnwindAsyncFunction, "", NewBlock);
// finally we go to the SaveAsyncCtxBlock, to register the callbac, save the local variables and leave
BasicBlock *MappedSaveAsyncCtxBlock = cast<BasicBlock>(VMap[CurEntry.SaveAsyncCtxBlock]);
BranchInst::Create(MappedSaveAsyncCtxBlock, NewBlock);
}
}
std::vector<AllocaInst*> ToPromote;
// applying loaded variables in the entry block
{
BasicBlockSet ReachableBlocks = FindReachableBlocksFrom(ResumeBlock);
for (size_t i = 0; i < CurEntry.ContextVariables.size(); ++i) {
Value *OrigVar = CurEntry.ContextVariables[i];
if (isa<Argument>(OrigVar)) continue; // already processed
Value *CurVar = VMap[OrigVar];
assert(CurVar != MappedAsyncCall);
if (Instruction *Inst = dyn_cast<Instruction>(CurVar)) {
if (ReachableBlocks.count(Inst->getParent())) {
// Inst could be either defined or loaded from the async context
// Do the dirty works in memory
// TODO: might need to check the safety first
// TODO: can we create phi directly?
AllocaInst *Addr = DemoteRegToStack(*Inst, false);
new StoreInst(LoadedAsyncVars[i], Addr, EntryBlock);
ToPromote.push_back(Addr);
} else {
// The parent block is not reachable, which means there is no confliction
// it's safe to replace Inst with the loaded value
assert(Inst != LoadedAsyncVars[i]); // this should only happen when OrigVar is an Argument
Inst->replaceAllUsesWith(LoadedAsyncVars[i]);
}
}
}
}
// resolve the return value of the previous async function
// it could be the value just loaded from the global area
// or directly returned by the function (in its sync case)
if (!CurEntry.AsyncCallInst->use_empty()) {
// load the async return value
CallInst *RawRetValAddr = CallInst::Create(GetAsyncReturnValueAddrFunction, "", EntryBlock);
BitCastInst *RetValAddr = new BitCastInst(RawRetValAddr, MappedAsyncCall->getType()->getPointerTo(), "AsyncRetValAddr", EntryBlock);
LoadInst *RetVal = new LoadInst(RetValAddr, "AsyncRetVal", EntryBlock);
AllocaInst *Addr = DemoteRegToStack(*MappedAsyncCall, false);
new StoreInst(RetVal, Addr, EntryBlock);
ToPromote.push_back(Addr);
}
// TODO remove unreachable blocks before creating phi
// We go right to ResumeBlock from the EntryBlock
BranchInst::Create(ResumeBlock, EntryBlock);
/*
* Creating phi's
* Normal stack frames and async stack frames are interleaving with each other.
* In a callback function, if we call an async function, we might need to realloc the async ctx.
* at this point we don't want anything stored after the ctx,
* such that we can free and extend the ctx by simply update STACKTOP.
* Therefore we don't want any alloca's in callback functions.
*
*/
if (!ToPromote.empty()) {
DominatorTreeWrapperPass DTW;
DTW.runOnFunction(*CurCallbackFunc);
PromoteMemToReg(ToPromote, DTW.getDomTree());
}
removeUnreachableBlocks(*CurCallbackFunc);
}
// Pass 4
// Here are modifications to the original function, which we won't want to be cloned into the callback functions
for (std::vector<AsyncCallEntry>::iterator EI = AsyncCallEntries.begin(), EE = AsyncCallEntries.end(); EI != EE; ++EI) {
AsyncCallEntry & CurEntry = *EI;
// remove the frame if no async functinon has been called
CallInst::Create(FreeAsyncCtxFunction, CurEntry.AllocAsyncCtxInst, "", CurEntry.AfterCallBlock->getFirstNonPHI());
}
}
示例10: assert
/// SplitCriticalEdge - If this edge is a critical edge, insert a new node to
/// split the critical edge. This will update DominatorTree information if it
/// is available, thus calling this pass will not invalidate either of them.
/// This returns the new block if the edge was split, null otherwise.
///
/// If MergeIdenticalEdges is true (not the default), *all* edges from TI to the
/// specified successor will be merged into the same critical edge block.
/// This is most commonly interesting with switch instructions, which may
/// have many edges to any one destination. This ensures that all edges to that
/// dest go to one block instead of each going to a different block, but isn't
/// the standard definition of a "critical edge".
///
/// It is invalid to call this function on a critical edge that starts at an
/// IndirectBrInst. Splitting these edges will almost always create an invalid
/// program because the address of the new block won't be the one that is jumped
/// to.
///
BasicBlock *llvm::SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum,
Pass *P, bool MergeIdenticalEdges,
bool DontDeleteUselessPhis,
bool SplitLandingPads) {
if (!isCriticalEdge(TI, SuccNum, MergeIdenticalEdges)) return 0;
assert(!isa<IndirectBrInst>(TI) &&
"Cannot split critical edge from IndirectBrInst");
BasicBlock *TIBB = TI->getParent();
BasicBlock *DestBB = TI->getSuccessor(SuccNum);
// Splitting the critical edge to a landing pad block is non-trivial. Don't do
// it in this generic function.
if (DestBB->isLandingPad()) return 0;
// Create a new basic block, linking it into the CFG.
BasicBlock *NewBB = BasicBlock::Create(TI->getContext(),
TIBB->getName() + "." + DestBB->getName() + "_crit_edge");
// Create our unconditional branch.
BranchInst *NewBI = BranchInst::Create(DestBB, NewBB);
NewBI->setDebugLoc(TI->getDebugLoc());
// Branch to the new block, breaking the edge.
TI->setSuccessor(SuccNum, NewBB);
// Insert the block into the function... right after the block TI lives in.
Function &F = *TIBB->getParent();
Function::iterator FBBI = TIBB;
F.getBasicBlockList().insert(++FBBI, NewBB);
// If there are any PHI nodes in DestBB, we need to update them so that they
// merge incoming values from NewBB instead of from TIBB.
{
unsigned BBIdx = 0;
for (BasicBlock::iterator I = DestBB->begin(); isa<PHINode>(I); ++I) {
// We no longer enter through TIBB, now we come in through NewBB.
// Revector exactly one entry in the PHI node that used to come from
// TIBB to come from NewBB.
PHINode *PN = cast<PHINode>(I);
// Reuse the previous value of BBIdx if it lines up. In cases where we
// have multiple phi nodes with *lots* of predecessors, this is a speed
// win because we don't have to scan the PHI looking for TIBB. This
// happens because the BB list of PHI nodes are usually in the same
// order.
if (PN->getIncomingBlock(BBIdx) != TIBB)
BBIdx = PN->getBasicBlockIndex(TIBB);
PN->setIncomingBlock(BBIdx, NewBB);
}
}
// If there are any other edges from TIBB to DestBB, update those to go
// through the split block, making those edges non-critical as well (and
// reducing the number of phi entries in the DestBB if relevant).
if (MergeIdenticalEdges) {
for (unsigned i = SuccNum+1, e = TI->getNumSuccessors(); i != e; ++i) {
if (TI->getSuccessor(i) != DestBB) continue;
// Remove an entry for TIBB from DestBB phi nodes.
DestBB->removePredecessor(TIBB, DontDeleteUselessPhis);
// We found another edge to DestBB, go to NewBB instead.
TI->setSuccessor(i, NewBB);
}
}
// If we don't have a pass object, we can't update anything...
if (P == 0) return NewBB;
DominatorTreeWrapperPass *DTWP =
P->getAnalysisIfAvailable<DominatorTreeWrapperPass>();
DominatorTree *DT = DTWP ? &DTWP->getDomTree() : 0;
LoopInfo *LI = P->getAnalysisIfAvailable<LoopInfo>();
// If we have nothing to update, just return.
if (DT == 0 && LI == 0)
return NewBB;
// Now update analysis information. Since the only predecessor of NewBB is
// the TIBB, TIBB clearly dominates NewBB. TIBB usually doesn't dominate
//.........这里部分代码省略.........