summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp4
-rw-r--r--llvm/lib/Target/AMDGPU/SIAnnotateControlFlow.cpp15
-rw-r--r--llvm/lib/Transforms/Scalar/StructurizeCFG.cpp15
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;
}
}
OpenPOWER on IntegriCloud