summaryrefslogtreecommitdiff
path: root/lib/Target/AMDGPU/SIAnnotateControlFlow.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/AMDGPU/SIAnnotateControlFlow.cpp')
-rw-r--r--lib/Target/AMDGPU/SIAnnotateControlFlow.cpp101
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) {