11
11
#include " llvm/ADT/MapVector.h"
12
12
#include " llvm/ADT/PostOrderIterator.h"
13
13
#include " llvm/ADT/SCCIterator.h"
14
+ #include " llvm/Analysis/DivergenceAnalysis.h"
14
15
#include " llvm/Analysis/LoopInfo.h"
15
16
#include " llvm/Analysis/RegionInfo.h"
16
17
#include " llvm/Analysis/RegionIterator.h"
@@ -161,6 +162,9 @@ class NearestCommonDominator {
161
162
// / consist of a network of PHI nodes where the true incoming values expresses
162
163
// / breaks and the false values expresses continue states.
163
164
class StructurizeCFG : public RegionPass {
165
+ bool SkipUniformRegions;
166
+ DivergenceAnalysis *DA;
167
+
164
168
Type *Boolean;
165
169
ConstantInt *BoolTrue;
166
170
ConstantInt *BoolFalse;
@@ -232,6 +236,8 @@ class StructurizeCFG : public RegionPass {
232
236
233
237
void rebuildSSA ();
234
238
239
+ bool hasOnlyUniformBranches (const Region *R);
240
+
235
241
public:
236
242
static char ID;
237
243
@@ -240,6 +246,11 @@ class StructurizeCFG : public RegionPass {
240
246
initializeStructurizeCFGPass (*PassRegistry::getPassRegistry ());
241
247
}
242
248
249
+ StructurizeCFG (bool SkipUniformRegions) :
250
+ RegionPass (ID), SkipUniformRegions(SkipUniformRegions) {
251
+ initializeStructurizeCFGPass (*PassRegistry::getPassRegistry ());
252
+ }
253
+
243
254
using Pass::doInitialization;
244
255
bool doInitialization (Region *R, RGPassManager &RGM) override ;
245
256
@@ -250,6 +261,8 @@ class StructurizeCFG : public RegionPass {
250
261
}
251
262
252
263
void getAnalysisUsage (AnalysisUsage &AU) const override {
264
+ if (SkipUniformRegions)
265
+ AU.addRequired <DivergenceAnalysis>();
253
266
AU.addRequiredID (LowerSwitchID);
254
267
AU.addRequired <DominatorTreeWrapperPass>();
255
268
AU.addRequired <LoopInfoWrapperPass>();
@@ -264,6 +277,7 @@ char StructurizeCFG::ID = 0;
264
277
265
278
INITIALIZE_PASS_BEGIN (StructurizeCFG, " structurizecfg" , " Structurize the CFG" ,
266
279
false , false )
280
+ INITIALIZE_PASS_DEPENDENCY(DivergenceAnalysis)
267
281
INITIALIZE_PASS_DEPENDENCY(LowerSwitch)
268
282
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
269
283
INITIALIZE_PASS_DEPENDENCY(RegionInfoPass)
@@ -914,11 +928,33 @@ void StructurizeCFG::rebuildSSA() {
914
928
}
915
929
}
916
930
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
+
917
944
// / \brief Run the transformation for each region found
918
945
bool StructurizeCFG::runOnRegion (Region *R, RGPassManager &RGM) {
919
946
if (R->isTopLevelRegion ())
920
947
return false ;
921
948
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
+
922
958
Func = R->getEntry ()->getParent ();
923
959
ParentRegion = R;
924
960
@@ -947,7 +983,6 @@ bool StructurizeCFG::runOnRegion(Region *R, RGPassManager &RGM) {
947
983
return true ;
948
984
}
949
985
950
- // / \brief Create the pass
951
- Pass *llvm::createStructurizeCFGPass () {
952
- return new StructurizeCFG ();
986
+ Pass *llvm::createStructurizeCFGPass (bool SkipUniformRegions) {
987
+ return new StructurizeCFG (SkipUniformRegions);
953
988
}
0 commit comments