mirror of
https://github.com/RPCSX/llvm.git
synced 2025-04-02 08:11:54 +00:00
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:
parent
b711faf7b3
commit
7c9f178cf7
@ -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);
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user