本文整理汇总了C++中DomTreeNode::getBlock方法的典型用法代码示例。如果您正苦于以下问题:C++ DomTreeNode::getBlock方法的具体用法?C++ DomTreeNode::getBlock怎么用?C++ DomTreeNode::getBlock使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类DomTreeNode
的用法示例。
在下文中一共展示了DomTreeNode::getBlock方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: isCold
/// \return true if the given block is dominated by a _slowPath branch hint.
///
/// Cache all blocks visited to avoid introducing quadratic behavior.
bool ColdBlockInfo::isCold(const SILBasicBlock *BB, int recursionDepth) {
auto I = ColdBlockMap.find(BB);
if (I != ColdBlockMap.end())
return I->second;
typedef llvm::DomTreeNodeBase<SILBasicBlock> DomTreeNode;
DominanceInfo *DT = DA->get(const_cast<SILFunction*>(BB->getParent()));
DomTreeNode *Node = DT->getNode(const_cast<SILBasicBlock*>(BB));
// Always consider unreachable code cold.
if (!Node)
return true;
std::vector<const SILBasicBlock*> DomChain;
DomChain.push_back(BB);
bool IsCold = false;
Node = Node->getIDom();
while (Node) {
if (isSlowPath(Node->getBlock(), DomChain.back(), recursionDepth)) {
IsCold = true;
break;
}
auto I = ColdBlockMap.find(Node->getBlock());
if (I != ColdBlockMap.end()) {
IsCold = I->second;
break;
}
DomChain.push_back(Node->getBlock());
Node = Node->getIDom();
}
for (auto *ChainBB : DomChain)
ColdBlockMap[ChainBB] = IsCold;
return IsCold;
}
示例2: buildCondition
void TempScopInfo::buildCondition(BasicBlock *BB, BasicBlock *RegionEntry) {
BBCond Cond;
DomTreeNode *BBNode = DT->getNode(BB), *EntryNode = DT->getNode(RegionEntry);
assert(BBNode && EntryNode && "Get null node while building condition!");
// Walk up the dominance tree until reaching the entry node. Add all
// conditions on the path to BB except if BB postdominates the block
// containing the condition.
while (BBNode != EntryNode) {
BasicBlock *CurBB = BBNode->getBlock();
BBNode = BBNode->getIDom();
assert(BBNode && "BBNode should not reach the root node!");
if (PDT->dominates(CurBB, BBNode->getBlock()))
continue;
BranchInst *Br = dyn_cast<BranchInst>(BBNode->getBlock()->getTerminator());
assert(Br && "A Valid Scop should only contain branch instruction");
if (Br->isUnconditional())
continue;
// Is BB on the ELSE side of the branch?
bool inverted = DT->dominates(Br->getSuccessor(1), BB);
Comparison *Cmp;
buildAffineCondition(*(Br->getCondition()), inverted, &Cmp);
Cond.push_back(*Cmp);
}
if (!Cond.empty())
BBConds[BB] = Cond;
}
示例3: computeDependencies
void ControlDependenceGraphBase::computeDependencies(Function &F, PostDominatorTree &pdt) {
root = new ControlDependenceNode();
nodes.insert(root);
for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
ControlDependenceNode *bn = new ControlDependenceNode(BB);
nodes.insert(bn);
bbMap[BB] = bn;
}
for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
BasicBlock *A = BB;
ControlDependenceNode *AN = bbMap[A];
for (succ_iterator succ = succ_begin(A), end = succ_end(A); succ != end; ++succ) {
BasicBlock *B = *succ;
assert(A && B);
if (A == B || !pdt.dominates(B,A)) {
BasicBlock *L = pdt.findNearestCommonDominator(A,B);
ControlDependenceNode::EdgeType type = ControlDependenceGraphBase::getEdgeType(A,B);
if (A == L) {
switch (type) {
case ControlDependenceNode::TRUE:
AN->addTrue(AN); break;
case ControlDependenceNode::FALSE:
AN->addFalse(AN); break;
case ControlDependenceNode::OTHER:
AN->addOther(AN); break;
}
AN->addParent(AN);
}
for (DomTreeNode *cur = pdt[B]; cur && cur != pdt[L]; cur = cur->getIDom()) {
ControlDependenceNode *CN = bbMap[cur->getBlock()];
switch (type) {
case ControlDependenceNode::TRUE:
AN->addTrue(CN); break;
case ControlDependenceNode::FALSE:
AN->addFalse(CN); break;
case ControlDependenceNode::OTHER:
AN->addOther(CN); break;
}
assert(CN);
CN->addParent(AN);
}
}
}
}
// ENTRY -> START
for (DomTreeNode *cur = pdt[&F.getEntryBlock()]; cur; cur = cur->getIDom()) {
if (cur->getBlock()) {
ControlDependenceNode *CN = bbMap[cur->getBlock()];
assert(CN);
root->addOther(CN); CN->addParent(root);
}
}
}
示例4: get
SILValue
StackAllocationPromoter::getLiveOutValue(BlockSet &PhiBlocks,
SILBasicBlock *StartBB) {
DEBUG(llvm::dbgs() << "*** Searching for a value definition.\n");
// Walk the Dom tree in search of a defining value:
for (DomTreeNode *Node = DT->getNode(StartBB); Node; Node = Node->getIDom()) {
SILBasicBlock *BB = Node->getBlock();
// If there is a store (that must come after the phi), use its value.
BlockToInstMap::iterator it = LastStoreInBlock.find(BB);
if (it != LastStoreInBlock.end())
if (auto *St = dyn_cast_or_null<StoreInst>(it->second)) {
DEBUG(llvm::dbgs() << "*** Found Store def " << *St->getSrc());
return St->getSrc();
}
// If there is a Phi definition in this block:
if (PhiBlocks.count(BB)) {
// Return the dummy instruction that represents the new value that we will
// add to the basic block.
SILValue Phi = BB->getArgument(BB->getNumArguments() - 1);
DEBUG(llvm::dbgs() << "*** Found a dummy Phi def " << *Phi);
return Phi;
}
// Move to the next dominating block.
DEBUG(llvm::dbgs() << "*** Walking up the iDOM.\n");
}
DEBUG(llvm::dbgs() << "*** Could not find a Def. Using Undef.\n");
return SILUndef::get(ASI->getElementType(), ASI->getModule());
}
示例5: placeInitializers
/// Optimize placement of initializer calls given a list of calls to the
/// same initializer. All original initialization points must be dominated by
/// the final initialization calls.
///
/// The current heuristic hoists all initialization points within a function to
/// a single dominating call in the outer loop preheader.
void SILGlobalOpt::placeInitializers(SILFunction *InitF,
ArrayRef<ApplyInst *> Calls) {
LLVM_DEBUG(llvm::dbgs() << "GlobalOpt: calls to "
<< Demangle::demangleSymbolAsString(InitF->getName())
<< " : " << Calls.size() << "\n");
// Map each initializer-containing function to its final initializer call.
llvm::DenseMap<SILFunction *, ApplyInst *> ParentFuncs;
for (auto *AI : Calls) {
assert(AI->getNumArguments() == 0 && "ill-formed global init call");
assert(cast<FunctionRefInst>(AI->getCallee())->getReferencedFunction()
== InitF && "wrong init call");
SILFunction *ParentF = AI->getFunction();
DominanceInfo *DT = DA->get(ParentF);
ApplyInst *HoistAI =
getHoistedApplyForInitializer(AI, DT, InitF, ParentF, ParentFuncs);
// If we were unable to find anything, just go onto the next apply.
if (!HoistAI) {
continue;
}
// Otherwise, move this call to the outermost loop preheader.
SILBasicBlock *BB = HoistAI->getParent();
typedef llvm::DomTreeNodeBase<SILBasicBlock> DomTreeNode;
DomTreeNode *Node = DT->getNode(BB);
while (Node) {
SILBasicBlock *DomParentBB = Node->getBlock();
if (isAvailabilityCheck(DomParentBB)) {
LLVM_DEBUG(llvm::dbgs() << " don't hoist above availability check "
"at bb"
<< DomParentBB->getDebugID() << "\n");
break;
}
BB = DomParentBB;
if (!isInLoop(BB))
break;
Node = Node->getIDom();
}
if (BB == HoistAI->getParent()) {
// BB is either unreachable or not in a loop.
LLVM_DEBUG(llvm::dbgs() << " skipping (not in a loop): " << *HoistAI
<< " in " << HoistAI->getFunction()->getName()
<< "\n");
continue;
}
LLVM_DEBUG(llvm::dbgs() << " hoisting: " << *HoistAI << " in "
<< HoistAI->getFunction()->getName() << "\n");
HoistAI->moveBefore(&*BB->begin());
placeFuncRef(HoistAI, DT);
HasChanged = true;
}
}
示例6: removeUndefBranches
/**
* removeUndefBranches -- remove branches with undef condition
*
* These are irrelevant to the code, so may be removed completely with their
* bodies.
*/
void FunctionStaticSlicer::removeUndefBranches(ModulePass *MP, Function &F) {
#ifdef DEBUG_SLICE
errs() << __func__ << " ============ Removing unused branches\n";
#endif
PostDominatorTree &PDT = MP->getAnalysis<PostDominatorTree>(F);
typedef llvm::SmallVector<const BasicBlock *, 10> Unsafe;
Unsafe unsafe;
for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) {
BasicBlock &bb = *I;
if (std::distance(succ_begin(&bb), succ_end(&bb)) <= 1)
continue;
Instruction &back = bb.back();
if (back.getOpcode() != Instruction::Br &&
back.getOpcode() != Instruction::Switch)
continue;
const Value *cond = back.getOperand(0);
if (cond->getValueID() != Value::UndefValueVal)
continue;
DomTreeNode *node = PDT.getNode(&bb);
if (!node) /* this bb is unreachable */
continue;
DomTreeNode *idom = node->getIDom();
assert(idom);
/* if (!idom)
continue;*/
BasicBlock *dest = idom->getBlock();
if (!dest) /* TODO when there are nodes with noreturn calls */
continue;
#ifdef DEBUG_SLICE
errs() << " considering branch: " << bb.getName() << '\n';
errs() << " dest=" << dest->getName() << "\n";
#endif
if (PHINode *PHI = dyn_cast<PHINode>(&dest->front()))
if (PHI->getBasicBlockIndex(&bb) == -1) {
/* TODO this is unsafe! */
unsafe.push_back(&bb);
PHI->addIncoming(Constant::getNullValue(PHI->getType()), &bb);
}
BasicBlock::iterator ii(back);
Instruction *newI = BranchInst::Create(dest);
ReplaceInstWithInst(bb.getInstList(), ii, newI);
}
for (Unsafe::const_iterator I = unsafe.begin(), E = unsafe.end();
I != E; ++I) {
const BasicBlock *bb = *I;
if (std::distance(pred_begin(bb), pred_end(bb)) > 1)
errs() << "WARNING: PHI node with added value which is zero\n";
}
#ifdef DEBUG_SLICE
errs() << __func__ << " ============ END\n";
#endif
}
示例7: gatherDominatingDefs
void GCPtrTracker::gatherDominatingDefs(const BasicBlock *BB,
AvailableValueSet &Result,
const DominatorTree &DT) {
DomTreeNode *DTN = DT[const_cast<BasicBlock *>(BB)];
while (DTN->getIDom()) {
DTN = DTN->getIDom();
const auto &Defs = BlockMap[DTN->getBlock()]->Contribution;
Result.insert(Defs.begin(), Defs.end());
// If this block is 'Cleared', then nothing LiveIn to this block can be
// available after this block completes. Note: This turns out to be
// really important for reducing memory consuption of the initial available
// sets and thus peak memory usage by this verifier.
if (BlockMap[DTN->getBlock()]->Cleared)
return;
}
for (const Argument &A : BB->getParent()->args())
if (containsGCPtrType(A.getType()))
Result.insert(&A);
}
示例8: findRegionsWithEntry
void RegionInfo::findRegionsWithEntry(BasicBlock *entry, BBtoBBMap *ShortCut) {
assert(entry);
DomTreeNode *N = PDT->getNode(entry);
if (!N)
return;
Region *lastRegion= 0;
BasicBlock *lastExit = entry;
// As only a BasicBlock that postdominates entry can finish a region, walk the
// post dominance tree upwards.
while ((N = getNextPostDom(N, ShortCut))) {
BasicBlock *exit = N->getBlock();
if (!exit)
break;
if (isRegion(entry, exit)) {
Region *newRegion = createRegion(entry, exit);
if (lastRegion)
newRegion->addSubRegion(lastRegion);
lastRegion = newRegion;
lastExit = exit;
}
// This can never be a region, so stop the search.
if (!DT->dominates(entry, exit))
break;
}
// Tried to create regions from entry to lastExit. Next time take a
// shortcut from entry to lastExit.
if (lastExit != entry)
insertShortCut(entry, lastExit, ShortCut);
}
示例9: buildCondition
void TempScopInfo::buildCondition(BasicBlock *BB, Region &R) {
BasicBlock *RegionEntry = R.getEntry();
BBCond Cond;
DomTreeNode *BBNode = DT->getNode(BB), *EntryNode = DT->getNode(RegionEntry);
assert(BBNode && EntryNode && "Get null node while building condition!");
// Walk up the dominance tree until reaching the entry node. Collect all
// branching blocks on the path to BB except if BB postdominates the block
// containing the condition.
SmallVector<BasicBlock *, 4> DominatorBrBlocks;
while (BBNode != EntryNode) {
BasicBlock *CurBB = BBNode->getBlock();
BBNode = BBNode->getIDom();
assert(BBNode && "BBNode should not reach the root node!");
if (PDT->dominates(CurBB, BBNode->getBlock()))
continue;
BranchInst *Br = dyn_cast<BranchInst>(BBNode->getBlock()->getTerminator());
assert(Br && "A Valid Scop should only contain branch instruction");
if (Br->isUnconditional())
continue;
DominatorBrBlocks.push_back(BBNode->getBlock());
}
RegionInfo *RI = R.getRegionInfo();
// Iterate in reverse order over the dominating blocks. Until a non-affine
// branch was encountered add all conditions collected. If a non-affine branch
// was encountered, stop as we overapproximate from here on anyway.
for (auto BIt = DominatorBrBlocks.rbegin(), BEnd = DominatorBrBlocks.rend();
BIt != BEnd; BIt++) {
BasicBlock *BBNode = *BIt;
BranchInst *Br = dyn_cast<BranchInst>(BBNode->getTerminator());
assert(Br && "A Valid Scop should only contain branch instruction");
assert(Br->isConditional() && "Assumed a conditional branch");
if (SD->isNonAffineSubRegion(RI->getRegionFor(BBNode), &R))
break;
BasicBlock *TrueBB = Br->getSuccessor(0), *FalseBB = Br->getSuccessor(1);
// Is BB on the ELSE side of the branch?
bool inverted = DT->dominates(FalseBB, BB);
// If both TrueBB and FalseBB dominate BB, one of them must be the target of
// a back-edge, i.e. a loop header.
if (inverted && DT->dominates(TrueBB, BB)) {
assert(
(DT->dominates(TrueBB, FalseBB) || DT->dominates(FalseBB, TrueBB)) &&
"One of the successors should be the loop header and dominate the"
"other!");
// It is not an invert if the FalseBB is the header.
if (DT->dominates(FalseBB, TrueBB))
inverted = false;
}
Comparison *Cmp;
buildAffineCondition(*(Br->getCondition()), inverted, &Cmp);
Cond.push_back(*Cmp);
}
if (!Cond.empty())
BBConds[BB] = Cond;
}
示例10:
/// getImmediateDominator - A handy utility for the specific DominatorTree
/// query that we need here.
///
static const BasicBlock *getImmediateDominator(const BasicBlock *BB,
const DominatorTree *DT) {
DomTreeNode *Node = DT->getNode(const_cast<BasicBlock *>(BB))->getIDom();
return Node ? Node->getBlock() : 0;
}
示例11: placeInitializers
/// Optimize placement of initializer calls given a list of calls to the
/// same initializer. All original initialization points must be dominated by
/// the final initialization calls.
///
/// The current heuristic hoists all initialization points within a function to
/// a single dominating call in the outer loop preheader.
void SILGlobalOpt::placeInitializers(SILFunction *InitF,
ArrayRef<ApplyInst*> Calls) {
DEBUG(llvm::dbgs() << "GlobalOpt: calls to "
<< demangle_wrappers::demangleSymbolAsString(InitF->getName())
<< " : " << Calls.size() << "\n");
// Map each initializer-containing function to its final initializer call.
llvm::DenseMap<SILFunction*, ApplyInst*> ParentFuncs;
for (auto *AI : Calls) {
assert(AI->getNumArguments() == 0 && "ill-formed global init call");
assert(cast<FunctionRefInst>(AI->getCallee())->getReferencedFunction()
== InitF && "wrong init call");
SILFunction *ParentF = AI->getFunction();
DominanceInfo *DT = DA->get(ParentF);
auto PFI = ParentFuncs.find(ParentF);
ApplyInst *HoistAI = nullptr;
if (PFI != ParentFuncs.end()) {
// Found a replacement for this init call.
// Ensure the replacement dominates the original call site.
ApplyInst *CommonAI = PFI->second;
assert(cast<FunctionRefInst>(CommonAI->getCallee())
->getReferencedFunction() == InitF &&
"ill-formed global init call");
SILBasicBlock *DomBB =
DT->findNearestCommonDominator(AI->getParent(), CommonAI->getParent());
// We must not move initializers around availability-checks.
if (!isAvailabilityCheckOnDomPath(DomBB, CommonAI->getParent(), DT)) {
if (DomBB != CommonAI->getParent()) {
CommonAI->moveBefore(&*DomBB->begin());
placeFuncRef(CommonAI, DT);
// Try to hoist the existing AI again if we move it to another block,
// e.g. from a loop exit into the loop.
HoistAI = CommonAI;
}
AI->replaceAllUsesWith(CommonAI);
AI->eraseFromParent();
HasChanged = true;
}
} else {
ParentFuncs[ParentF] = AI;
// It's the first time we found a call to InitF in this function, so we
// try to hoist it out of any loop.
HoistAI = AI;
}
if (HoistAI) {
// Move this call to the outermost loop preheader.
SILBasicBlock *BB = HoistAI->getParent();
typedef llvm::DomTreeNodeBase<SILBasicBlock> DomTreeNode;
DomTreeNode *Node = DT->getNode(BB);
while (Node) {
SILBasicBlock *DomParentBB = Node->getBlock();
if (isAvailabilityCheck(DomParentBB)) {
DEBUG(llvm::dbgs() << " don't hoist above availability check at bb" <<
DomParentBB->getDebugID() << "\n");
break;
}
BB = DomParentBB;
if (!isInLoop(BB))
break;
Node = Node->getIDom();
}
if (BB == HoistAI->getParent()) {
// BB is either unreachable or not in a loop.
DEBUG(llvm::dbgs() << " skipping (not in a loop): " << *HoistAI
<< " in " << HoistAI->getFunction()->getName() << "\n");
}
else {
DEBUG(llvm::dbgs() << " hoisting: " << *HoistAI
<< " in " << HoistAI->getFunction()->getName() << "\n");
HoistAI->moveBefore(&*BB->begin());
placeFuncRef(HoistAI, DT);
HasChanged = true;
}
}
}
}
示例12: computeAntidependencePaths
void idenRegion::computeAntidependencePaths() {
// Iterate through every pair of antidependency
// Record all the store along the path
for (AntiDepPairs::iterator I = AntiDepPairs_.begin(), E = AntiDepPairs_.end(); I != E; I++) {
BasicBlock::iterator Load, Store;
tie(Load, Store) = *I;
// create a new path
AntiDepPaths_.resize(AntiDepPaths_.size()+1);
AntiDepPathTy &newPath = AntiDepPaths_.back();
// Always record current store
newPath.push_back(Store);
// Load and store in the same basic block
BasicBlock::iterator curInst = Store;
BasicBlock *LoadBB = Load->getParent(), *StoreBB = Store->getParent();
if (LoadBB == StoreBB && DT->dominates(Load, Store)) {
while(--curInst != Load) {
if (isa<StoreInst>(curInst))
newPath.push_back(curInst);
}
errs() << "@@@ Local BB: \[email protected]@@ ";
printPath(newPath);
errs() << "\n";
continue;
}
// Load and store in different basic block
BasicBlock *curBB = StoreBB;
DomTreeNode *curDTNode = DT->getNode(StoreBB), *LoadDTNode = DT->getNode(LoadBB);
// loop until load is not
while (DT->dominates(LoadDTNode, curDTNode)) {
errs() << "^^^^^ Current BB is " << curBB->getName() << "\n";
BasicBlock::iterator E;
// check if Load and current node in the same BB
if (curBB == LoadBB) {
E = Load;
} else {
E = curBB->begin();
}
// scan current BB
while(curInst != E) {
if (isa<StoreInst>(--curInst)) {
newPath.push_back(curInst);
}
}
// find current Node's iDOM
curDTNode = curDTNode->getIDom();
if (curDTNode == NULL)
break;
curBB = curDTNode->getBlock();
curInst = curBB->end();
}
errs() << "@@@ Inter BB: \[email protected]@@ ";
printPath(newPath);
errs() << "\n";
}
errs() << "Path cap is " << AntiDepPaths_.capacity() << "\n";
errs() << "Path size is " << AntiDepPaths_.size() << "\n";
errs() << "#########################################################\n";
errs() << "#################### Paths Summary ######################\n";
errs() << "#########################################################\n";
printCollection(AntiDepPaths_);
errs() << "\n";
}
示例13: while
void IDFCalculator<NodeTy>::calculate(
SmallVectorImpl<BasicBlock *> &PHIBlocks) {
// Use a priority queue keyed on dominator tree level so that inserted nodes
// are handled from the bottom of the dominator tree upwards.
typedef std::pair<DomTreeNode *, unsigned> DomTreeNodePair;
typedef std::priority_queue<DomTreeNodePair, SmallVector<DomTreeNodePair, 32>,
less_second> IDFPriorityQueue;
IDFPriorityQueue PQ;
for (BasicBlock *BB : *DefBlocks) {
if (DomTreeNode *Node = DT.getNode(BB))
PQ.push({Node, Node->getLevel()});
}
SmallVector<DomTreeNode *, 32> Worklist;
SmallPtrSet<DomTreeNode *, 32> VisitedPQ;
SmallPtrSet<DomTreeNode *, 32> VisitedWorklist;
while (!PQ.empty()) {
DomTreeNodePair RootPair = PQ.top();
PQ.pop();
DomTreeNode *Root = RootPair.first;
unsigned RootLevel = RootPair.second;
// Walk all dominator tree children of Root, inspecting their CFG edges with
// targets elsewhere on the dominator tree. Only targets whose level is at
// most Root's level are added to the iterated dominance frontier of the
// definition set.
Worklist.clear();
Worklist.push_back(Root);
VisitedWorklist.insert(Root);
while (!Worklist.empty()) {
DomTreeNode *Node = Worklist.pop_back_val();
BasicBlock *BB = Node->getBlock();
// Succ is the successor in the direction we are calculating IDF, so it is
// successor for IDF, and predecessor for Reverse IDF.
for (auto *Succ : children<NodeTy>(BB)) {
DomTreeNode *SuccNode = DT.getNode(Succ);
// Quickly skip all CFG edges that are also dominator tree edges instead
// of catching them below.
if (SuccNode->getIDom() == Node)
continue;
const unsigned SuccLevel = SuccNode->getLevel();
if (SuccLevel > RootLevel)
continue;
if (!VisitedPQ.insert(SuccNode).second)
continue;
BasicBlock *SuccBB = SuccNode->getBlock();
if (useLiveIn && !LiveInBlocks->count(SuccBB))
continue;
PHIBlocks.emplace_back(SuccBB);
if (!DefBlocks->count(SuccBB))
PQ.push(std::make_pair(SuccNode, SuccLevel));
}
for (auto DomChild : *Node) {
if (VisitedWorklist.insert(DomChild).second)
Worklist.push_back(DomChild);
}
}
}
}
示例14: computePostDominators
void LLVMDependenceGraph::computePostDominators(bool addPostDomFrontiers)
{
using namespace llvm;
// iterate over all functions
for (auto& F : getConstructedFunctions()) {
analysis::PostDominanceFrontiers<LLVMNode> pdfrontiers;
// root of post-dominator tree
LLVMBBlock *root = nullptr;
Value *val = const_cast<Value *>(F.first);
Function& f = *cast<Function>(val);
PostDominatorTree *pdtree;
#if ((LLVM_VERSION_MAJOR == 3) && (LLVM_VERSION_MINOR < 9))
pdtree = new PostDominatorTree();
// compute post-dominator tree for this function
pdtree->runOnFunction(f);
#else
PostDominatorTreeWrapperPass wrapper;
wrapper.runOnFunction(f);
pdtree = &wrapper.getPostDomTree();
#ifndef NDEBUG
wrapper.verifyAnalysis();
#endif
#endif
// add immediate post-dominator edges
auto& our_blocks = F.second->getBlocks();
bool built = false;
for (auto& it : our_blocks) {
LLVMBBlock *BB = it.second;
BasicBlock *B = cast<BasicBlock>(const_cast<Value *>(it.first));
DomTreeNode *N = pdtree->getNode(B);
// when function contains infinite loop, we're screwed
// and we don't have anything
// FIXME: just check for the root,
// don't iterate over all blocks, stupid...
if (!N)
continue;
DomTreeNode *idom = N->getIDom();
BasicBlock *idomBB = idom ? idom->getBlock() : nullptr;
built = true;
if (idomBB) {
LLVMBBlock *pb = our_blocks[idomBB];
assert(pb && "Do not have constructed BB");
BB->setIPostDom(pb);
assert(cast<BasicBlock>(BB->getKey())->getParent()
== cast<BasicBlock>(pb->getKey())->getParent()
&& "BBs are from diferent functions");
// if we do not have idomBB, then the idomBB is a root BB
} else {
// PostDominatorTree may has special root without BB set
// or it is the node without immediate post-dominator
if (!root) {
root = new LLVMBBlock();
root->setKey(nullptr);
F.second->setPostDominatorTreeRoot(root);
}
BB->setIPostDom(root);
}
}
// well, if we haven't built the pdtree, this is probably infinite loop
// that has no pdtree. Until we have anything better, just add sound control
// edges that are not so precise - to predecessors.
if (!built && addPostDomFrontiers) {
for (auto& it : our_blocks) {
LLVMBBlock *BB = it.second;
for (const LLVMBBlock::BBlockEdge& succ : BB->successors()) {
// in this case we add only the control dependencies,
// since we have no pd frontiers
BB->addControlDependence(succ.target);
}
}
}
if (addPostDomFrontiers) {
// assert(root && "BUG: must have root");
if (root)
pdfrontiers.compute(root, true /* store also control depend. */);
}
#if ((LLVM_VERSION_MAJOR == 3) && (LLVM_VERSION_MINOR < 9))
delete pdtree;
#endif
}
}
示例15: promoteAllocationToPhi
void StackAllocationPromoter::promoteAllocationToPhi() {
DEBUG(llvm::dbgs() << "*** Placing Phis for : " << *ASI);
// A list of blocks that will require new Phi values.
BlockSet PhiBlocks;
// The "piggy-bank" data-structure that we use for processing the dom-tree
// bottom-up.
NodePriorityQueue PQ;
// Collect all of the stores into the AllocStack. We know that at this point
// we have at most one store per block.
for (auto UI = ASI->use_begin(), E = ASI->use_end(); UI != E; ++UI) {
SILInstruction *II = UI->getUser();
// We need to place Phis for this block.
if (isa<StoreInst>(II)) {
// If the block is in the dom tree (dominated by the entry block).
if (DomTreeNode *Node = DT->getNode(II->getParent()))
PQ.push(std::make_pair(Node, DomTreeLevels[Node]));
}
}
DEBUG(llvm::dbgs() << "*** Found: " << PQ.size() << " Defs\n");
// A list of nodes for which we already calculated the dominator frontier.
llvm::SmallPtrSet<DomTreeNode *, 32> Visited;
SmallVector<DomTreeNode *, 32> Worklist;
// Scan all of the definitions in the function bottom-up using the priority
// queue.
while (!PQ.empty()) {
DomTreeNodePair RootPair = PQ.top();
PQ.pop();
DomTreeNode *Root = RootPair.first;
unsigned RootLevel = RootPair.second;
// Walk all dom tree children of Root, inspecting their successors. Only
// J-edges, whose target level is at most Root's level are added to the
// dominance frontier.
Worklist.clear();
Worklist.push_back(Root);
while (!Worklist.empty()) {
DomTreeNode *Node = Worklist.pop_back_val();
SILBasicBlock *BB = Node->getBlock();
// For all successors of the node:
for (auto &Succ : BB->getSuccessors()) {
DomTreeNode *SuccNode = DT->getNode(Succ);
// Skip D-edges (edges that are dom-tree edges).
if (SuccNode->getIDom() == Node)
continue;
// Ignore J-edges that point to nodes that are not smaller or equal
// to the root level.
unsigned SuccLevel = DomTreeLevels[SuccNode];
if (SuccLevel > RootLevel)
continue;
// Ignore visited nodes.
if (!Visited.insert(SuccNode).second)
continue;
// If the new PHInode is not dominated by the allocation then it's dead.
if (!DT->dominates(ASI->getParent(), SuccNode->getBlock()))
continue;
// If the new PHInode is properly dominated by the deallocation then it
// is obviously a dead PHInode, so we don't need to insert it.
if (DSI && DT->properlyDominates(DSI->getParent(),
SuccNode->getBlock()))
continue;
// The successor node is a new PHINode. If this is a new PHI node
// then it may require additional definitions, so add it to the PQ.
if (PhiBlocks.insert(Succ).second)
PQ.push(std::make_pair(SuccNode, SuccLevel));
}
// Add the children in the dom-tree to the worklist.
for (auto CI = Node->begin(), CE = Node->end(); CI != CE; ++CI)
if (!Visited.count(*CI))
Worklist.push_back(*CI);
}
}
DEBUG(llvm::dbgs() << "*** Found: " << PhiBlocks.size() << " new PHIs\n");
NumPhiPlaced += PhiBlocks.size();
// At this point we calculated the locations of all of the new Phi values.
// Next, add the Phi values and promote all of the loads and stores into the
// new locations.
// Replace the dummy values with new block arguments.
addBlockArguments(PhiBlocks);
// Hook up the Phi nodes, loads, and debug_value_addr with incoming values.
fixBranchesAndUses(PhiBlocks);
//.........这里部分代码省略.........