aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2006-02-08 02:38:11 +0000
committerChris Lattner <sabre@nondot.org>2006-02-08 02:38:11 +0000
commitfe243ebb64cccc649bb31e76163da58b68e8dd84 (patch)
tree1db26cb8392633439779e39f51e446104ca481bb /lib/Transforms
parentd27460f291da027a5ac748fbc47d43bb3f65a1d2 (diff)
Implement some more interesting select sccp cases. This implements:
test/Regression/Transforms/SCCP/select.ll git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26049 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r--lib/Transforms/Scalar/SCCP.cpp50
1 files changed, 35 insertions, 15 deletions
diff --git a/lib/Transforms/Scalar/SCCP.cpp b/lib/Transforms/Scalar/SCCP.cpp
index 3972282a01..a57cea8b7e 100644
--- a/lib/Transforms/Scalar/SCCP.cpp
+++ b/lib/Transforms/Scalar/SCCP.cpp
@@ -241,6 +241,11 @@ private:
else if (IV.getConstant() != MergeWithV.getConstant())
markOverdefined(IV, V);
}
+
+ inline void mergeInValue(Value *V, LatticeVal &MergeWithV) {
+ return mergeInValue(ValueState[V], V, MergeWithV);
+ }
+
// getValueState - Return the LatticeVal object that corresponds to the value.
// This function is necessary because not all values should start out in the
@@ -589,23 +594,38 @@ void SCCPSolver::visitCastInst(CastInst &I) {
void SCCPSolver::visitSelectInst(SelectInst &I) {
LatticeVal &CondValue = getValueState(I.getCondition());
- if (CondValue.isOverdefined())
- markOverdefined(&I);
- else if (CondValue.isConstant()) {
+ if (CondValue.isUndefined())
+ return;
+ if (CondValue.isConstant()) {
+ Value *InVal = 0;
if (CondValue.getConstant() == ConstantBool::True) {
- LatticeVal &Val = getValueState(I.getTrueValue());
- if (Val.isOverdefined())
- markOverdefined(&I);
- else if (Val.isConstant())
- markConstant(&I, Val.getConstant());
+ mergeInValue(&I, getValueState(I.getTrueValue()));
+ return;
} else if (CondValue.getConstant() == ConstantBool::False) {
- LatticeVal &Val = getValueState(I.getFalseValue());
- if (Val.isOverdefined())
- markOverdefined(&I);
- else if (Val.isConstant())
- markConstant(&I, Val.getConstant());
- } else
- markOverdefined(&I);
+ mergeInValue(&I, getValueState(I.getFalseValue()));
+ return;
+ }
+ }
+
+ // Otherwise, the condition is overdefined or a constant we can't evaluate.
+ // See if we can produce something better than overdefined based on the T/F
+ // value.
+ LatticeVal &TVal = getValueState(I.getTrueValue());
+ LatticeVal &FVal = getValueState(I.getFalseValue());
+
+ // select ?, C, C -> C.
+ if (TVal.isConstant() && FVal.isConstant() &&
+ TVal.getConstant() == FVal.getConstant()) {
+ markConstant(&I, FVal.getConstant());
+ return;
+ }
+
+ if (TVal.isUndefined()) { // select ?, undef, X -> X.
+ mergeInValue(&I, FVal);
+ } else if (FVal.isUndefined()) { // select ?, X, undef -> X.
+ mergeInValue(&I, TVal);
+ } else {
+ markOverdefined(&I);
}
}