12
12
// ===----------------------------------------------------------------------===//
13
13
14
14
#include " llvm/Transforms/Scalar/ConstraintElimination.h"
15
+ #include " llvm/ADT/STLExtras.h"
15
16
#include " llvm/ADT/SmallVector.h"
16
17
#include " llvm/ADT/Statistic.h"
17
18
#include " llvm/Analysis/ConstraintSystem.h"
@@ -38,7 +39,11 @@ DEBUG_COUNTER(EliminatedCounter, "conds-eliminated",
38
39
39
40
static int64_t MaxConstraintValue = std::numeric_limits<int64_t >::max();
40
41
41
- static Optional<std::pair<int64_t , Value *>> decompose (Value *V) {
42
+ // Decomposes \p V into a vector of pairs of the form { c, X } where c * X. The
43
+ // sum of the pairs equals \p V. The first pair is the constant-factor and X
44
+ // must be nullptr. If the expression cannot be decomposed, returns an empty
45
+ // vector.
46
+ static SmallVector<std::pair<int64_t , Value *>, 4 > decompose (Value *V) {
42
47
if (auto *CI = dyn_cast<ConstantInt>(V)) {
43
48
if (CI->isNegative () || CI->uge (MaxConstraintValue))
44
49
return {};
@@ -49,9 +54,10 @@ static Optional<std::pair<int64_t, Value *>> decompose(Value *V) {
49
54
isa<ConstantInt>(GEP->getOperand (GEP->getNumOperands () - 1 ))) {
50
55
return {{cast<ConstantInt>(GEP->getOperand (GEP->getNumOperands () - 1 ))
51
56
->getSExtValue (),
52
- GEP->getPointerOperand ()}};
57
+ nullptr },
58
+ {1 , GEP->getPointerOperand ()}};
53
59
}
54
- return {{0 , V}};
60
+ return {{0 , nullptr }, { 1 , V}};
55
61
}
56
62
57
63
// / Turn a condition \p CmpI into a constraint vector, using indices from \p
@@ -60,8 +66,6 @@ static Optional<std::pair<int64_t, Value *>> decompose(Value *V) {
60
66
static SmallVector<int64_t , 8 >
61
67
getConstraint (CmpInst::Predicate Pred, Value *Op0, Value *Op1,
62
68
DenseMap<Value *, unsigned > &Value2Index, bool ShouldAdd) {
63
- Value *A, *B;
64
-
65
69
int64_t Offset1 = 0 ;
66
70
int64_t Offset2 = 0 ;
67
71
@@ -81,33 +85,46 @@ getConstraint(CmpInst::Predicate Pred, Value *Op0, Value *Op1,
81
85
return getConstraint (CmpInst::getSwappedPredicate (Pred), Op1, Op0,
82
86
Value2Index, ShouldAdd);
83
87
84
- if (Pred == CmpInst::ICMP_ULE || Pred == CmpInst::ICMP_ULT) {
85
- auto ADec = decompose (Op0);
86
- auto BDec = decompose (Op1);
87
- if (!ADec || !BDec)
88
+ // Only ULE and ULT predicates are supported at the moment.
89
+ if (Pred != CmpInst::ICMP_ULE && Pred != CmpInst::ICMP_ULT)
90
+ return {};
91
+
92
+ auto ADec = decompose (Op0);
93
+ auto BDec = decompose (Op1);
94
+ // Skip if decomposing either of the values failed.
95
+ if (ADec.empty () || BDec.empty ())
96
+ return {};
97
+
98
+ // Skip trivial constraints without any variables.
99
+ if (ADec.size () == 1 && BDec.size () == 1 )
100
+ return {};
101
+
102
+ Offset1 = ADec[0 ].first ;
103
+ Offset2 = BDec[0 ].first ;
104
+ Offset1 *= -1 ;
105
+
106
+ // Create iterator ranges that skip the constant-factor.
107
+ auto VariablesA = make_range (std::next (ADec.begin ()), ADec.end ());
108
+ auto VariablesB = make_range (std::next (BDec.begin ()), BDec.end ());
109
+
110
+ // Check if each referenced value in the constraint is already in the system
111
+ // or can be added (if ShouldAdd is true).
112
+ for (const auto &KV :
113
+ concat<std::pair<int64_t , Value *>>(VariablesA, VariablesB))
114
+ if (!TryToGetIndex (KV.second ))
88
115
return {};
89
- std::tie (Offset1, A) = *ADec;
90
- std::tie (Offset2, B) = *BDec;
91
- Offset1 *= -1 ;
92
116
93
- if (!A && !B)
94
- return {};
117
+ // Build result constraint, by first adding all coefficients from A and then
118
+ // subtracting all coefficients from B.
119
+ SmallVector<int64_t , 8 > R (Value2Index.size () + 1 , 0 );
120
+ for (const auto &KV : VariablesA)
121
+ R[Value2Index[KV.second ]] += KV.first ;
95
122
96
- auto AIdx = A ? TryToGetIndex (A) : None;
97
- auto BIdx = B ? TryToGetIndex (B) : None;
98
- if ((A && !AIdx) || (B && !BIdx))
99
- return {};
100
-
101
- SmallVector<int64_t , 8 > R (Value2Index.size () + 1 , 0 );
102
- if (AIdx)
103
- R[*AIdx] = 1 ;
104
- if (BIdx)
105
- R[*BIdx] = -1 ;
106
- R[0 ] = Offset1 + Offset2 + (Pred == CmpInst::ICMP_ULT ? -1 : 0 );
107
- return R;
108
- }
123
+ for (const auto &KV : VariablesB)
124
+ R[Value2Index[KV.second ]] -= KV.first ;
109
125
110
- return {};
126
+ R[0 ] = Offset1 + Offset2 + (Pred == CmpInst::ICMP_ULT ? -1 : 0 );
127
+ return R;
111
128
}
112
129
113
130
static SmallVector<int64_t , 8 >
@@ -252,7 +269,7 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT) {
252
269
if (!Cmp)
253
270
continue ;
254
271
auto R = getConstraint (Cmp, Value2Index, false );
255
- if (R.empty ())
272
+ if (R.empty () || R. size () == 1 )
256
273
continue ;
257
274
if (CS.isConditionImplied (R)) {
258
275
if (!DebugCounter::shouldExecute (EliminatedCounter))
0 commit comments