diff options
| author | Frits van Bommel <fvbommel@gmail.com> | 2010-12-15 09:51:20 +0000 |
|---|---|---|
| committer | Frits van Bommel <fvbommel@gmail.com> | 2010-12-15 09:51:20 +0000 |
| commit | 3d1803495e6c2fcca78ba904afd1110dbf837743 (patch) | |
| tree | f61a360cc251f57ca5bdde9bfb17fbbfb2d364ed /llvm/lib/Transforms | |
| parent | 03e7576deef3ed9dbde65462a1a0044728614da8 (diff) | |
| download | bcm5719-llvm-3d1803495e6c2fcca78ba904afd1110dbf837743.tar.gz bcm5719-llvm-3d1803495e6c2fcca78ba904afd1110dbf837743.zip | |
Teach jump threading to "look through" a select when the branch direction of a terminator depends on it.
When it sees a promising select it now tries to figure out whether the condition of the select is known in any of the predecessors and if so it maps the operands appropriately.
llvm-svn: 121859
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/JumpThreading.cpp | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp index b44bc5efef5..e59ae31e134 100644 --- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp +++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp @@ -538,6 +538,40 @@ ComputeValueKnownInPredecessors(Value *V, BasicBlock *BB, PredValueInfo &Result, } } + if (SelectInst *SI = dyn_cast<SelectInst>(I)) { + // Handle select instructions where at least one operand is a known constant + // and we can figure out the condition value for any predecessor block. + Constant *TrueVal = getKnownConstant(SI->getTrueValue(), Preference); + Constant *FalseVal = getKnownConstant(SI->getFalseValue(), Preference); + PredValueInfoTy Conds; + if ((TrueVal || FalseVal) && + ComputeValueKnownInPredecessors(SI->getCondition(), BB, Conds, + WantInteger)) { + for (unsigned i = 0, e = Conds.size(); i != e; ++i) { + Constant *Cond = Conds[i].first; + + // Figure out what value to use for the condition. + bool KnownCond; + if (ConstantInt *CI = dyn_cast<ConstantInt>(Cond)) { + // A known boolean. + KnownCond = CI->isOne(); + } else { + assert(isa<UndefValue>(Cond) && "Unexpected condition value"); + // Either operand will do, so be sure to pick the one that's a known + // constant. + // FIXME: Do this more cleverly if both values are known constants? + KnownCond = (TrueVal != 0); + } + + // See if the select has a known constant value for this predecessor. + if (Constant *Val = KnownCond ? TrueVal : FalseVal) + Result.push_back(std::make_pair(Val, Conds[i].second)); + } + + return !Result.empty(); + } + } + // If all else fails, see if LVI can figure out a constant value for us. Constant *CI = LVI->getConstant(V, BB); if (Constant *KC = getKnownConstant(CI, Preference)) { |

