diff options
author | Chris Lattner <sabre@nondot.org> | 2006-02-08 02:38:11 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2006-02-08 02:38:11 +0000 |
commit | fe243ebb64cccc649bb31e76163da58b68e8dd84 (patch) | |
tree | 1db26cb8392633439779e39f51e446104ca481bb /lib/Transforms | |
parent | d27460f291da027a5ac748fbc47d43bb3f65a1d2 (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.cpp | 50 |
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); } } |