diff options
Diffstat (limited to 'lib/Target/AMDGPU/SIAnnotateControlFlow.cpp')
| -rw-r--r-- | lib/Target/AMDGPU/SIAnnotateControlFlow.cpp | 101 |
1 files changed, 11 insertions, 90 deletions
diff --git a/lib/Target/AMDGPU/SIAnnotateControlFlow.cpp b/lib/Target/AMDGPU/SIAnnotateControlFlow.cpp index 74f1bd8fb9866..98e9ea662324f 100644 --- a/lib/Target/AMDGPU/SIAnnotateControlFlow.cpp +++ b/lib/Target/AMDGPU/SIAnnotateControlFlow.cpp @@ -16,7 +16,7 @@ #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/Analysis/DivergenceAnalysis.h" +#include "llvm/Analysis/LegacyDivergenceAnalysis.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/IR/BasicBlock.h" @@ -52,7 +52,7 @@ using StackEntry = std::pair<BasicBlock *, Value *>; using StackVector = SmallVector<StackEntry, 16>; class SIAnnotateControlFlow : public FunctionPass { - DivergenceAnalysis *DA; + LegacyDivergenceAnalysis *DA; Type *Boolean; Type *Void; @@ -66,9 +66,7 @@ class SIAnnotateControlFlow : public FunctionPass { Function *If; Function *Else; - Function *Break; Function *IfBreak; - Function *ElseBreak; Function *Loop; Function *EndCf; @@ -95,8 +93,7 @@ class SIAnnotateControlFlow : public FunctionPass { Value * handleLoopCondition(Value *Cond, PHINode *Broken, llvm::Loop *L, - BranchInst *Term, - SmallVectorImpl<WeakTrackingVH> &LoopPhiConditions); + BranchInst *Term); void handleLoop(BranchInst *Term); @@ -116,7 +113,7 @@ public: void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequired<LoopInfoWrapperPass>(); AU.addRequired<DominatorTreeWrapperPass>(); - AU.addRequired<DivergenceAnalysis>(); + AU.addRequired<LegacyDivergenceAnalysis>(); AU.addPreserved<DominatorTreeWrapperPass>(); FunctionPass::getAnalysisUsage(AU); } @@ -127,7 +124,7 @@ public: INITIALIZE_PASS_BEGIN(SIAnnotateControlFlow, DEBUG_TYPE, "Annotate SI Control Flow", false, false) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) -INITIALIZE_PASS_DEPENDENCY(DivergenceAnalysis) +INITIALIZE_PASS_DEPENDENCY(LegacyDivergenceAnalysis) INITIALIZE_PASS_END(SIAnnotateControlFlow, DEBUG_TYPE, "Annotate SI Control Flow", false, false) @@ -149,9 +146,7 @@ bool SIAnnotateControlFlow::doInitialization(Module &M) { If = Intrinsic::getDeclaration(&M, Intrinsic::amdgcn_if); Else = Intrinsic::getDeclaration(&M, Intrinsic::amdgcn_else); - Break = Intrinsic::getDeclaration(&M, Intrinsic::amdgcn_break); IfBreak = Intrinsic::getDeclaration(&M, Intrinsic::amdgcn_if_break); - ElseBreak = Intrinsic::getDeclaration(&M, Intrinsic::amdgcn_else_break); Loop = Intrinsic::getDeclaration(&M, Intrinsic::amdgcn_loop); EndCf = Intrinsic::getDeclaration(&M, Intrinsic::amdgcn_end_cf); return false; @@ -160,7 +155,7 @@ bool SIAnnotateControlFlow::doInitialization(Module &M) { /// Is the branch condition uniform or did the StructurizeCFG pass /// consider it as such? bool SIAnnotateControlFlow::isUniform(BranchInst *T) { - return DA->isUniform(T->getCondition()) || + return DA->isUniform(T) || T->getMetadata("structurizecfg.uniform") != nullptr; } @@ -227,76 +222,7 @@ void SIAnnotateControlFlow::insertElse(BranchInst *Term) { /// Recursively handle the condition leading to a loop Value *SIAnnotateControlFlow::handleLoopCondition( - Value *Cond, PHINode *Broken, llvm::Loop *L, BranchInst *Term, - SmallVectorImpl<WeakTrackingVH> &LoopPhiConditions) { - // Only search through PHI nodes which are inside the loop. If we try this - // with PHI nodes that are outside of the loop, we end up inserting new PHI - // nodes outside of the loop which depend on values defined inside the loop. - // This will break the module with - // 'Instruction does not dominate all users!' errors. - PHINode *Phi = nullptr; - if ((Phi = dyn_cast<PHINode>(Cond)) && L->contains(Phi)) { - BasicBlock *Parent = Phi->getParent(); - PHINode *NewPhi = PHINode::Create(Int64, 0, "loop.phi", &Parent->front()); - Value *Ret = NewPhi; - - // Handle all non-constant incoming values first - for (unsigned i = 0, e = Phi->getNumIncomingValues(); i != e; ++i) { - Value *Incoming = Phi->getIncomingValue(i); - BasicBlock *From = Phi->getIncomingBlock(i); - if (isa<ConstantInt>(Incoming)) { - NewPhi->addIncoming(Broken, From); - continue; - } - - Phi->setIncomingValue(i, BoolFalse); - Value *PhiArg = handleLoopCondition(Incoming, Broken, L, - Term, LoopPhiConditions); - NewPhi->addIncoming(PhiArg, From); - } - - BasicBlock *IDom = DT->getNode(Parent)->getIDom()->getBlock(); - - for (unsigned i = 0, e = Phi->getNumIncomingValues(); i != e; ++i) { - Value *Incoming = Phi->getIncomingValue(i); - if (Incoming != BoolTrue) - continue; - - BasicBlock *From = Phi->getIncomingBlock(i); - if (From == IDom) { - // We're in the following situation: - // IDom/From - // | \ - // | If-block - // | / - // Parent - // where we want to break out of the loop if the If-block is not taken. - // Due to the depth-first traversal, there should be an end.cf - // intrinsic in Parent, and we insert an else.break before it. - // - // Note that the end.cf need not be the first non-phi instruction - // of parent, particularly when we're dealing with a multi-level - // break, but it should occur within a group of intrinsic calls - // at the beginning of the block. - CallInst *OldEnd = dyn_cast<CallInst>(Parent->getFirstInsertionPt()); - while (OldEnd && OldEnd->getCalledFunction() != EndCf) - OldEnd = dyn_cast<CallInst>(OldEnd->getNextNode()); - if (OldEnd && OldEnd->getCalledFunction() == EndCf) { - Value *Args[] = { OldEnd->getArgOperand(0), NewPhi }; - Ret = CallInst::Create(ElseBreak, Args, "", OldEnd); - continue; - } - } - - TerminatorInst *Insert = From->getTerminator(); - Value *PhiArg = CallInst::Create(Break, Broken, "", Insert); - NewPhi->setIncomingValue(i, PhiArg); - } - - LoopPhiConditions.push_back(WeakTrackingVH(Phi)); - return Ret; - } - + Value *Cond, PHINode *Broken, llvm::Loop *L, BranchInst *Term) { if (Instruction *Inst = dyn_cast<Instruction>(Cond)) { BasicBlock *Parent = Inst->getParent(); Instruction *Insert; @@ -335,21 +261,15 @@ void SIAnnotateControlFlow::handleLoop(BranchInst *Term) { BasicBlock *Target = Term->getSuccessor(1); PHINode *Broken = PHINode::Create(Int64, 0, "phi.broken", &Target->front()); - SmallVector<WeakTrackingVH, 8> LoopPhiConditions; Value *Cond = Term->getCondition(); Term->setCondition(BoolTrue); - Value *Arg = handleLoopCondition(Cond, Broken, L, Term, LoopPhiConditions); + Value *Arg = handleLoopCondition(Cond, Broken, L, Term); for (BasicBlock *Pred : predecessors(Target)) Broken->addIncoming(Pred == BB ? Arg : Int64Zero, Pred); Term->setCondition(CallInst::Create(Loop, Arg, "", Term)); - for (WeakTrackingVH Val : llvm::reverse(LoopPhiConditions)) { - if (PHINode *Cond = cast_or_null<PHINode>(Val)) - eraseIfUnused(Cond); - } - push(Term->getSuccessor(0), Arg); } @@ -372,7 +292,8 @@ void SIAnnotateControlFlow::closeControlFlow(BasicBlock *BB) { Preds.push_back(Pred); } - BB = SplitBlockPredecessors(BB, Preds, "endcf.split", DT, LI, false); + BB = SplitBlockPredecessors(BB, Preds, "endcf.split", DT, LI, nullptr, + false); } Value *Exec = popSaved(); @@ -386,7 +307,7 @@ void SIAnnotateControlFlow::closeControlFlow(BasicBlock *BB) { bool SIAnnotateControlFlow::runOnFunction(Function &F) { DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo(); - DA = &getAnalysis<DivergenceAnalysis>(); + DA = &getAnalysis<LegacyDivergenceAnalysis>(); for (df_iterator<BasicBlock *> I = df_begin(&F.getEntryBlock()), E = df_end(&F.getEntryBlock()); I != E; ++I) { |
