[llvm] a8a79c9 - [ConstraintElimination] Refactor constraint extraction (NFC).
Florian Hahn via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 18 05:59:53 PST 2020
Author: Florian Hahn
Date: 2020-11-18T13:59:18Z
New Revision: a8a79c90699a7ae9dee07daf7281cbbd592bf6ea
URL: https://github.com/llvm/llvm-project/commit/a8a79c90699a7ae9dee07daf7281cbbd592bf6ea
DIFF: https://github.com/llvm/llvm-project/commit/a8a79c90699a7ae9dee07daf7281cbbd592bf6ea.diff
LOG: [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.
Added:
Modified:
llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
index 01fead12dc08..2ae913ce8f0a 100644
--- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/Transforms/Scalar/ConstraintElimination.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/ConstraintSystem.h"
@@ -38,7 +39,11 @@ DEBUG_COUNTER(EliminatedCounter, "conds-eliminated",
static int64_t MaxConstraintValue = std::numeric_limits<int64_t>::max();
-static Optional<std::pair<int64_t, Value *>> decompose(Value *V) {
+// Decomposes \p V into a vector of pairs of the form { c, X } where c * X. The
+// sum of the pairs equals \p V. The first pair is the constant-factor and X
+// must be nullptr. If the expression cannot be decomposed, returns an empty
+// vector.
+static SmallVector<std::pair<int64_t, Value *>, 4> decompose(Value *V) {
if (auto *CI = dyn_cast<ConstantInt>(V)) {
if (CI->isNegative() || CI->uge(MaxConstraintValue))
return {};
@@ -49,9 +54,10 @@ static Optional<std::pair<int64_t, Value *>> decompose(Value *V) {
isa<ConstantInt>(GEP->getOperand(GEP->getNumOperands() - 1))) {
return {{cast<ConstantInt>(GEP->getOperand(GEP->getNumOperands() - 1))
->getSExtValue(),
- GEP->getPointerOperand()}};
+ nullptr},
+ {1, GEP->getPointerOperand()}};
}
- return {{0, V}};
+ return {{0, nullptr}, {1, V}};
}
/// 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) {
static SmallVector<int64_t, 8>
getConstraint(CmpInst::Predicate Pred, Value *Op0, Value *Op1,
DenseMap<Value *, unsigned> &Value2Index, bool ShouldAdd) {
- Value *A, *B;
-
int64_t Offset1 = 0;
int64_t Offset2 = 0;
@@ -81,33 +85,46 @@ getConstraint(CmpInst::Predicate Pred, Value *Op0, Value *Op1,
return getConstraint(CmpInst::getSwappedPredicate(Pred), Op1, Op0,
Value2Index, ShouldAdd);
- if (Pred == CmpInst::ICMP_ULE || Pred == CmpInst::ICMP_ULT) {
- auto ADec = decompose(Op0);
- auto BDec = decompose(Op1);
- if (!ADec || !BDec)
+ // Only ULE and ULT predicates are supported at the moment.
+ if (Pred != CmpInst::ICMP_ULE && Pred != CmpInst::ICMP_ULT)
+ return {};
+
+ auto ADec = decompose(Op0);
+ auto BDec = decompose(Op1);
+ // Skip if decomposing either of the values failed.
+ if (ADec.empty() || BDec.empty())
+ return {};
+
+ // Skip trivial constraints without any variables.
+ if (ADec.size() == 1 && BDec.size() == 1)
+ return {};
+
+ Offset1 = ADec[0].first;
+ Offset2 = BDec[0].first;
+ Offset1 *= -1;
+
+ // Create iterator ranges that skip the constant-factor.
+ auto VariablesA = make_range(std::next(ADec.begin()), ADec.end());
+ auto VariablesB = make_range(std::next(BDec.begin()), BDec.end());
+
+ // Check if each referenced value in the constraint is already in the system
+ // or can be added (if ShouldAdd is true).
+ for (const auto &KV :
+ concat<std::pair<int64_t, Value *>>(VariablesA, VariablesB))
+ if (!TryToGetIndex(KV.second))
return {};
- std::tie(Offset1, A) = *ADec;
- std::tie(Offset2, B) = *BDec;
- Offset1 *= -1;
- if (!A && !B)
- return {};
+ // Build result constraint, by first adding all coefficients from A and then
+ // subtracting all coefficients from B.
+ SmallVector<int64_t, 8> R(Value2Index.size() + 1, 0);
+ for (const auto &KV : VariablesA)
+ R[Value2Index[KV.second]] += KV.first;
- auto AIdx = A ? TryToGetIndex(A) : None;
- auto BIdx = B ? TryToGetIndex(B) : None;
- if ((A && !AIdx) || (B && !BIdx))
- return {};
-
- SmallVector<int64_t, 8> R(Value2Index.size() + 1, 0);
- if (AIdx)
- R[*AIdx] = 1;
- if (BIdx)
- R[*BIdx] = -1;
- R[0] = Offset1 + Offset2 + (Pred == CmpInst::ICMP_ULT ? -1 : 0);
- return R;
- }
+ for (const auto &KV : VariablesB)
+ R[Value2Index[KV.second]] -= KV.first;
- return {};
+ R[0] = Offset1 + Offset2 + (Pred == CmpInst::ICMP_ULT ? -1 : 0);
+ return R;
}
static SmallVector<int64_t, 8>
@@ -252,7 +269,7 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT) {
if (!Cmp)
continue;
auto R = getConstraint(Cmp, Value2Index, false);
- if (R.empty())
+ if (R.empty() || R.size() == 1)
continue;
if (CS.isConditionImplied(R)) {
if (!DebugCounter::shouldExecute(EliminatedCounter))
More information about the llvm-commits
mailing list