Skip to content

Commit 755a4e6

Browse files
committed
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 llvm-svn: 260336
1 parent aad9353 commit 755a4e6

File tree

2 files changed

+42
-4
lines changed

2 files changed

+42
-4
lines changed

llvm/include/llvm/Transforms/Scalar.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,10 @@ FunctionPass *createFlattenCFGPass();
258258
//
259259
// CFG Structurization - Remove irreducible control flow
260260
//
261-
Pass *createStructurizeCFGPass();
261+
///
262+
/// When \p SkipUniformRegions is true the structizer will not structurize
263+
/// regions that only contain uniform branches.
264+
Pass *createStructurizeCFGPass(bool SkipUniformRegions = false);
262265

263266
//===----------------------------------------------------------------------===//
264267
//

llvm/lib/Transforms/Scalar/StructurizeCFG.cpp

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "llvm/ADT/MapVector.h"
1212
#include "llvm/ADT/PostOrderIterator.h"
1313
#include "llvm/ADT/SCCIterator.h"
14+
#include "llvm/Analysis/DivergenceAnalysis.h"
1415
#include "llvm/Analysis/LoopInfo.h"
1516
#include "llvm/Analysis/RegionInfo.h"
1617
#include "llvm/Analysis/RegionIterator.h"
@@ -161,6 +162,9 @@ class NearestCommonDominator {
161162
/// consist of a network of PHI nodes where the true incoming values expresses
162163
/// breaks and the false values expresses continue states.
163164
class StructurizeCFG : public RegionPass {
165+
bool SkipUniformRegions;
166+
DivergenceAnalysis *DA;
167+
164168
Type *Boolean;
165169
ConstantInt *BoolTrue;
166170
ConstantInt *BoolFalse;
@@ -232,6 +236,8 @@ class StructurizeCFG : public RegionPass {
232236

233237
void rebuildSSA();
234238

239+
bool hasOnlyUniformBranches(const Region *R);
240+
235241
public:
236242
static char ID;
237243

@@ -240,6 +246,11 @@ class StructurizeCFG : public RegionPass {
240246
initializeStructurizeCFGPass(*PassRegistry::getPassRegistry());
241247
}
242248

249+
StructurizeCFG(bool SkipUniformRegions) :
250+
RegionPass(ID), SkipUniformRegions(SkipUniformRegions) {
251+
initializeStructurizeCFGPass(*PassRegistry::getPassRegistry());
252+
}
253+
243254
using Pass::doInitialization;
244255
bool doInitialization(Region *R, RGPassManager &RGM) override;
245256

@@ -250,6 +261,8 @@ class StructurizeCFG : public RegionPass {
250261
}
251262

252263
void getAnalysisUsage(AnalysisUsage &AU) const override {
264+
if (SkipUniformRegions)
265+
AU.addRequired<DivergenceAnalysis>();
253266
AU.addRequiredID(LowerSwitchID);
254267
AU.addRequired<DominatorTreeWrapperPass>();
255268
AU.addRequired<LoopInfoWrapperPass>();
@@ -264,6 +277,7 @@ char StructurizeCFG::ID = 0;
264277

265278
INITIALIZE_PASS_BEGIN(StructurizeCFG, "structurizecfg", "Structurize the CFG",
266279
false, false)
280+
INITIALIZE_PASS_DEPENDENCY(DivergenceAnalysis)
267281
INITIALIZE_PASS_DEPENDENCY(LowerSwitch)
268282
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
269283
INITIALIZE_PASS_DEPENDENCY(RegionInfoPass)
@@ -914,11 +928,33 @@ void StructurizeCFG::rebuildSSA() {
914928
}
915929
}
916930

931+
bool StructurizeCFG::hasOnlyUniformBranches(const Region *R) {
932+
for (const BasicBlock *BB : R->blocks()) {
933+
const BranchInst *Br = dyn_cast<BranchInst>(BB->getTerminator());
934+
if (!Br || !Br->isConditional())
935+
continue;
936+
937+
if (!DA->isUniform(Br->getCondition()))
938+
return false;
939+
DEBUG(dbgs() << "BB: " << BB->getName() << " has uniform terminator\n");
940+
}
941+
return true;
942+
}
943+
917944
/// \brief Run the transformation for each region found
918945
bool StructurizeCFG::runOnRegion(Region *R, RGPassManager &RGM) {
919946
if (R->isTopLevelRegion())
920947
return false;
921948

949+
if (SkipUniformRegions) {
950+
DA = &getAnalysis<DivergenceAnalysis>();
951+
// TODO: We could probably be smarter here with how we handle sub-regions.
952+
if (hasOnlyUniformBranches(R)) {
953+
DEBUG(dbgs() << "Skipping region with uniform control flow: " << *R << '\n');
954+
return false;
955+
}
956+
}
957+
922958
Func = R->getEntry()->getParent();
923959
ParentRegion = R;
924960

@@ -947,7 +983,6 @@ bool StructurizeCFG::runOnRegion(Region *R, RGPassManager &RGM) {
947983
return true;
948984
}
949985

950-
/// \brief Create the pass
951-
Pass *llvm::createStructurizeCFGPass() {
952-
return new StructurizeCFG();
986+
Pass *llvm::createStructurizeCFGPass(bool SkipUniformRegions) {
987+
return new StructurizeCFG(SkipUniformRegions);
953988
}

0 commit comments

Comments
 (0)