aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms/Scalar/JumpThreading.cpp
diff options
context:
space:
mode:
authorOwen Anderson <resistor@mac.com>2010-08-26 17:40:24 +0000
committerOwen Anderson <resistor@mac.com>2010-08-26 17:40:24 +0000
commit62efd3b38576536cf06ed5bf2f39535eb7961e99 (patch)
tree3087e5b3755999f011c8b8d6b228dd3e6cc2d6d1 /lib/Transforms/Scalar/JumpThreading.cpp
parent63d37b932278724d51e7f8bd1f2574c7b45f85f0 (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.cpp94
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;
}