StructurizeCFG: Add an option for skipping regions with only uniform branches

Summary:
Tests for this will be added once the AMDGPU backend enables this
option.

Reviewers: arsenm

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D16602

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@260336 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Tom Stellard 2016-02-10 00:39:37 +00:00
parent b711faf7b3
commit 7c9f178cf7
2 changed files with 42 additions and 4 deletions

View File

@ -258,7 +258,10 @@ FunctionPass *createFlattenCFGPass();
//
// CFG Structurization - Remove irreducible control flow
//
Pass *createStructurizeCFGPass();
///
/// When \p SkipUniformRegions is true the structizer will not structurize
/// regions that only contain uniform branches.
Pass *createStructurizeCFGPass(bool SkipUniformRegions = false);
//===----------------------------------------------------------------------===//
//

View File

@ -11,6 +11,7 @@
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/SCCIterator.h"
#include "llvm/Analysis/DivergenceAnalysis.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/RegionInfo.h"
#include "llvm/Analysis/RegionIterator.h"
@ -161,6 +162,9 @@ public:
/// consist of a network of PHI nodes where the true incoming values expresses
/// breaks and the false values expresses continue states.
class StructurizeCFG : public RegionPass {
bool SkipUniformRegions;
DivergenceAnalysis *DA;
Type *Boolean;
ConstantInt *BoolTrue;
ConstantInt *BoolFalse;
@ -232,6 +236,8 @@ class StructurizeCFG : public RegionPass {
void rebuildSSA();
bool hasOnlyUniformBranches(const Region *R);
public:
static char ID;
@ -240,6 +246,11 @@ public:
initializeStructurizeCFGPass(*PassRegistry::getPassRegistry());
}
StructurizeCFG(bool SkipUniformRegions) :
RegionPass(ID), SkipUniformRegions(SkipUniformRegions) {
initializeStructurizeCFGPass(*PassRegistry::getPassRegistry());
}
using Pass::doInitialization;
bool doInitialization(Region *R, RGPassManager &RGM) override;
@ -250,6 +261,8 @@ public:
}
void getAnalysisUsage(AnalysisUsage &AU) const override {
if (SkipUniformRegions)
AU.addRequired<DivergenceAnalysis>();
AU.addRequiredID(LowerSwitchID);
AU.addRequired<DominatorTreeWrapperPass>();
AU.addRequired<LoopInfoWrapperPass>();
@ -264,6 +277,7 @@ char StructurizeCFG::ID = 0;
INITIALIZE_PASS_BEGIN(StructurizeCFG, "structurizecfg", "Structurize the CFG",
false, false)
INITIALIZE_PASS_DEPENDENCY(DivergenceAnalysis)
INITIALIZE_PASS_DEPENDENCY(LowerSwitch)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(RegionInfoPass)
@ -914,11 +928,33 @@ void StructurizeCFG::rebuildSSA() {
}
}
bool StructurizeCFG::hasOnlyUniformBranches(const Region *R) {
for (const BasicBlock *BB : R->blocks()) {
const BranchInst *Br = dyn_cast<BranchInst>(BB->getTerminator());
if (!Br || !Br->isConditional())
continue;
if (!DA->isUniform(Br->getCondition()))
return false;
DEBUG(dbgs() << "BB: " << BB->getName() << " has uniform terminator\n");
}
return true;
}
/// \brief Run the transformation for each region found
bool StructurizeCFG::runOnRegion(Region *R, RGPassManager &RGM) {
if (R->isTopLevelRegion())
return false;
if (SkipUniformRegions) {
DA = &getAnalysis<DivergenceAnalysis>();
// 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');
return false;
}
}
Func = R->getEntry()->getParent();
ParentRegion = R;
@ -947,7 +983,6 @@ bool StructurizeCFG::runOnRegion(Region *R, RGPassManager &RGM) {
return true;
}
/// \brief Create the pass
Pass *llvm::createStructurizeCFGPass() {
return new StructurizeCFG();
Pass *llvm::createStructurizeCFGPass(bool SkipUniformRegions) {
return new StructurizeCFG(SkipUniformRegions);
}