diff options
author | Christian Konig <christian.koenig@amd.com> | 2013-02-16 11:27:50 +0000 |
---|---|---|
committer | Christian Konig <christian.koenig@amd.com> | 2013-02-16 11:27:50 +0000 |
commit | d886099f13f0e6310a20a80f8fed08bcac4a3759 (patch) | |
tree | e44ba7dd5ca2b75c8c78cc805dcd7704a961cde0 /llvm/lib/Target/R600/AMDGPUStructurizeCFG.cpp | |
parent | fc6a985c12fc5c13644484379ce02dc42ddddc1f (diff) | |
download | bcm5719-llvm-d886099f13f0e6310a20a80f8fed08bcac4a3759.tar.gz bcm5719-llvm-d886099f13f0e6310a20a80f8fed08bcac4a3759.zip |
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>
llvm-svn: 175349
Diffstat (limited to 'llvm/lib/Target/R600/AMDGPUStructurizeCFG.cpp')
-rw-r--r-- | llvm/lib/Target/R600/AMDGPUStructurizeCFG.cpp | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/llvm/lib/Target/R600/AMDGPUStructurizeCFG.cpp b/llvm/lib/Target/R600/AMDGPUStructurizeCFG.cpp index c2b084afc7e..26f842eb14f 100644 --- a/llvm/lib/Target/R600/AMDGPUStructurizeCFG.cpp +++ b/llvm/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; } |