diff options
author | ckoenig <ckoenig@91177308-0d34-0410-b5e6-96231b3b80d8> | 2013-02-16 11:27:50 +0000 |
---|---|---|
committer | Tom Stellard <thomas.stellard@amd.com> | 2013-02-19 15:01:28 +0000 |
commit | 12fa80635f08a62b5fec5b5ade245373ae28567e (patch) | |
tree | b6a8e125bf7c91af9f0a6149333722db7f8690d4 | |
parent | 779dfb5fe7e85bebfd0c86f26a7c7575e6b666fc (diff) |
R600/structurizer: improve inverting conditions
Stop adding more instructions than necessary.
This is a candidate for the stable branch.
Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Tom Stellard <thomas.stellard@amd.com>
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175349 91177308-0d34-0410-b5e6-96231b3b80d8
(cherry picked from commit ee16b32089843751148b61fc3889f26965dc9a5f)
-rw-r--r-- | lib/Target/R600/AMDGPUStructurizeCFG.cpp | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/lib/Target/R600/AMDGPUStructurizeCFG.cpp b/lib/Target/R600/AMDGPUStructurizeCFG.cpp index 990088903f3..a8c9621174f 100644 --- a/lib/Target/R600/AMDGPUStructurizeCFG.cpp +++ b/lib/Target/R600/AMDGPUStructurizeCFG.cpp @@ -22,8 +22,10 @@ #include "llvm/Analysis/RegionInfo.h" #include "llvm/Analysis/RegionPass.h" #include "llvm/Transforms/Utils/SSAUpdater.h" +#include "llvm/Support/PatternMatch.h" using namespace llvm; +using namespace llvm::PatternMatch; namespace { @@ -193,6 +195,8 @@ class AMDGPUStructurizeCFG : public RegionPass { void analyzeLoops(RegionNode *N); + Value *invert(Value *Condition); + Value *buildCondition(BranchInst *Term, unsigned Idx, bool Invert); void gatherPredicates(RegionNode *N); @@ -305,6 +309,40 @@ void AMDGPUStructurizeCFG::analyzeLoops(RegionNode *N) { } } +/// \brief Invert the given condition +Value *AMDGPUStructurizeCFG::invert(Value *Condition) { + + // First: Check if it's a constant + if (Condition == BoolTrue) + return BoolFalse; + + if (Condition == BoolFalse) + return BoolTrue; + + if (Condition == BoolUndef) + return BoolUndef; + + // Second: If the condition is already inverted, return the original value + if (match(Condition, m_Not(m_Value(Condition)))) + return Condition; + + // Third: Check all the users for an invert + BasicBlock *Parent = cast<Instruction>(Condition)->getParent(); + for (Value::use_iterator I = Condition->use_begin(), + E = Condition->use_end(); I != E; ++I) { + + Instruction *User = dyn_cast<Instruction>(*I); + if (!User || User->getParent() != Parent) + continue; + + if (match(*I, m_Not(m_Specific(Condition)))) + return *I; + } + + // Last option: Create a new instruction + return BinaryOperator::CreateNot(Condition, "", Parent->getTerminator()); +} + /// \brief Build the condition for one edge Value *AMDGPUStructurizeCFG::buildCondition(BranchInst *Term, unsigned Idx, bool Invert) { @@ -313,7 +351,7 @@ Value *AMDGPUStructurizeCFG::buildCondition(BranchInst *Term, unsigned Idx, Cond = Term->getCondition(); if (Idx != Invert) - Cond = BinaryOperator::CreateNot(Cond, "", Term); + Cond = invert(Cond); } return Cond; } |