summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMatt Arsenault <Matthew.Arsenault@amd.com>2013-06-19 20:18:24 +0000
committerMatt Arsenault <Matthew.Arsenault@amd.com>2013-06-19 20:18:24 +0000
commitad966ea7a81a538425d5319f6d8568e460639e54 (patch)
tree6e01ec2f16c31a5a31093450dc7616f69270c7f9 /lib
parent5a2fb058d3628063cacc3dda0cda331c8d4dab11 (diff)
downloadllvm-ad966ea7a81a538425d5319f6d8568e460639e54.tar.gz
llvm-ad966ea7a81a538425d5319f6d8568e460639e54.tar.bz2
llvm-ad966ea7a81a538425d5319f6d8568e460639e54.tar.xz
Move StructurizeCFG out of R600 to generic Transforms.
Register it with PassManager git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@184343 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/R600/AMDGPUTargetMachine.cpp2
-rw-r--r--lib/Target/R600/CMakeLists.txt1
-rw-r--r--lib/Transforms/Scalar/CMakeLists.txt1
-rw-r--r--lib/Transforms/Scalar/Scalar.cpp1
-rw-r--r--lib/Transforms/Scalar/StructurizeCFG.cpp (renamed from lib/Target/R600/AMDGPUStructurizeCFG.cpp)119
5 files changed, 54 insertions, 70 deletions
diff --git a/lib/Target/R600/AMDGPUTargetMachine.cpp b/lib/Target/R600/AMDGPUTargetMachine.cpp
index 2fba4347ac..90f72de8ea 100644
--- a/lib/Target/R600/AMDGPUTargetMachine.cpp
+++ b/lib/Target/R600/AMDGPUTargetMachine.cpp
@@ -109,7 +109,7 @@ bool
AMDGPUPassConfig::addPreISel() {
const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>();
if (ST.getGeneration() > AMDGPUSubtarget::NORTHERN_ISLANDS) {
- addPass(createAMDGPUStructurizeCFGPass());
+ addPass(createStructurizeCFGPass());
addPass(createSIAnnotateControlFlowPass());
} else {
addPass(createR600TextureIntrinsicsReplacer());
diff --git a/lib/Target/R600/CMakeLists.txt b/lib/Target/R600/CMakeLists.txt
index 1b79bf5da7..824475e732 100644
--- a/lib/Target/R600/CMakeLists.txt
+++ b/lib/Target/R600/CMakeLists.txt
@@ -22,7 +22,6 @@ add_llvm_target(R600CodeGen
AMDGPUMCInstLower.cpp
AMDGPUMachineFunction.cpp
AMDGPUSubtarget.cpp
- AMDGPUStructurizeCFG.cpp
AMDGPUTargetMachine.cpp
AMDGPUISelLowering.cpp
AMDGPUConvertToISA.cpp
diff --git a/lib/Transforms/Scalar/CMakeLists.txt b/lib/Transforms/Scalar/CMakeLists.txt
index fd55e082ac..aeddf7852c 100644
--- a/lib/Transforms/Scalar/CMakeLists.txt
+++ b/lib/Transforms/Scalar/CMakeLists.txt
@@ -30,6 +30,7 @@ add_llvm_library(LLVMScalarOpts
SimplifyCFGPass.cpp
SimplifyLibCalls.cpp
Sink.cpp
+ StructurizeCFG.cpp
TailRecursionElimination.cpp
)
diff --git a/lib/Transforms/Scalar/Scalar.cpp b/lib/Transforms/Scalar/Scalar.cpp
index 8a9c7da113..5f57f77eeb 100644
--- a/lib/Transforms/Scalar/Scalar.cpp
+++ b/lib/Transforms/Scalar/Scalar.cpp
@@ -58,6 +58,7 @@ void llvm::initializeScalarOpts(PassRegistry &Registry) {
initializeSROA_DTPass(Registry);
initializeSROA_SSAUpPass(Registry);
initializeCFGSimplifyPassPass(Registry);
+ initializeStructurizeCFGPass(Registry);
initializeSimplifyLibCallsPass(Registry);
initializeSinkingPass(Registry);
initializeTailCallElimPass(Registry);
diff --git a/lib/Target/R600/AMDGPUStructurizeCFG.cpp b/lib/Transforms/Scalar/StructurizeCFG.cpp
index d26783d54c..bec066b266 100644
--- a/lib/Target/R600/AMDGPUStructurizeCFG.cpp
+++ b/lib/Transforms/Scalar/StructurizeCFG.cpp
@@ -1,4 +1,4 @@
-//===-- AMDGPUStructurizeCFG.cpp - ------------------===//
+//===-- StructurizeCFG.cpp ------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,16 +6,9 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-/// \file
-/// The pass implemented in this file transforms the programs control flow
-/// graph into a form that's suitable for code generation on hardware that
-/// implements control flow by execution masking. This currently includes all
-/// AMD GPUs but may as well be useful for other types of hardware.
-//
-//===----------------------------------------------------------------------===//
-#include "AMDGPU.h"
+#define DEBUG_TYPE "structurizecfg"
+#include "llvm/Transforms/Scalar.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SCCIterator.h"
#include "llvm/Analysis/RegionInfo.h"
@@ -56,10 +49,9 @@ static const char *FlowBlockName = "Flow";
/// @brief Find the nearest common dominator for multiple BasicBlocks
///
-/// Helper class for AMDGPUStructurizeCFG
+/// Helper class for StructurizeCFG
/// TODO: Maybe move into common code
class NearestCommonDominator {
-
DominatorTree *DT;
DTN2UnsignedMap IndexMap;
@@ -77,7 +69,6 @@ public:
/// \brief Add BB to the resulting dominator
void addBlock(BasicBlock *BB, bool Remember = true) {
-
DomTreeNode *Node = DT->getNode(BB);
if (Result == 0) {
@@ -131,7 +122,7 @@ public:
/// | |
/// 2 |
/// | /
-/// |/
+/// |/
/// 3
/// || Where:
/// | | 1 = "If" block, calculates the condition
@@ -164,10 +155,7 @@ public:
/// while the true side continues the general flow. So the loop condition
/// consist of a network of PHI nodes where the true incoming values expresses
/// breaks and the false values expresses continue states.
-class AMDGPUStructurizeCFG : public RegionPass {
-
- static char ID;
-
+class StructurizeCFG : public RegionPass {
Type *Boolean;
ConstantInt *BoolTrue;
ConstantInt *BoolFalse;
@@ -239,9 +227,10 @@ class AMDGPUStructurizeCFG : public RegionPass {
void rebuildSSA();
public:
- AMDGPUStructurizeCFG():
- RegionPass(ID) {
+ static char ID;
+ StructurizeCFG() :
+ RegionPass(ID) {
initializeRegionInfoPass(*PassRegistry::getPassRegistry());
}
@@ -251,24 +240,29 @@ public:
virtual bool runOnRegion(Region *R, RGPassManager &RGM);
virtual const char *getPassName() const {
- return "AMDGPU simplify control flow";
+ return "Structurize control flow";
}
void getAnalysisUsage(AnalysisUsage &AU) const {
-
AU.addRequired<DominatorTree>();
AU.addPreserved<DominatorTree>();
RegionPass::getAnalysisUsage(AU);
}
-
};
} // end anonymous namespace
-char AMDGPUStructurizeCFG::ID = 0;
+char StructurizeCFG::ID = 0;
+
+INITIALIZE_PASS_BEGIN(StructurizeCFG, "structurizecfg", "Structurize the CFG",
+ false, false)
+INITIALIZE_PASS_DEPENDENCY(DominatorTree)
+INITIALIZE_PASS_DEPENDENCY(RegionInfo)
+INITIALIZE_PASS_END(StructurizeCFG, "structurizecfg", "Structurize the CFG",
+ false, false)
/// \brief Initialize the types and constants used in the pass
-bool AMDGPUStructurizeCFG::doInitialization(Region *R, RGPassManager &RGM) {
+bool StructurizeCFG::doInitialization(Region *R, RGPassManager &RGM) {
LLVMContext &Context = R->getEntry()->getContext();
Boolean = Type::getInt1Ty(Context);
@@ -280,7 +274,7 @@ bool AMDGPUStructurizeCFG::doInitialization(Region *R, RGPassManager &RGM) {
}
/// \brief Build up the general order of nodes
-void AMDGPUStructurizeCFG::orderNodes() {
+void StructurizeCFG::orderNodes() {
scc_iterator<Region *> I = scc_begin(ParentRegion),
E = scc_end(ParentRegion);
for (Order.clear(); I != E; ++I) {
@@ -290,8 +284,7 @@ void AMDGPUStructurizeCFG::orderNodes() {
}
/// \brief Determine the end of the loops
-void AMDGPUStructurizeCFG::analyzeLoops(RegionNode *N) {
-
+void StructurizeCFG::analyzeLoops(RegionNode *N) {
if (N->isSubRegion()) {
// Test for exit as back edge
BasicBlock *Exit = N->getNodeAs<Region>()->getExit();
@@ -313,8 +306,7 @@ void AMDGPUStructurizeCFG::analyzeLoops(RegionNode *N) {
}
/// \brief Invert the given condition
-Value *AMDGPUStructurizeCFG::invert(Value *Condition) {
-
+Value *StructurizeCFG::invert(Value *Condition) {
// First: Check if it's a constant
if (Condition == BoolTrue)
return BoolFalse;
@@ -347,8 +339,8 @@ Value *AMDGPUStructurizeCFG::invert(Value *Condition) {
}
/// \brief Build the condition for one edge
-Value *AMDGPUStructurizeCFG::buildCondition(BranchInst *Term, unsigned Idx,
- bool Invert) {
+Value *StructurizeCFG::buildCondition(BranchInst *Term, unsigned Idx,
+ bool Invert) {
Value *Cond = Invert ? BoolFalse : BoolTrue;
if (Term->isConditional()) {
Cond = Term->getCondition();
@@ -360,8 +352,7 @@ Value *AMDGPUStructurizeCFG::buildCondition(BranchInst *Term, unsigned Idx,
}
/// \brief Analyze the predecessors of each block and build up predicates
-void AMDGPUStructurizeCFG::gatherPredicates(RegionNode *N) {
-
+void StructurizeCFG::gatherPredicates(RegionNode *N) {
RegionInfo *RI = ParentRegion->getRegionInfo();
BasicBlock *BB = N->getEntry();
BBPredicates &Pred = Predicates[BB];
@@ -398,7 +389,7 @@ void AMDGPUStructurizeCFG::gatherPredicates(RegionNode *N) {
}
}
Pred[*PI] = buildCondition(Term, i, false);
-
+
} else {
// Back edge
LPred[*PI] = buildCondition(Term, i, true);
@@ -425,8 +416,7 @@ void AMDGPUStructurizeCFG::gatherPredicates(RegionNode *N) {
}
/// \brief Collect various loop and predicate infos
-void AMDGPUStructurizeCFG::collectInfos() {
-
+void StructurizeCFG::collectInfos() {
// Reset predicate
Predicates.clear();
@@ -452,7 +442,7 @@ void AMDGPUStructurizeCFG::collectInfos() {
}
/// \brief Insert the missing branch conditions
-void AMDGPUStructurizeCFG::insertConditions(bool Loops) {
+void StructurizeCFG::insertConditions(bool Loops) {
BranchVector &Conds = Loops ? LoopConds : Conditions;
Value *Default = Loops ? BoolTrue : BoolFalse;
SSAUpdater PhiInserter;
@@ -501,7 +491,7 @@ void AMDGPUStructurizeCFG::insertConditions(bool Loops) {
/// \brief Remove all PHI values coming from "From" into "To" and remember
/// them in DeletedPhis
-void AMDGPUStructurizeCFG::delPhiValues(BasicBlock *From, BasicBlock *To) {
+void StructurizeCFG::delPhiValues(BasicBlock *From, BasicBlock *To) {
PhiMap &Map = DeletedPhis[To];
for (BasicBlock::iterator I = To->begin(), E = To->end();
I != E && isa<PHINode>(*I);) {
@@ -515,7 +505,7 @@ void AMDGPUStructurizeCFG::delPhiValues(BasicBlock *From, BasicBlock *To) {
}
/// \brief Add a dummy PHI value as soon as we knew the new predecessor
-void AMDGPUStructurizeCFG::addPhiValues(BasicBlock *From, BasicBlock *To) {
+void StructurizeCFG::addPhiValues(BasicBlock *From, BasicBlock *To) {
for (BasicBlock::iterator I = To->begin(), E = To->end();
I != E && isa<PHINode>(*I);) {
@@ -527,8 +517,7 @@ void AMDGPUStructurizeCFG::addPhiValues(BasicBlock *From, BasicBlock *To) {
}
/// \brief Add the real PHI value as soon as everything is set up
-void AMDGPUStructurizeCFG::setPhiValues() {
-
+void StructurizeCFG::setPhiValues() {
SSAUpdater Updater;
for (BB2BBVecMap::iterator AI = AddedPhis.begin(), AE = AddedPhis.end();
AI != AE; ++AI) {
@@ -576,7 +565,7 @@ void AMDGPUStructurizeCFG::setPhiValues() {
}
/// \brief Remove phi values from all successors and then remove the terminator.
-void AMDGPUStructurizeCFG::killTerminator(BasicBlock *BB) {
+void StructurizeCFG::killTerminator(BasicBlock *BB) {
TerminatorInst *Term = BB->getTerminator();
if (!Term)
return;
@@ -591,9 +580,8 @@ void AMDGPUStructurizeCFG::killTerminator(BasicBlock *BB) {
}
/// \brief Let node exit(s) point to NewExit
-void AMDGPUStructurizeCFG::changeExit(RegionNode *Node, BasicBlock *NewExit,
- bool IncludeDominator) {
-
+void StructurizeCFG::changeExit(RegionNode *Node, BasicBlock *NewExit,
+ bool IncludeDominator) {
if (Node->isSubRegion()) {
Region *SubRegion = Node->getNodeAs<Region>();
BasicBlock *OldExit = SubRegion->getExit();
@@ -639,7 +627,7 @@ void AMDGPUStructurizeCFG::changeExit(RegionNode *Node, BasicBlock *NewExit,
}
/// \brief Create a new flow node and update dominator tree and region info
-BasicBlock *AMDGPUStructurizeCFG::getNextFlow(BasicBlock *Dominator) {
+BasicBlock *StructurizeCFG::getNextFlow(BasicBlock *Dominator) {
LLVMContext &Context = Func->getContext();
BasicBlock *Insert = Order.empty() ? ParentRegion->getExit() :
Order.back()->getEntry();
@@ -651,8 +639,7 @@ BasicBlock *AMDGPUStructurizeCFG::getNextFlow(BasicBlock *Dominator) {
}
/// \brief Create a new or reuse the previous node as flow node
-BasicBlock *AMDGPUStructurizeCFG::needPrefix(bool NeedEmpty) {
-
+BasicBlock *StructurizeCFG::needPrefix(bool NeedEmpty) {
BasicBlock *Entry = PrevNode->getEntry();
if (!PrevNode->isSubRegion()) {
@@ -660,7 +647,7 @@ BasicBlock *AMDGPUStructurizeCFG::needPrefix(bool NeedEmpty) {
if (!NeedEmpty || Entry->getFirstInsertionPt() == Entry->end())
return Entry;
- }
+ }
// create a new flow node
BasicBlock *Flow = getNextFlow(Entry);
@@ -672,9 +659,8 @@ BasicBlock *AMDGPUStructurizeCFG::needPrefix(bool NeedEmpty) {
}
/// \brief Returns the region exit if possible, otherwise just a new flow node
-BasicBlock *AMDGPUStructurizeCFG::needPostfix(BasicBlock *Flow,
- bool ExitUseAllowed) {
-
+BasicBlock *StructurizeCFG::needPostfix(BasicBlock *Flow,
+ bool ExitUseAllowed) {
if (Order.empty() && ExitUseAllowed) {
BasicBlock *Exit = ParentRegion->getExit();
DT->changeImmediateDominator(Exit, Flow);
@@ -685,12 +671,12 @@ BasicBlock *AMDGPUStructurizeCFG::needPostfix(BasicBlock *Flow,
}
/// \brief Set the previous node
-void AMDGPUStructurizeCFG::setPrevNode(BasicBlock *BB) {
+void StructurizeCFG::setPrevNode(BasicBlock *BB) {
PrevNode = ParentRegion->contains(BB) ? ParentRegion->getBBNode(BB) : 0;
}
/// \brief Does BB dominate all the predicates of Node ?
-bool AMDGPUStructurizeCFG::dominatesPredicates(BasicBlock *BB, RegionNode *Node) {
+bool StructurizeCFG::dominatesPredicates(BasicBlock *BB, RegionNode *Node) {
BBPredicates &Preds = Predicates[Node->getEntry()];
for (BBPredicates::iterator PI = Preds.begin(), PE = Preds.end();
PI != PE; ++PI) {
@@ -702,8 +688,7 @@ bool AMDGPUStructurizeCFG::dominatesPredicates(BasicBlock *BB, RegionNode *Node)
}
/// \brief Can we predict that this node will always be called?
-bool AMDGPUStructurizeCFG::isPredictableTrue(RegionNode *Node) {
-
+bool StructurizeCFG::isPredictableTrue(RegionNode *Node) {
BBPredicates &Preds = Predicates[Node->getEntry()];
bool Dominated = false;
@@ -726,9 +711,8 @@ bool AMDGPUStructurizeCFG::isPredictableTrue(RegionNode *Node) {
}
/// Take one node from the order vector and wire it up
-void AMDGPUStructurizeCFG::wireFlow(bool ExitUseAllowed,
- BasicBlock *LoopEnd) {
-
+void StructurizeCFG::wireFlow(bool ExitUseAllowed,
+ BasicBlock *LoopEnd) {
RegionNode *Node = Order.pop_back_val();
Visited.insert(Node->getEntry());
@@ -763,8 +747,8 @@ void AMDGPUStructurizeCFG::wireFlow(bool ExitUseAllowed,
}
}
-void AMDGPUStructurizeCFG::handleLoops(bool ExitUseAllowed,
- BasicBlock *LoopEnd) {
+void StructurizeCFG::handleLoops(bool ExitUseAllowed,
+ BasicBlock *LoopEnd) {
RegionNode *Node = Order.back();
BasicBlock *LoopStart = Node->getEntry();
@@ -793,8 +777,7 @@ void AMDGPUStructurizeCFG::handleLoops(bool ExitUseAllowed,
/// After this function control flow looks like it should be, but
/// branches and PHI nodes only have undefined conditions.
-void AMDGPUStructurizeCFG::createFlow() {
-
+void StructurizeCFG::createFlow() {
BasicBlock *Exit = ParentRegion->getExit();
bool EntryDominatesExit = DT->dominates(ParentRegion->getEntry(), Exit);
@@ -818,7 +801,7 @@ void AMDGPUStructurizeCFG::createFlow() {
/// Handle a rare case where the disintegrated nodes instructions
/// no longer dominate all their uses. Not sure if this is really nessasary
-void AMDGPUStructurizeCFG::rebuildSSA() {
+void StructurizeCFG::rebuildSSA() {
SSAUpdater Updater;
for (Region::block_iterator I = ParentRegion->block_begin(),
E = ParentRegion->block_end();
@@ -859,7 +842,7 @@ void AMDGPUStructurizeCFG::rebuildSSA() {
}
/// \brief Run the transformation for each region found
-bool AMDGPUStructurizeCFG::runOnRegion(Region *R, RGPassManager &RGM) {
+bool StructurizeCFG::runOnRegion(Region *R, RGPassManager &RGM) {
if (R->isTopLevelRegion())
return false;
@@ -891,6 +874,6 @@ bool AMDGPUStructurizeCFG::runOnRegion(Region *R, RGPassManager &RGM) {
}
/// \brief Create the pass
-Pass *llvm::createAMDGPUStructurizeCFGPass() {
- return new AMDGPUStructurizeCFG();
+Pass *llvm::createStructurizeCFGPass() {
+ return new StructurizeCFG();
}