diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp | 4 | ||||
| -rw-r--r-- | llvm/lib/Target/AMDGPU/SIAnnotateControlFlow.cpp | 15 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Scalar/StructurizeCFG.cpp | 15 |
3 files changed, 30 insertions, 4 deletions
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp index 795e9927cfa..3028ff67d18 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp @@ -661,7 +661,9 @@ bool AMDGPUDAGToDAGISel::isPrivateLoad(const LoadSDNode *N) const { bool AMDGPUDAGToDAGISel::isUniformBr(const SDNode *N) const { const BasicBlock *BB = FuncInfo->MBB->getBasicBlock(); - return BB->getTerminator()->getMetadata("amdgpu.uniform"); + const Instruction *Term = BB->getTerminator(); + return Term->getMetadata("amdgpu.uniform") || + Term->getMetadata("structurizecfg.uniform"); } const char *AMDGPUDAGToDAGISel::getPassName() const { diff --git a/llvm/lib/Target/AMDGPU/SIAnnotateControlFlow.cpp b/llvm/lib/Target/AMDGPU/SIAnnotateControlFlow.cpp index 3009564f854..f8c7fb9fdb4 100644 --- a/llvm/lib/Target/AMDGPU/SIAnnotateControlFlow.cpp +++ b/llvm/lib/Target/AMDGPU/SIAnnotateControlFlow.cpp @@ -69,6 +69,8 @@ class SIAnnotateControlFlow : public FunctionPass { LoopInfo *LI; + bool isUniform(BranchInst *T); + bool isTopOfStack(BasicBlock *BB); Value *popSaved(); @@ -162,6 +164,13 @@ bool SIAnnotateControlFlow::doInitialization(Module &M) { return false; } +/// \brief Is the branch condition uniform or did the StructurizeCFG pass +/// consider it as such? +bool SIAnnotateControlFlow::isUniform(BranchInst *T) { + return DA->isUniform(T->getCondition()) || + T->getMetadata("structurizecfg.uniform") != nullptr; +} + /// \brief Is BB the last block saved on the stack ? bool SIAnnotateControlFlow::isTopOfStack(BasicBlock *BB) { return !Stack.empty() && Stack.back().first == BB; @@ -204,7 +213,7 @@ void SIAnnotateControlFlow::eraseIfUnused(PHINode *Phi) { /// \brief Open a new "If" block void SIAnnotateControlFlow::openIf(BranchInst *Term) { - if (DA->isUniform(Term->getCondition())) { + if (isUniform(Term)) { return; } Value *Ret = CallInst::Create(If, Term->getCondition(), "", Term); @@ -214,7 +223,7 @@ void SIAnnotateControlFlow::openIf(BranchInst *Term) { /// \brief Close the last "If" block and open a new "Else" block void SIAnnotateControlFlow::insertElse(BranchInst *Term) { - if (DA->isUniform(Term->getCondition())) { + if (isUniform(Term)) { return; } Value *Ret = CallInst::Create(Else, popSaved(), "", Term); @@ -316,7 +325,7 @@ Value *SIAnnotateControlFlow::handleLoopCondition(Value *Cond, PHINode *Broken, /// \brief Handle a back edge (loop) void SIAnnotateControlFlow::handleLoop(BranchInst *Term) { - if (DA->isUniform(Term->getCondition())) { + if (isUniform(Term)) { return; } diff --git a/llvm/lib/Transforms/Scalar/StructurizeCFG.cpp b/llvm/lib/Transforms/Scalar/StructurizeCFG.cpp index d45683294c7..675614dca95 100644 --- a/llvm/lib/Transforms/Scalar/StructurizeCFG.cpp +++ b/llvm/lib/Transforms/Scalar/StructurizeCFG.cpp @@ -951,6 +951,21 @@ bool StructurizeCFG::runOnRegion(Region *R, RGPassManager &RGM) { // TODO: We could probably be smarter here with how we handle sub-regions. if (hasOnlyUniformBranches(R)) { DEBUG(dbgs() << "Skipping region with uniform control flow: " << *R << '\n'); + + // Mark all direct child block terminators as having been treated as + // uniform. To account for a possible future in which non-uniform + // sub-regions are treated more cleverly, indirect children are not + // marked as uniform. + MDNode *MD = MDNode::get(R->getEntry()->getParent()->getContext(), {}); + Region::element_iterator E = R->element_end(); + for (Region::element_iterator I = R->element_begin(); I != E; ++I) { + if (I->isSubRegion()) + continue; + + if (Instruction *Term = I->getEntry()->getTerminator()) + Term->setMetadata("structurizecfg.uniform", MD); + } + return false; } } |

