Skip to content

Commit a8a79c9

Browse files
committed
[ConstraintElimination] Refactor constraint extraction (NFC).
This patch generalizes the extraction of a constraint for a given condition. It allows decompose to return a vector of c * X pairs, which allows de-composing multiple instructions in the future. It also adds more clarifying comments.
1 parent aad3ea8 commit a8a79c9

File tree

1 file changed

+46
-29
lines changed

1 file changed

+46
-29
lines changed

llvm/lib/Transforms/Scalar/ConstraintElimination.cpp

Lines changed: 46 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
//===----------------------------------------------------------------------===//
1313

1414
#include "llvm/Transforms/Scalar/ConstraintElimination.h"
15+
#include "llvm/ADT/STLExtras.h"
1516
#include "llvm/ADT/SmallVector.h"
1617
#include "llvm/ADT/Statistic.h"
1718
#include "llvm/Analysis/ConstraintSystem.h"
@@ -38,7 +39,11 @@ DEBUG_COUNTER(EliminatedCounter, "conds-eliminated",
3839

3940
static int64_t MaxConstraintValue = std::numeric_limits<int64_t>::max();
4041

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) {
4247
if (auto *CI = dyn_cast<ConstantInt>(V)) {
4348
if (CI->isNegative() || CI->uge(MaxConstraintValue))
4449
return {};
@@ -49,9 +54,10 @@ static Optional<std::pair<int64_t, Value *>> decompose(Value *V) {
4954
isa<ConstantInt>(GEP->getOperand(GEP->getNumOperands() - 1))) {
5055
return {{cast<ConstantInt>(GEP->getOperand(GEP->getNumOperands() - 1))
5156
->getSExtValue(),
52-
GEP->getPointerOperand()}};
57+
nullptr},
58+
{1, GEP->getPointerOperand()}};
5359
}
54-
return {{0, V}};
60+
return {{0, nullptr}, {1, V}};
5561
}
5662

5763
/// 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) {
6066
static SmallVector<int64_t, 8>
6167
getConstraint(CmpInst::Predicate Pred, Value *Op0, Value *Op1,
6268
DenseMap<Value *, unsigned> &Value2Index, bool ShouldAdd) {
63-
Value *A, *B;
64-
6569
int64_t Offset1 = 0;
6670
int64_t Offset2 = 0;
6771

@@ -81,33 +85,46 @@ getConstraint(CmpInst::Predicate Pred, Value *Op0, Value *Op1,
8185
return getConstraint(CmpInst::getSwappedPredicate(Pred), Op1, Op0,
8286
Value2Index, ShouldAdd);
8387

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))
88115
return {};
89-
std::tie(Offset1, A) = *ADec;
90-
std::tie(Offset2, B) = *BDec;
91-
Offset1 *= -1;
92116

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;
95122

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;
109125

110-
return {};
126+
R[0] = Offset1 + Offset2 + (Pred == CmpInst::ICMP_ULT ? -1 : 0);
127+
return R;
111128
}
112129

113130
static SmallVector<int64_t, 8>
@@ -252,7 +269,7 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT) {
252269
if (!Cmp)
253270
continue;
254271
auto R = getConstraint(Cmp, Value2Index, false);
255-
if (R.empty())
272+
if (R.empty() || R.size() == 1)
256273
continue;
257274
if (CS.isConditionImplied(R)) {
258275
if (!DebugCounter::shouldExecute(EliminatedCounter))

0 commit comments

Comments
 (0)