summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolai Haehnle <nhaehnle@gmail.com>2016-04-14 17:42:35 +0000
committerNicolai Haehnle <nhaehnle@gmail.com>2016-04-14 17:42:35 +0000
commit05b127da063133a2702c4399d97e14f43492a596 (patch)
tree0cf7cee370ad197cb13fc8ee1012570bab58985b
parent723b73b4eb70d4015bb32ec94c6a782608c5112b (diff)
downloadbcm5719-llvm-05b127da063133a2702c4399d97e14f43492a596.tar.gz
bcm5719-llvm-05b127da063133a2702c4399d97e14f43492a596.zip
[StructurizeCFG] Annotate branches that were treated as uniform
Summary: This fully solves the problem where the StructurizeCFG pass does not consider the same branches as uniform as the SIAnnotateControlFlow pass. The patch in D19013 helps with this problem, but is not sufficient (and, interestingly, causes a "regression" with one of the existing test cases). No tests included here, because tests in D19013 already cover this. Reviewers: arsenm, tstellarAMD Subscribers: arsenm, llvm-commits Differential Revision: http://reviews.llvm.org/D19018 llvm-svn: 266346
-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