summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Konig <christian.koenig@amd.com>2013-02-16 11:27:50 +0000
committerChristian Konig <christian.koenig@amd.com>2013-02-16 11:27:50 +0000
commitef6b24856d39ca69381d445c8363a86f5e0945db (patch)
tree617694fb59ebd11ab883c7c92ff3b5cb193d1d1d
parent623977d9ba064a6f3b46edee1cb2246716a33397 (diff)
downloadllvm-ef6b24856d39ca69381d445c8363a86f5e0945db.tar.gz
llvm-ef6b24856d39ca69381d445c8363a86f5e0945db.tar.bz2
llvm-ef6b24856d39ca69381d445c8363a86f5e0945db.tar.xz
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
-rw-r--r--lib/Target/R600/AMDGPUStructurizeCFG.cpp40
1 files changed, 39 insertions, 1 deletions
diff --git a/lib/Target/R600/AMDGPUStructurizeCFG.cpp b/lib/Target/R600/AMDGPUStructurizeCFG.cpp
index c2b084afc7..26f842eb14 100644
--- a/lib/Target/R600/AMDGPUStructurizeCFG.cpp
+++ b/lib/Target/R600/AMDGPUStructurizeCFG.cpp
@@ -22,8 +22,10 @@
#include "llvm/Analysis/RegionPass.h"
#include "llvm/IR/Module.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;
}