diff options
author | Owen Anderson <resistor@mac.com> | 2010-08-26 17:40:24 +0000 |
---|---|---|
committer | Owen Anderson <resistor@mac.com> | 2010-08-26 17:40:24 +0000 |
commit | 62efd3b38576536cf06ed5bf2f39535eb7961e99 (patch) | |
tree | 3087e5b3755999f011c8b8d6b228dd3e6cc2d6d1 /lib/Transforms/Scalar/JumpThreading.cpp | |
parent | 63d37b932278724d51e7f8bd1f2574c7b45f85f0 (diff) |
Make JumpThreading smart enough to properly thread StrSwitch when it's compiled with clang++.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@112198 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar/JumpThreading.cpp')
-rw-r--r-- | lib/Transforms/Scalar/JumpThreading.cpp | 94 |
1 files changed, 77 insertions, 17 deletions
diff --git a/lib/Transforms/Scalar/JumpThreading.cpp b/lib/Transforms/Scalar/JumpThreading.cpp index 40250fa12e..8abd842038 100644 --- a/lib/Transforms/Scalar/JumpThreading.cpp +++ b/lib/Transforms/Scalar/JumpThreading.cpp @@ -322,6 +322,12 @@ ComputeValueKnownInPredecessors(Value *V, BasicBlock *BB,PredValueInfo &Result){ if (isa<ConstantInt>(InVal) || isa<UndefValue>(InVal)) { ConstantInt *CI = dyn_cast<ConstantInt>(InVal); Result.push_back(std::make_pair(CI, PN->getIncomingBlock(i))); + } else if (LVI) { + Constant *CI = LVI->getConstantOnEdge(InVal, + PN->getIncomingBlock(i), BB); + ConstantInt *CInt = dyn_cast_or_null<ConstantInt>(CI); + if (CInt) + Result.push_back(std::make_pair(CInt, PN->getIncomingBlock(i))); } } return !Result.empty(); @@ -367,6 +373,10 @@ ComputeValueKnownInPredecessors(Value *V, BasicBlock *BB,PredValueInfo &Result){ } } return !Result.empty(); + + // Try to process a few other binary operator patterns. + } else if (isa<BinaryOperator>(I)) { + } // Handle the NOT form of XOR. @@ -384,6 +394,21 @@ ComputeValueKnownInPredecessors(Value *V, BasicBlock *BB,PredValueInfo &Result){ cast<ConstantInt>(ConstantExpr::getNot(Result[i].first)); return true; } + + // Try to simplify some other binary operator values. + } else if (BinaryOperator *BO = dyn_cast<BinaryOperator>(I)) { + // AND or OR of a value with itself is that value. + ConstantInt *CI = dyn_cast<ConstantInt>(BO->getOperand(1)); + if (CI && (BO->getOpcode() == Instruction::And || + BO->getOpcode() == Instruction::Or)) { + SmallVector<std::pair<ConstantInt*, BasicBlock*>, 8> LHSVals; + ComputeValueKnownInPredecessors(BO->getOperand(0), BB, LHSVals); + for (unsigned i = 0, e = LHSVals.size(); i != e; ++i) + if (LHSVals[i].first == CI) + Result.push_back(std::make_pair(CI, LHSVals[i].second)); + + return !Result.empty(); + } } // Handle compare with phi operand, where the PHI is defined in this block. @@ -423,28 +448,63 @@ ComputeValueKnownInPredecessors(Value *V, BasicBlock *BB,PredValueInfo &Result){ // If comparing a live-in value against a constant, see if we know the // live-in value on any predecessors. if (LVI && isa<Constant>(Cmp->getOperand(1)) && - Cmp->getType()->isIntegerTy() && // Not vector compare. - (!isa<Instruction>(Cmp->getOperand(0)) || - cast<Instruction>(Cmp->getOperand(0))->getParent() != BB)) { - Constant *RHSCst = cast<Constant>(Cmp->getOperand(1)); + Cmp->getType()->isIntegerTy()) { + if (!isa<Instruction>(Cmp->getOperand(0)) || + cast<Instruction>(Cmp->getOperand(0))->getParent() != BB) { + Constant *RHSCst = cast<Constant>(Cmp->getOperand(1)); + + for (pred_iterator PI = pred_begin(BB), E = pred_end(BB);PI != E; ++PI){ + BasicBlock *P = *PI; + // If the value is known by LazyValueInfo to be a constant in a + // predecessor, use that information to try to thread this block. + LazyValueInfo::Tristate Res = + LVI->getPredicateOnEdge(Cmp->getPredicate(), Cmp->getOperand(0), + RHSCst, P, BB); + if (Res == LazyValueInfo::Unknown) + continue; - for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) { - BasicBlock *P = *PI; - // If the value is known by LazyValueInfo to be a constant in a - // predecessor, use that information to try to thread this block. - LazyValueInfo::Tristate - Res = LVI->getPredicateOnEdge(Cmp->getPredicate(), Cmp->getOperand(0), - RHSCst, P, BB); - if (Res == LazyValueInfo::Unknown) - continue; + Constant *ResC = ConstantInt::get(Cmp->getType(), Res); + Result.push_back(std::make_pair(cast<ConstantInt>(ResC), P)); + } - Constant *ResC = ConstantInt::get(Cmp->getType(), Res); - Result.push_back(std::make_pair(cast<ConstantInt>(ResC), P)); + return !Result.empty(); + } + + // Try to find a constant value for the LHS of an equality comparison, + // and evaluate it statically if we can. + if (Cmp->getPredicate() == CmpInst::ICMP_EQ || + Cmp->getPredicate() == CmpInst::ICMP_NE) { + SmallVector<std::pair<ConstantInt*, BasicBlock*>, 8> LHSVals; + ComputeValueKnownInPredecessors(I->getOperand(0), BB, LHSVals); + + ConstantInt *True = ConstantInt::getTrue(I->getContext()); + ConstantInt *False = ConstantInt::getFalse(I->getContext()); + if (Cmp->getPredicate() == CmpInst::ICMP_NE) std::swap(True, False); + + for (unsigned i = 0, e = LHSVals.size(); i != e; ++i) { + if (LHSVals[i].first == Cmp->getOperand(1)) + Result.push_back(std::make_pair(True, LHSVals[i].second)); + else + Result.push_back(std::make_pair(False, LHSVals[i].second)); + } + + return !Result.empty(); } - - return !Result.empty(); } } + + if (LVI) { + // If all else fails, see if LVI can figure out a constant value for us. + Constant *CI = LVI->getConstant(V, BB); + ConstantInt *CInt = dyn_cast_or_null<ConstantInt>(CI); + if (CInt) { + for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) + Result.push_back(std::make_pair(CInt, *PI)); + } + + return !Result.empty(); + } + return false; } |