Skip to content

Commit

Permalink
[StructurizeCFG] Annotate branches that were treated as uniform
Browse files Browse the repository at this point in the history
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
  • Loading branch information
nhaehnle committed Apr 14, 2016
1 parent 723b73b commit 05b127d
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 4 deletions.
4 changes: 3 additions & 1 deletion llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
15 changes: 12 additions & 3 deletions llvm/lib/Target/AMDGPU/SIAnnotateControlFlow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ class SIAnnotateControlFlow : public FunctionPass {

LoopInfo *LI;

bool isUniform(BranchInst *T);

bool isTopOfStack(BasicBlock *BB);

Value *popSaved();
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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;
}

Expand Down
15 changes: 15 additions & 0 deletions llvm/lib/Transforms/Scalar/StructurizeCFG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand Down

0 comments on commit 05b127d

Please sign in to comment.